Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.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
C# Camera.targetTexture=新建渲染器时内存泄漏(…)_C#_Unity3d_Rendering - Fatal编程技术网

C# Camera.targetTexture=新建渲染器时内存泄漏(…)

C# Camera.targetTexture=新建渲染器时内存泄漏(…),c#,unity3d,rendering,C#,Unity3d,Rendering,我已经编写了一个编辑器窗口,它将摄影机的视图渲染到一个附加的编辑器窗口中。为了在调整窗口大小时立即进行调整,相机的目标纹理将在勾选时间重新指定(实际上仅在必要时进行),以演示问题: public class PlayerViewWindow : EditorWindow { private Camera PlayerViewCamera; // References a camera in the scene public void OnGUI() {

我已经编写了一个编辑器窗口,它将摄影机的视图渲染到一个附加的编辑器窗口中。为了在调整窗口大小时立即进行调整,相机的目标纹理将在勾选时间重新指定(实际上仅在必要时进行),以演示问题:

public class PlayerViewWindow : EditorWindow
{
    private Camera PlayerViewCamera; // References a camera in the scene

    public void OnGUI()
    {
        PlayerViewCamera.targetTexture = new RenderTexture((int)position.width, (int)position.height, 24, RenderTextureFormat.ARGB32);
        PlayerViewCamera.Render();
        GUI.DrawTexture(new Rect(0, 0, position.width, position.height), PlayerViewCamera.targetTexture);       
    }
}
当我激活此窗口时,重新指定摄影机目标纹理会导致内存泄漏。那么:为什么旧的目标纹理没有被垃圾收集? 有没有办法显式破坏旧的目标纹理

感谢您

来自:

与其他“本机引擎对象”类型一样,重要的是要注意任何渲染纹理的生存期,并在使用release函数后释放它们,因为它们不会像普通托管类型那样被垃圾收集

因此,在附加新的渲染器之前,只需调用旧的渲染器即可:

public class PlayerViewWindow : EditorWindow
{
    private Camera PlayerViewCamera; // References a camera in the scene

    public void OnGUI()
    {
        if(PlayerViewCamera.targetTexture != null)
        {
            PlayerViewCamera.targetTexture.Release();
        }

        PlayerViewCamera.targetTexture = new RenderTexture((int)position.width, (int)position.height, 24, RenderTextureFormat.ARGB32);
        PlayerViewCamera.Render();
        GUI.DrawTexture(new Rect(0, 0, position.width, position.height), PlayerViewCamera.targetTexture);       
    }
}

你必须像他在回答中所说的那样,在使用完
渲染器之后释放它。不幸的是,每次调用
OnGUI
时,创建和销毁
RenderTexture
的成本很高,而且调用
OnGUI
的频率甚至比调用
Update
函数的频率还要高

最好使用
RenderTexture.GetTemporary
获取临时渲染,然后在使用完后使用
RenderTexture.releaseTimorary
释放它。请注意,在过去的一些平台上,
RenderTexture.ReleaseTemporary
函数有一个bug。我假设它现在是固定的,但如果你遇到问题,然后坚持解决方案

public class PlayerViewWindow : EditorWindow
{
    private Camera PlayerViewCamera; // References a camera in the scene

    public void OnGUI()
    {
        Vector2 size = new Vector2(position.width, position.width);
        //Get temporary RenderTexture
        RenderTexture tempRT = RenderTexture.GetTemporary((int)size.x, (int)size.y, 24, RenderTextureFormat.ARGB32);
        PlayerViewCamera.targetTexture = tempRT;
        PlayerViewCamera.Render();
        GUI.DrawTexture(new Rect(0, 0, size.x, size.x), PlayerViewCamera.targetTexture);
        //Release temporary RenderTexture
        RenderTexture.ReleaseTemporary(tempRT);
    }
}