質問するログイン新規登録

Q&A

解決済

1回答

4842閲覧

EventTriggerの引数でPointerEventDataが使えない。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/03/28 16:41

0

0

前提・実現したいこと

EventTriggerコンポーネントをアタッチする方法で、クリック処理の実装を試みているのですが、
イベントハンドラの引数にPointerEventDataが使えないような挙動になってしまいます。
使えないのでしょうか?
そうすると、PointerEventData.clickCountや、PointerEventData.position等も取得できないのでしょうか?
ご教示お願いします。

試したこと

C#

1public class EventTriggerTest : MonoBehaviour 2{ 3 void Start() 4 { 5 6 } 7 8 public void Mytap(PointerEventData eventData){ 9 //Destroy (this.gameObject); 10 11 if (eventData.clickCount > 1) { 12 Debug.Log (eventData.clickCount); 13 } 14 15 Debug.Log ("eventData.position.x:" + eventData.position.x); 16 Debug.Log ("eventData.position.y:" + eventData.position.y); 17 } 18}

このように、引数にPointerEventDataを指定すると、下図のようにMytapが候補として出てこないです。
イメージ説明

そこで試しに引数を、BaseEventDataに変更してみました。

C#

1public void Mytap(BaseEventData eventData){ 2}

すると、今度は、
イメージ説明
Mytapメソッドが選べるようになります。

しかしMytapメソッドの引数をBaseEventDataにしてしまうと、
メソッド内で「eventData.clickCount」「eventData.position」を取得しようとすると、
下記のようなエラーが出ます。

Assets\EventTriggerTest.cs(18,23): error CS1061: 'BaseEventData' does not contain a definition for 'clickCount' and no accessible extension method 'clickCount' accepting a first argument of type 'BaseEventData' could be found (are you missing a using directive or an assembly reference?)

BaseEventDataは、clickCount等を持っていないということなのだと把握しました。

そうすると、clickCount等を持っていないBaseEventDataを引数に指定して使う方法しかないのでしょうか?

腑に落ちないのは、こちらのリファレンスです。

IPointerClickHandler.OnPointerClick public void OnPointerClick (EventSystems.PointerEventData eventData);

OnPointerClickは、引数にPointerEventDataを指定するように書かれています。
これを見ると、引数にPointerEventDataを指定できるように思えるのですが、いかがでしょうか?
ご教示お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答1

0

ベストアンサー

回答させていただきます。
3つほど方法が思いつきました。

#1 キャストする
全てのイベントタイプの親がBaseEventDataです。PointerEventDataにキャストすることで取得できます。

C#

1using UnityEngine; 2using UnityEngine.EventSystems; 3 4public class EventTriggerTest : MonoBehaviour 5{ 6 public void Mytap(BaseEventData eventData) 7 { 8 var pointerEventData = eventData as PointerEventData; 9 //Destroy (this.gameObject); 10 11 if(pointerEventData != null) 12 { 13 if (pointerEventData.clickCount > 1) 14 { 15 Debug.Log(pointerEventData.clickCount); 16 } 17 18 Debug.Log("eventData.position.x:" + pointerEventData.position.x); 19 Debug.Log("eventData.position.y:" + pointerEventData.position.y); 20 } 21 } 22}

#2 EventTriggerにスクリプトから登録
インスペクタからのアタッチではなくスクリプトから登録もできます。

C#

1using UnityEngine; 2using UnityEngine.EventSystems; 3 4public class EventTriggerTest : MonoBehaviour 5{ 6 [SerializeField] EventTrigger Trigger; 7 8 void Start() 9 { 10 EventTrigger.Entry entry = new EventTrigger.Entry(); 11 entry.eventID = EventTriggerType.PointerClick; 12 entry.callback.AddListener((data) => { Mytap((PointerEventData)data); }); 13 Trigger.triggers.Add(entry); 14 } 15 16 public void Mytap(PointerEventData eventData) 17 { 18 //Destroy (this.gameObject); 19 20 if (eventData.clickCount > 1) 21 { 22 Debug.Log(eventData.clickCount); 23 } 24 25 Debug.Log("eventData.position.x:" + eventData.position.x); 26 Debug.Log("eventData.position.y:" + eventData.position.y); 27 } 28}

#3 IPointerClickHandlerを実装する
もしUnityEngine.UI.Imageなどのイベントを受け取れるオブジェクトにスクリプトをアタッチしているのでしたらインターフェィスを実装するのがコード量が少なくて済みます。この場合、EventTriggerは必要無いので削除しても問題ありません。

C#

1using UnityEngine; 2using UnityEngine.EventSystems; 3 4public class EventTriggerTest : MonoBehaviour , IPointerClickHandler 5{ 6 public void OnPointerClick(PointerEventData eventData) 7 { 8 if (eventData.clickCount > 1) 9 { 10 Debug.Log(eventData.clickCount); 11 } 12 13 Debug.Log("eventData.position.x:" + eventData.position.x); 14 Debug.Log("eventData.position.y:" + eventData.position.y); 15 } 16}

投稿2019/03/28 18:22

IShix

総合スコア1729

退会済みユーザー

退会済みユーザー

2019/03/29 07:05 編集

ご回答ありがとうございます。 「1 キャストする」が1番意図したかったことでした、解決しました。 ありがとうございます。 1のコードなのですが、 「if(pointerEventData != null)」は、どういった必要性があって書かれていますか? pointerEventDataがnullになることはなさそうと思ったのですが、ご教示いただきたいです。 このif文を書かずに検証した所、特に不具合等がわからなかったです。 3のコードの方では、このようなnullチェックはされていないのですね。
IShix

2019/03/29 22:05

解決できてよかったです。 as演算子はキャストに失敗した場合エラーにならずnullを返すので習慣的にnullチェックしてます。どのタイミングでエラーになるか分からないので入れなくても良いです。 3はキャストしていないのでnullチェックしてません。
退会済みユーザー

退会済みユーザー

2019/03/30 05:39

ご回答ありがとうございます。 なるほど、as演算子はキャスト失敗時にnullを返すので、nullチェックされていたということなのですね。 疑問点が全て解消されました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問