List型またはDictionary型の変化でイベントを発生させたいです。
以下参考サイトを元に、int型やbool(以下サンプルコードのはbool)などの変数ではイベントの発生は上手くいっているのですが、List型またはDictionary型ではAdd時にNullReferenceExceptionが出て失敗してしまいます。
エラーがNullエラーなので、なにか単純な事を見落としている気がするのですが、そもそも値を追加するAddでなぜNullのエラーが出るのか分からず行き詰っています。
なんとなぁくアクセスしている先が違うのかなぁとは思っているのですが、対応方法も分からずです。
尚、参考サイトではシングルトンで実施していたのでそのままシングルトンを使用していますが、今回はイベント発生検知が主目的であるため、シングルトンである必要はありません。
環境
環境:Unity 2021.1.25f1(2D)
IDE:VisualStudio2019
参考サイト
1:シングルトンを使ってみよう
2:
値の変更を通知するクラス
ソースコード
イベントを検知して処理を実行するスクリプトファイル
C#
1public class SampleEvent : MonoBehaviour 2{ 3 4 private void Start() 5 { 6 //サンプル:単一値変化時のイベントハンドラ登録 7 CameraManager.Instance.TergetValue.Action += ChangeValue; 8 9 //Dictionaryの変化を検知するイベントを登録 10 CameraManager.Instance.DictionaryValue.Action += ChangeDictionary; 11 12 } 13 14 private void Update() 15 { 16 17 } 18 19 20 /// <summary> 21 /// サンプル:値の変更検知時の処理(bool) 22 /// </summary> 23 void ChangeValue(bool value) 24 { 25 Debug.Log("変更された(bool) / " + CameraManager.Instance.TergetValue.Value.ToString()); 26 } 27 28 /// <summary> 29 /// サンプル:値の変更検知時の処理(Dictionary) 30 /// </summary> 31 void ChangeDictionary(Dictionary<string,string> dictionaryValue) 32 { 33 Debug.Log("変更された(Dictionary) / " + CameraManager.Instance.DictionaryValue.Value.Count); 34 } 35 36}
コールする別のスクリプトファイル(値の追加)
※テストとしてボタンのClickイベントでコールしている
C#
1//こちらでは成功 2public void ValueChange() 3{ 4 //成功 5 //サンプル:値を変化(bool) 6 CameraManager.Instance.TergetValue.Value = true; 7} 8 9public void DictionaryChange() 10{ 11 //NullReferenceException: 12 //Object reference not set to an instance of an object 13 //サンプル:Listを変化 14 CameraManager.Instance.DictionaryValue.Value.Add("1","test"); 15 16}
GameManager(シングルトンクラス)
C#
1 2using UnityEngine; 3using System.Collections; 4 5public class GameManager : SingletonMonoBehaviour<GameManager> { 6 7 /// <summary> 8 /// サンプル:値の変化を検知する単一変数 9 /// </summary> 10 /// <remarks>型は要変更</remarks> 11 public NotificationObject<bool> TergetValue = new NotificationObject<bool>(); 12 //List型は省略 13 public NotificationObject<Dictionary<string,string>> DictionaryValue = new NotificationObject<Dictionary<string, string>>(); 14 15}
SingletonMonoBehaviour(参考サイト1をそのまま使用)
C#
1using UnityEngine; 2using System; 3 4public abstract class SingletonMonoBehaviour<T> : MonoBehaviour where T : MonoBehaviour{ 5 6 private static T instance; 7 public static T Instance 8 { 9 get{ 10 if (instance == null) { 11 Type t = typeof(T); 12 13 instance = (T)FindObjectOfType (t); 14 if (instance == null) { 15 Debug.LogError (t + " をアタッチしているGameObjectはありません"); 16 } 17 } 18 19 return instance; 20 } 21 } 22 23 virtual protected void Awake(){ 24 // 他のゲームオブジェクトにアタッチされているか調べる 25 // アタッチされている場合は破棄する。 26 CheckInstance(); 27 } 28 29 protected bool CheckInstance(){ 30 if (instance == null) { 31 instance = this as T; 32 return true; 33 } else if (Instance == this) { 34 return true; 35 } 36 Destroy (this); 37 return false; 38 } 39}
NotificationObject.cs(参考サイト2をそのまま使用)
C#
1using UnityEngine; 2using System.Collections; 3using System; 4 5[System.Serializable] 6public class NotificationObject<T> 7{ 8 public delegate void NotificationAction (T t); 9 10 private T data; 11 12 public NotificationObject (T t) 13 { 14 Value = t; 15 } 16 17 public NotificationObject () 18 { 19 } 20 21 ~NotificationObject () 22 { 23 Dispose (); 24 } 25 26 public UnityEngine.Events.UnityAction<T> action; 27 28 public T Value { 29 get { 30 return data; 31 } 32 set { 33 data = value; 34 Notice (); 35 } 36 } 37 38 private void Notice () 39 { 40 if (action != null) 41 action (data); 42 } 43 44 public void Dispose () 45 { 46 action = null; 47 } 48}
追記:
動的な増減には対応できなかった為、次回質問に続きます。
https://teratail.com/questions/366249?modal=q-comp
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/10/25 10:10 編集
2021/10/26 00:38
2021/10/26 01:34
2021/10/26 03:00