unity以Package模式加载项目,如何修复资源无法找到的问题

简介

为了能更便捷地使用ShaderForge,我们可以将其通过Package Manager加载。
但这样会遇到Unable to locate the internal resources folder. Make sure your Shader Forge installation is intact这个报错,因为Package里面Asset的加载方式和项目里的Asset是不同的。
这里我们希望在不影响import加载shaderforge的使用的情况下,支持package模式的shaderforge的使用。

如何判断代码是否运行在Package里面

unity提供了PackageInfo.FindForAssembly接口,可以帮助我们判断传入的Assembly程序集是否有对应的PackageInfo信息。
为此我们需要在ShaderForge 的package中创建一个AssemblyDefinition

然后我们就可以使用下面的代码来判断,当前的代码是否运行在package中。

		public static bool IsPackage()
		{
            var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(SF_Tools).Assembly);

			//if(packageInfo != null)
			//	Debug.Log($"{packageInfo.name}");

            return packageInfo != null;

        }

访问Package里面的Asset

访问package路径

通过Accessing package assets可知,"Assets/..."这样的路径对应到Package中是 "Packages/<package-name>/..."
这里我们结合上文,将SF_Resources`的类修改为如下:

		public static string InternalResourcesPath
		{
			get
			{

                if (SF_Tools.IsPackage())
				{

					return InternalResourcesPath_Package;

                }

            ...
			}
		}
		public static string InternalResourcesPath_Package => 
			"Packages/com.acegikmo.shaderforge/Editor/InternalResources/";

将package路径解析为绝对路径

接着 在SF_Editor.TryCreateNewShader这个函数中,我们需要将

			string presetPath = GetShaderPresetPath( preset );
            //StreamReader presetReader = new StreamReader( Application.dataPath + presetPath.Substring( 6 ) );

修改为

			string presetPath = GetShaderPresetPath( preset );

            string fullPath = Application.dataPath + presetPath.Substring(6);

			if(SF_Tools.IsPackage())
			{
				fullPath = Path.GetFullPath(presetPath);
			}

            StreamReader presetReader = new StreamReader(fullPath);

参考

Accessing package assets

PackageInfo.FindForAssembly接口

posted @ 2025-05-21 21:02  dewxin  阅读(104)  评论(0)    收藏  举报