Button 等 uGUI の要素には 押されたときなどのイベントをハンドルするために UnityEvent
が利用されています
UnityEvent
にはイベントを登録する方法として下記の2つの方法がある
Inspector から GameObject と メソッドを指定
Script から イベントを登録
private void Start() { _button.onClick.AddListener(Click); } public void Click(){}
がしかし、Script を書く側としては 1 の方法を利用してくしくない
Inspector からメソッドを指定する際の問題 [1]
呼び出すメソッド名が変更されると再度登録し直す必要があり
IDE を利用している際に呼び出し元が探せないので、利用されているかされてないのか分からなくなる
Inspector からメソッドを指定する際の問題 [2]
RemoveAllListeners を呼び出しても削除されない
UnityEvent
には登録したイベントを削除するメソッドとして RemoveAllListener が用意されていますが
こちらは Inspector から登録したイベントを削除できません
/// <summary> /// <para>Remove all non-persisent (ie created from script) listeners from the event.</para> /// </summary> public void RemoveAllListeners() { this.m_Calls.Clear(); }
それもそのはずで RemoveAllListeners で削除するのは m_Calls
に登録されているイベントのみで
Inspector からは m_PersistentCalls
に登録されるためです
public abstract class UnityEventBase : ISerializationCallbackReceiver { private bool m_CallsDirty = true; private InvokableCallList m_Calls; [FormerlySerializedAs("m_PersistentListeners")] [SerializeField] private PersistentCallGroup m_PersistentCalls; }
これに関しては公式にも 非永続的
と記述されているので、確認すればわかるものですが・・・
もし 永続的なイベントの管理をする場合 UnityEventBase.SetPersistentListenerState
から実行しないようにはできそうです