Unity3d 如何销毁在静态类中创建的unity对象? 请考虑下面的代码。它从特定路径创建材质和着色器。这是一个在编辑器扩展中使用的实用程序 public static class GpuImageProcessing { private static readonly string matPath = Application.dataPath + "/Uplus/Zcommon/Material/ImageProcessing/"; private static Shader Gaussian2D5Shader; private static Material Gaussian2D5Mat; static GpuImageProcessing() { Gaussian2D5Shader = (Shader) AssetDatabase.LoadAssetAtPath(matPath + "Gaussian2D5.shader", typeof(Shader)); Gaussian2D5Mat = new Material(Gaussian2D5Shader); } }
现在的问题是,每次更改脚本时,如何在编辑器重新编译之前销毁此材料?我的意思是,在更改某些代码后,编辑器需要重新编译脚本并创建新的执行上下文,然后将创建此Unity3d 如何销毁在静态类中创建的unity对象? 请考虑下面的代码。它从特定路径创建材质和着色器。这是一个在编辑器扩展中使用的实用程序 public static class GpuImageProcessing { private static readonly string matPath = Application.dataPath + "/Uplus/Zcommon/Material/ImageProcessing/"; private static Shader Gaussian2D5Shader; private static Material Gaussian2D5Mat; static GpuImageProcessing() { Gaussian2D5Shader = (Shader) AssetDatabase.LoadAssetAtPath(matPath + "Gaussian2D5.shader", typeof(Shader)); Gaussian2D5Mat = new Material(Gaussian2D5Shader); } },unity3d,Unity3d,现在的问题是,每次更改脚本时,如何在编辑器重新编译之前销毁此材料?我的意思是,在更改某些代码后,编辑器需要重新编译脚本并创建新的执行上下文,然后将创建此GpuImageProcessing的新版本。我想销毁在上一次运行时创建的材质 PS:这是包含在DLL文件中的,因此我无法将其设置为ScriptableObject并侦听事件回调,也因为它是一个实用程序类,所以我非常喜欢它是静态的。多亏了@Programmer,我找到了一个解决方法来确保材料的销毁。为了使其工作,该类应该成为单例并从Scripta
GpuImageProcessing
的新版本。我想销毁在上一次运行时创建的材质
PS:这是包含在DLL文件中的,因此我无法将其设置为
ScriptableObject
并侦听事件回调,也因为它是一个实用程序类,所以我非常喜欢它是静态的。多亏了@Programmer,我找到了一个解决方法来确保材料的销毁。为了使其工作,该类应该成为单例并从ScriptableObject
继承。然后我们可以实现OnDisable(),它将在编辑器重新编译时被调用。以下是工作示例:
public class GpuImageProcessing:ScriptableObject
{
private static readonly string matPath = "Assets/Uplus/Zcommon/Material/ImageProcessing/";
private Material Gaussian2D5Mat;
private Material Gaussian1DVariableMat;
private static GpuImageProcessing _instance;
private bool destroyedAlready;
public static GpuImageProcessing Instance
{
get
{
if (_instance != null) return _instance;
_instance= CreateInstance<GpuImageProcessing>();
_instance.Init();
return _instance;
}
}
private void Init()
{
var Gaussian2D5Shader = (Shader)AssetDatabase.LoadAssetAtPath(matPath + "Gaussian2D5.shader", typeof(Shader));
Gaussian2D5Mat = new Material(Gaussian2D5Shader);
var gaus1dVarShader = (Shader)AssetDatabase.LoadAssetAtPath(matPath + "Gaussian1DVariable.shader", typeof(Shader));
Gaussian1DVariableMat = new Material(gaus1dVarShader);
}
private void OnDisable()
{
Debug.Log("On disable GpuImgProc");
if(destroyedAlready) return;
DestroyImmediate(Gaussian2D5Mat);
DestroyImmediate(Gaussian1DVariableMat);
destroyedAlready = true;
DestroyImmediate(this);
}
}
公共类GpuImageProcessing:ScriptableObject
{
私有静态只读字符串matPath=“Assets/Uplus/Zcommon/Material/ImageProcessing/”;
专用材料Gaussian2D5Mat;
私人材料Gaussian1DVariableMat;
私有静态GpuImageProcessing_实例;
私人住宅已被摧毁;
公共静态GpuImageProcessing实例
{
得到
{
if(_instance!=null)返回_instance;
_instance=CreateInstance();
_Init();
返回_实例;
}
}
私有void Init()
{
var Gaussian2D5Shader=(Shader)AssetDatabase.loadAssetPath(matPath+“Gaussian2D5.Shader”,typeof(Shader));
Gaussian2D5Mat=新材质(Gaussian2D5Shader);
var gaus1dVarShader=(Shader)AssetDatabase.loadAssetPath(matPath+“gaussian1dvvariable.Shader”,typeof(Shader));
Gaussian1DVariableMat=新材质(gaus1dVarShader);
}
私有无效不可撤销()
{
Log(“On disable GpuImgProc”);
如果(已销毁)返回;
瞬时(高斯2d5mat);
直接(高斯变量);
destroyedAlready=真;
(这个);
}
}
重要提示:请注意destroyedAlready字段。它确保只销毁一次材质,因为OnDisable被调用了两次(一次是在unity editor调用它时,一次是在weDestroyImmediate(this)
时)。请在调用destroyedImmediate(this)
之前设置destroyedAlready
虽然不是原始问题的精确解决方案,也不是一个好的解决方案,但它确实有效,可以防止内存泄漏,同时保持类的静态特性。多亏@Programmer,它找到了一种解决方法,以确保材料的销毁。为了使其工作,该类应该成为单例并从
ScriptableObject
继承。然后我们可以实现OnDisable(),它将在编辑器重新编译时被调用。以下是工作示例:
public class GpuImageProcessing:ScriptableObject
{
private static readonly string matPath = "Assets/Uplus/Zcommon/Material/ImageProcessing/";
private Material Gaussian2D5Mat;
private Material Gaussian1DVariableMat;
private static GpuImageProcessing _instance;
private bool destroyedAlready;
public static GpuImageProcessing Instance
{
get
{
if (_instance != null) return _instance;
_instance= CreateInstance<GpuImageProcessing>();
_instance.Init();
return _instance;
}
}
private void Init()
{
var Gaussian2D5Shader = (Shader)AssetDatabase.LoadAssetAtPath(matPath + "Gaussian2D5.shader", typeof(Shader));
Gaussian2D5Mat = new Material(Gaussian2D5Shader);
var gaus1dVarShader = (Shader)AssetDatabase.LoadAssetAtPath(matPath + "Gaussian1DVariable.shader", typeof(Shader));
Gaussian1DVariableMat = new Material(gaus1dVarShader);
}
private void OnDisable()
{
Debug.Log("On disable GpuImgProc");
if(destroyedAlready) return;
DestroyImmediate(Gaussian2D5Mat);
DestroyImmediate(Gaussian1DVariableMat);
destroyedAlready = true;
DestroyImmediate(this);
}
}
公共类GpuImageProcessing:ScriptableObject
{
私有静态只读字符串matPath=“Assets/Uplus/Zcommon/Material/ImageProcessing/”;
专用材料Gaussian2D5Mat;
私人材料Gaussian1DVariableMat;
私有静态GpuImageProcessing_实例;
私人住宅已被摧毁;
公共静态GpuImageProcessing实例
{
得到
{
if(_instance!=null)返回_instance;
_instance=CreateInstance();
_Init();
返回_实例;
}
}
私有void Init()
{
var Gaussian2D5Shader=(Shader)AssetDatabase.loadAssetPath(matPath+“Gaussian2D5.Shader”,typeof(Shader));
Gaussian2D5Mat=新材质(Gaussian2D5Shader);
var gaus1dVarShader=(Shader)AssetDatabase.loadAssetPath(matPath+“gaussian1dvvariable.Shader”,typeof(Shader));
Gaussian1DVariableMat=新材质(gaus1dVarShader);
}
私有无效不可撤销()
{
Log(“On disable GpuImgProc”);
如果(已销毁)返回;
瞬时(高斯2d5mat);
直接(高斯变量);
destroyedAlready=真;
(这个);
}
}
重要提示:请注意destroyedAlready字段。它确保只销毁一次材质,因为OnDisable被调用了两次(一次是在unity editor调用它时,一次是在weDestroyImmediate(this)
时)。请在调用destroyedImmediate(this)
之前设置destroyedAlready
虽然不是原始问题的精确解决方案,也不是一个好的解决方案,但它确实有效,可以防止内存泄漏,同时保持类的静态性质。类不必是静态的。您只需将其中的函数设置为静态即可。…@程序员的观点很好。但即使它是一个可脚本化对象,也不能监听unity生命周期事件,对吗?因为场景中没有游戏对象,所以类不必是静态的。您只需将其中的函数设置为静态即可。…@程序员的观点很好。但即使它是一个可脚本化对象,也不能监听unity生命周期事件,对吗?因为场景中没有游戏对象?