今回はスクリプトからボタン操作時のイベントリスナーを取り付けてみたいと思います。
通常であればボタンのOnClickにボタンをクリックした時に実行するメソッドを指定したり、EventTriggerコンポーネントを取り付け、それぞれの操作に対して実行するメソッドを指定する事で簡単に該当する処理を実行する事が出来ます。
手動で指定する場合は、
↑の記事に記載しています。
ですが、同じボタンを押した時でも違うメソッドを呼び出したい!といった事も必要になる事があります。
そこでスクリプトからボタン操作時のイベントリスナーを追加したり削除したり出来るようにして、これに対応出来るようにします。
ボタンを押した時に実行するメソッドを追加する
まずは簡単なイベントリスナーの追加からやっていきましょう。
まずはヒエラルキー上に右クリック→UI→Buttonを選択し作成します。
ボタンにはAddListenerTest1スクリプトを作成し取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using UnityEngine; using System.Collections; using UnityEngine.UI; public class AddListenerTest1 : MonoBehaviour { private Button testButton; private Text buttonText; // Use this for initialization void Start () { testButton = GetComponent <Button>(); buttonText = testButton.transform.GetChild (0).GetComponent <Text> (); buttonText.text = "test1"; testButton.onClick.AddListener (OnClickButton); } public void OnClickButton() { Debug.Log ("クリックされた"); // ボタンの文字列に応じて書き換える buttonText.text = (buttonText.text == "test1") ? "test2" : "test1"; } } |
StartメソッドでButtonコンポーネントを取得し、ボタンの子要素のTextを書き換えてボタンに表示されるテキストを書き換えています。
ボタンにはOnClickというイベントが発生するので、それに対するイベントリスナーを設定します。
それをしているのが、
1 2 3 | testButton.onClick.AddListener (OnClickButton); |
↑の部分で、ボタンをクリックするイベントが起きた時にOnClickButtonという自前のメソッドを実行するようにAddListenerメソッドで指定しています。
OnClickButtonメソッドではボタンのテキストの文字がtest1だったらtest2に書き換え、test1でなければtest1に書き換えます。
実行すると、
↑のようになりました。
ButtonコンポーネントのOnClickイベントに手動でOnClickButtonメソッドを指定しなくても実行出来ています。
EventTriggerの取り付けとリスナーの設定
次はEventTriggerコンポーネントをスクリプトから取り付け、イベントリスナーの設定を行ってみます。
トリガーイベントを一括削除して再度登録する
まずはEventTriggerコンポーネントを取り付け、イベントリスナーの登録をしてイベントの削除をする時は全部一旦削除してから、再び登録してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | using UnityEngine; using System.Collections; using UnityEngine.UI; using UnityEngine.EventSystems; using System; using System.Collections.Generic; using UnityEngine.Events; public class AddListenerTest2 : MonoBehaviour { private Button testButton; private Text buttonText; private EventTrigger eventTrigger; private EventTrigger.Entry entry; private string eventName; // Use this for initialization void Start () { testButton = GetComponent <Button>(); buttonText = testButton.transform.GetChild (0).GetComponent <Text> (); buttonText.text = "ボタン2"; testButton.onClick.AddListener (OnClickButton); // EventTriggerコンポーネントを取り付ける eventTrigger = testButton.gameObject.AddComponent<EventTrigger> (); // イベントトリガーのEntryクラスを作成 entry = new EventTrigger.Entry (); // イベントの種類を設定 entry.eventID = EventTriggerType.PointerEnter; ChangeOnMouseEnterEvent (); } public void OnClickButton() { Debug.Log ("クリックされた"); ChangeOnMouseEnterEvent (); } // ボタンがクリックされたらイベントを切り替える void ChangeOnMouseEnterEvent() { // 登録しているイベントをクリア eventTrigger.triggers.Clear (); if(eventName == "OnMouseEnter1") { eventName = "OnMouseEnter2"; entry.callback.AddListener (data => OnMyMouseEnter2()); } else { eventName = "OnMouseEnter1"; entry.callback.AddListener (data => OnMyMouseEnter1()); } // イベントトリガーリストに作成したイベントを追加 eventTrigger.triggers.Add (entry); } // ボタンがハイライトされた時に色を赤色にし、サイズは通常サイズ public void OnMyMouseEnter1() { Debug.Log ("OnMyMouseEnter1"); ColorBlock colorBlock = testButton.colors; colorBlock.highlightedColor = Color.red; testButton.colors = colorBlock; testButton.transform.localScale = new Vector3 (1f, 1f, 1f); } // ボタンがハイライトされた時に青色し、サイズを大きくする public void OnMyMouseEnter2() { Debug.Log ("OnMyMouseEnter2"); ColorBlock colorBlock = testButton.colors; colorBlock.highlightedColor = Color.blue; testButton.colors = colorBlock; testButton.transform.localScale = new Vector3 (1.2f, 1.2f, 1.2f); } } |
EventTriggerコンポーネントを取り付けた後、EventTriggerのtriggersのAddListenerメソッドでイベントリスナーを登録します。
AddListenerメソッドにはラムダ式で実行するメソッドを渡しています。
EventTrigger.Entryクラスのインスタンスを生成し、entryID(イベントの種類)とcallback(実行する処理)を設定した後、eventTrigger.triggers.Addで追加しています。
ボタンを押す度にボタン上にマウスが来た時に実行するメソッドを変更してます。
ChangeOnMouseEnterEventメソッドでは実際に実行するメソッドを切り替えていて、eventTrigger.triggersのクリアをして一旦登録したトリガーをクリアにしています。
その後、再度AddListenerで実行するメソッドを登録し、eventTrigger.triggers.Addでイベントを登録しています。
それでは確認してみます。
↑のようにボタンをクリックする度に呼び出すメソッドを変えて処理が変わっています。
イベントリスナーの一部を削除する
先ほどの例ではeventTrigger.triggersのリストを一旦全部削除してから再度イベントリスナーを登録しているので、ちょっとモヤモヤしますね。
そこで、EventTrigger.Entry毎にイベントリスナーを削除するようにしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | using UnityEngine; using System.Collections; using UnityEngine.UI; using UnityEngine.EventSystems; using UnityEngine.Events; public class AddListenerTest3 : MonoBehaviour { private EventTrigger eventTrigger; private Button button; private UnityAction<BaseEventData> unityAction; private EventTrigger.Entry entry1; private EventTrigger.Entry entry2; // Use this for initialization void Start () { button = GetComponent<Button> (); ColorBlock colorBlock = button.colors; colorBlock.highlightedColor = Color.red; button.colors = colorBlock; eventTrigger = gameObject.AddComponent <EventTrigger> (); // ボタン内にマウスが入った時のイベントリスナー登録(ラムダ式で設定) entry1 = new EventTrigger.Entry (); entry1.eventID = EventTriggerType.PointerEnter; entry1.callback.AddListener (data => OnMyPointerEnter((BaseEventData) data)); eventTrigger.triggers.Add (entry1); // Unityアクション設定 unityAction = new UnityAction<BaseEventData> (OnMyPointerClick1); unityAction += new UnityAction<BaseEventData> (OnMyPointerClick2); // ボタンをクリックした時のイベントリスナー登録(UnityActionで設定) entry2 = new EventTrigger.Entry (); entry2.eventID = EventTriggerType.PointerClick; entry2.callback.AddListener (unityAction); eventTrigger.triggers.Add (entry2); } void OnMyPointerEnter(BaseEventData data) { Debug.Log ("OnMyPointerEnter"); } void OnMyPointerClick1(BaseEventData data) { Debug.Log ("OnMyPointerClick1"); } void OnMyPointerClick2(BaseEventData data) { Debug.Log ("OnMyPointerClick2"); // クリックイベントリスナーの削除 eventTrigger.triggers.Remove (entry1); } } |
ボタンの上にマウスポインタが入った時のイベントリスナー登録はラムダ式で設定してます。
ボタンをクリックした時のイベントリスナー登録にはUnityActionクラスをインスタンス化して設定しています。
UnityActionの場合は+=でそのまま追加でイベントリスナー登録が出来ます。
削除する場合は-=です。
OnMyPointerClick2メソッドではEventTriggerに登録したイベントリスナーを削除する為、Removeメソッドの引数にentry1を設定し、登録したOnMyPointerEnterイベントリスナーを削除しています。
その為、ボタンをクリックするとボタン内にマウスが入ってもOnMyPointerEnterメソッドが呼ばれないようになります。
それでは試してみましょう。
↑のように最初はボタンの上にマウスを置くとOnMyPointerEnterメソッドが呼ばれましたが、ボタンをクリックした後はマウスの上に置いても何も実行されなくなりました。
終わりに
ButtonコンポーネントのOnClickやEventTriggerコンポーネントを手動で設定し、イベントが発生したら実行するメソッドを選択出来ますが、
同じボタンでも処理を切り替えたい時等は、スクリプトを使ってイベントリスナーの登録や削除を行うと良さそうですね。(^_^)v