環境
Unity2020.3.11f1から2021.3.0f1にバージョンアップしたプロジェクトファイル
他の環境でも同様のケースが起きるかは未確認です
CinemachineBrainから約0.7KBのGC Allocが発生していた
似ているケースかどうかの情報を求められていると思うのでその辺りを先に記します。
ProfilerでGC Allocの数値に気付いたタイミングが微妙なのでいつから発生していたかは分かりません。
導入の経路
- 2020の環境で初期のStarter Assetsをインポート
- このアセットではCinemachineを使用しているので同じタイミングでCinemachineもインポートしていた
- Unity バージョン2021のLTSが発表されたのでプロジェクトをバージョンアップ
- その後にCinemachineもStarterAssetsもアップデートがきたのでGC解決時点で最新にしています(4/26)
GC Allocは2ヵ所で発生していた
- CinemachineBrain.LateUpdate() …赤枠の部分
- GUI.Repaint …青色の部分
この2パターンから発生していました。どちらもCinemachineBrainから呼ばれていますが連動している訳ではないようです。
1つ目から順に説明します。
CinemachinePostProcessing (336B)
赤枠で囲った方のGC Allocです。CinemachineBrainのLateUpdate関数からCinemachinePostProcessingクラスのstatic関数を参照しています。

この青い選択範囲の処理がGCの原因でした。UnityEventへの操作で無駄なゴミを生成しています。
赤枠で囲ったディレクティブでポストプロセスが2018以降であれば必ずこの辺りを通るはずです。なのでローカルのlayerがnullにならないようにすることで対処します1。
対処方法

CinemachineBrainを持つGameObjectに、"Post-process Layer"コンポーネントをアタッチします。インスペクターとGCサイズに注目してください。

これで多分OKです。コンポーネントさえ付いていればOffにしても問題ありません。
GUI.Repaint
青色の方のGC Allocです。こっちは実害がないので放置しても問題ないようです。

OnGUIの処理がGCを発生させています。ですが、エディター上でしか処理されないので、ゲームとして世に出せばGCは発生しません。ここでGCが発生していても軽微な場合放置した方が管理面でも良いかもしれません。
気になるので消したい場合、方法はいくつかありますが、一例としてシンプルな方法を紹介します。
対処方法
あえて放置しない場合、このようなスクリプトを用意してください。
using UnityEngine;
public class Example : MonoBehaviour {
void Start() {
if (TryGetComponent(out Cinemachine.CinemachineBrain brain) {
brain.useGUILayout = false;
}
}
}
これをCinemachineBrainを持つGameObjectにアタッチすると、

※ GCサイズに注目

これでOKです。"WorkMono"は上で用意したExampleスクリプトです
動画バージョンもあります
この記事の画像は動画の方から切り取ってきました。
もしよろしければ、動画の方も見ていただけたら嬉しいです。
YouTube Link
感想
初めてQiitaで記事を書きましたが、とても疲れました……
HTMLでも行けそうだったのでごり押しで行こうと思ったんですが、画像とか注釈とか色々うまく行かなくて逆に手間と時間が増えました。
今回は記事内容についてより、QiitaやYouTube、Twitter等で情報発信の作業を一通り確認することが目的だったので、そういう意味では良い勉強になりました。
-
ただ、ポストプロセスを使用しない場合とか結構簡単にこのケースを踏みそうに思うんですけど、私が何か根本的に勘違いしている気がしてます。教えてください。 ↩
