Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
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 - Fatal编程技术网

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调用它时,一次是在we
DestroyImmediate(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调用它时,一次是在we
DestroyImmediate(this)
时)。请在调用
destroyedImmediate(this)
之前设置
destroyedAlready


虽然不是原始问题的精确解决方案,也不是一个好的解决方案,但它确实有效,可以防止内存泄漏,同时保持类的静态性质。

类不必是静态的。您只需将其中的函数设置为静态即可。…@程序员的观点很好。但即使它是一个可脚本化对象,也不能监听unity生命周期事件,对吗?因为场景中没有游戏对象,所以类不必是静态的。您只需将其中的函数设置为静态即可。…@程序员的观点很好。但即使它是一个可脚本化对象,也不能监听unity生命周期事件,对吗?因为场景中没有游戏对象?