新生
うっかり買ってしまった信長の野望にハマってしまい寝不足な皆さんこんにちは。今回の新作は寡兵で大軍を打ち破って一発逆転、という展開が難しいため敵の兵力をいかに目減りさせて局面を有利に運ぶか、が重要となっているのですが、これが面白くて時間を忘れて遊んでしまいます。あと、COMがやたら好戦的でモタモタしているとあっという間に大勢力を築いてしまうのも気が抜けなくて面白いです。
UIのクリック検知
UnityではボタンやテキストボックスなどのUI機能としてuGUIが搭載されています。
uGUIのButtonコンポーネントを使えばボタンに対するクリックを検知してイベントを発行してくれますが、Buttonコンポーネント以外のUI(テキストやイメージ等)に関してクリックを検知したい場合はIPointerClickHandlerを使う必要があります。
IPointerClickHandlerは先頭に「I」が付いているのでお察しの通りコンポーネントではなくインターフェースなので、IPointerClickHandlerを継承したクラスを作成して使用することになります。
public class ClickEventTest : MonoBehaviour, IPointerClickHandler { // クリックイベント public void OnPointerClick(PointerEventData pointerData){ // クリック時の処理を実装 } }
上のようなスクリプトをクリックを検知したいUIオブジェトにアタッチすることで、そのUIに対するクリックイベントをキャッチします。
下の動画ではTextMeshProUGUIに対するクリックイベントを検知し、そのタイミングで別のオブジェトを下に動かしています。
Drag&Dropしたい
クリックを検知できるのならDrag&Dropのイベントも検知して操作したいところです。
まず、Dragのイベントを検知するにはIDragHandler, IBeginDragHandler, IEndDragHandlerを使用します。
これらはIPointerClickHandler同様、どれもインターフェイスとなっており、それぞれ「Drag中」「Drag開始時」「Drag終了時」の操作時にイベントをキャッチする仕組みとなっています。
public class DragObj : MonoBehaviour,IDragHandler,IBeginDragHandler,IEndDragHandler { public void OnBeginDrag(PointerEventData eventData) { } public void OnDrag(PointerEventData eventData) { // Drag中は位置を更新する transform.position = eventData.position; } public void OnEndDrag(PointerEventData eventData) { } }
イベント発行時に引数として渡されるPointerEventDataにマウスポインタの位置が渡されてくるので、その位置を参照することでDrag操作を行います。
Drop処理
Drop時の処理はOnEndDrag(Drag終了時イベント)で行います。
この時、他のUIと重ねっているか判定したい場合はそれぞれのUIにCollider2Dを設定してOnTriggerEnter2Dで判定します。
この時「IsTrigger」のチェックがONになっている事と、接触判定するUIオブジェトのどちらかにRigidbody2Dのコンポーネントがアタッチされている事を忘れないでください。
bool isOverlap = false; void OnTriggerEnter2D(Collider2D other) { isOverlap = true; } public void OnEndDrag(PointerEventData eventData) { if(isOverlap) { // 重なっている時のDrop動作 } }
下の動画では「カギ」というTextを「カギ穴」というTextへDrag&Drop→OnEndDrag内でTextを「オープン」という表記に変更、ドアを開ける操作をしています。
ちなみにIDragHandler,IBeginDragHandler,IEndDragHandlerはこの3つで1セットとして動作します。
OnTriggerEnterを使うのにOnTriggerStayやOnTriggerExitを実装する必要はありませんが、DragHandlerはそれとは異なり、IBeginDragHandlerやIEndDragHandlerのみ実装しただけではドラッグ開始終了の検知ができないようです。