まるコットでメモ的な何か

反省文 delegeteは必ず初期化しよう

Unity 2021.3.6f1

何が起きたか

  • Unityでアクションゲーム制作をしていた
  • 対話UIを開いたまま SceneManager.LoadScene() で同じシーンを再読み込みした
  • シーンを再読込した状態で対話UIを開こうとすると、UIを構成するGameObjectが見つからない旨の NullReferenceException が発生した
  • なぜかGameObjectの参照が切れている

トラブルシューティング

  • UIを構成しているGameObjectはInspectorからアタッチしているだけの普通のGameObject
  • シーン再読み込みした際にHierarchyやInspectorの参照を見たところ該当のGameObjectは生きていた
  • 試しにどこで参照が切れたのか Debug.Log() で確認した
    • Start()では参照がある
    • Update()では参照がある
    • UIの表示制御をする際にdelegateで呼ばれるメソッド内では参照が切れている

原因

  • UIの制御で利用していたdelegateの初期化が不十分だったのが原因だった
    • 対話終わりには破棄していたが、対話中にシーン遷移が発生すると破棄されない
  • OnDestroy() で必ず破棄するように修正したところ直った
private void Awake() {
    MyUI.OnTextChange += UpdateUI;
}

private void OnDestroy() {
    MyUI.OnTextChange -= UpdateUI;
}

反省点

  • 原因を突き止めるのにだいぶ時間が掛かった
  • そのためdelegateを使う際は必ず初期化もセットで記述すること

参考

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です