ゆいブロ

自分の好きなことや知見をまとめていくブログです。

スポンサーリンク

【Unity】AssetBundle化したプレハブの中でRenderTextureを持っていたらエラーが出た

はじめに

Timelineの中で、RenderTextureを使用していたところ、

Unity: Releasing render texture that is set as Camera.targetTexture! というエラーが出てしまいました。

バグが起きた環境

  • Unity2019

  • Timelineに必要なアセットをプレハブにまとめ、PlayableDirectorをアタッチし、AssetBundle化

  • 事前にRenderTextureを生成しておいて、TimelineAsset内でRenderTextureの参照を直接持っていた

  • Timelineのプレハブは使用後はPoolし、使いまわしていた

上記の環境でゲームを実行したところ、TimelineのプレハブをAssetbundle.Unloadする際に

Unity: Releasing render texture that is set as Camera.targetTexture!

エラーが出ました。

解決策

RenderTextureをScript上で動的に生成し、随時参照を渡して、

Finalizeのタイミングで動的生成したRenderTextureを解放するようにしました。

Timelineに直接持っているRenderTextureを適切なタイミングで解放し、参照にnullを入れてみたのですが、

そもそもTimelineのプレハブをInstantiateしているため、AssetBundle内のリソース元のプレハブ内では

依然として参照を持っているため、解決しなかったみたいです。

RenderTextureをScript上で扱うために下記のようなコードを書きました。

    /// <summary>
    /// RenderTextureに写すためのカメラ
    /// </summary>
    private Camera renderTextureCamera;
    
    /// <summary>
    /// RenderTextureを表示するためのRawImage
    /// </summary>
    private RawImage rawImage;
    
    /// <summary>
    /// RenderTexture
    /// </summary>
    private RenderTexture renderTexture;

    /// <summary>
    /// RenderTextureの生成
    /// </summary>
    private void CreateRenderTexture()
    {
        renderTexture = new RenderTexture(512,512,24);
        renderTextureCamera.targetTexture = renderTexture;
        rawImage.texture = renderTexture;
    }

    /// <summary>
    /// RenderTextureを解放
    /// </summary>
    private void ReleaseRenderTexture()
    {
        renderTextureCamera.targetTexture = null;
        rawImage.texture = null;
        renderTexture.Release();
        renderTexture = null;
    }

解説

CreateRenderTexture()でRenderTextureのセットアップを行っています。

new RenderTexture(横幅, 縦幅, Depth)で、RenderTextureのサイズとDepthを指定しつつ生成します。

その後に、RenderTextureに画面を写すためのカメラのtargetTextureと、

その映像を表示するためのRawImageのtextureにRenderTextureの参照を代入します。

また、RenderTextureを使用しなくなった場合は、ReleaseRenderTexture()を呼びます。

RenderTextureの参照を持っている変数にnullを代入し、RenderTexture.Release()でRenderTextureを解放します。

こうすることでメモリリークしないようになり、該当のエラーも出ないようになりました。

まとめ

AssetBundleにするアセット内でRenderTextureを使用したい場合は

動的に生成した方が良さそうです。

参考リンク

techblog.kayac.com