UIのボタンの問題点
Unityでは標準でUIのボタンが用意されており、ボタンを押したときの処理はonClickから設定することができます。
しかし、このonClickが呼び出されるタイミングは少し癖があり自分で実際に調べると「あるボタンをタッチしてからそのボタンの範囲内でタッチを離したとき」に呼び出されていました。
onClickにDebug.Log("OnClick")を搭載した関数を割り当てた例(分かりやすくするためにマウスをクリックしている間は星が赤く、そうでない間は緑色になるようにしています)
実際のゲームではボタンを使うときは押した瞬間などに処理をしてほしいことなどが多いのでその方法を調べまとめてみました。
解決策
結論としてはUIボタンにEvent Triggerを追加して使用するということで解決できました。
使用例(インスペクターから割り当て)
1. UIボタンの追加
まず、Hierarchyのプラスボタンのようなものを押してから「UI」⇒「Button」としてシーン上に任意のUIボタンを追加。
2. Event Triggerの追加
Add Componentから「Event Trigger」を追加します。
3. Event Typeの追加
追加したEvent Triggerに「Add New Event Type」というボタンがあるのでこれをクリックして
- Pointer Up(ボタンを押した瞬間に呼び出す)
- Pointer Down(ボタンを話した瞬間に呼び出す)
を追加します。他のEvent Typeについては
EventTriggerType - Unity スクリプトリファレンスを参考にしてください。
4. スクリプトの作成
以下のスクリプト「Sample.cs」を作成します(比較のためにOnClick()も記述しています)。
using UnityEngine; public class Sample : MonoBehaviour { public void PointerDown() { Debug.Log("PointerDown"); } public void PointerUp() { Debug.Log("PointerUp"); } public void OnClick() { Debug.Log("OnClick"); } }
5. 処理の割り当て
先ほど作成したスクリプトをアタッチして、シーン上のボタンのonClickとPointer Up、Pointer Downにそれぞれ処理を割り当てます。
6. 実行
下の動画が実行結果です
onClickとPointer Downはともに離した瞬間に呼び出されているけど、ボタンの範囲外で離したときはonClickが呼び出されていないことも確認できます。
スクリプトから処理を割り当てる方法
先ほどの例ではインスペクターから
- Event Triggerを追加
- Event Triggerの「Add New Event Type」からPointer UpとPointer Downを追加してこれらに処理を割り当てる
という方法をとりましたが、ここではこれらの処理をスクリプトから行う方法を紹介します(公式ドキュメント参照)。
ソースコード
先ほどの「1. UIボタンの追加」の処理をしてボタンを追加したらそのボタンに以下のスクリプトをアタッチします。
using UnityEngine; using UnityEngine.EventSystems; public class Sample2 : MonoBehaviour { void Start() { //add EventTrigger EventTrigger eventTrigger = gameObject.AddComponent<EventTrigger>(); //Pointer Downの追加 EventTrigger.Entry entry = new EventTrigger.Entry(); entry.eventID = EventTriggerType.PointerDown; entry.callback.AddListener((data) => { PointerDown((PointerEventData)data); }); eventTrigger.triggers.Add(entry); //PointerUpの追加 EventTrigger.Entry entry2 = new EventTrigger.Entry(); entry2.eventID = EventTriggerType.PointerUp; entry2.callback.AddListener((data) => { PointerUp((PointerEventData)data); }); eventTrigger.triggers.Add(entry2); } void PointerDown(PointerEventData data) { Debug.Log("PointerDown from Script"); } void PointerUp(PointerEventData data) { Debug.Log("PointerUp from Script"); } }
実行結果