原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】UIをDrag&Dropで操作する

新生

うっかり買ってしまった信長の野望にハマってしまい寝不足な皆さんこんにちは。今回の新作は寡兵で大軍を打ち破って一発逆転、という展開が難しいため敵の兵力をいかに目減りさせて局面を有利に運ぶか、が重要となっているのですが、これが面白くて時間を忘れて遊んでしまいます。あと、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のみ実装しただけではドラッグ開始終了の検知ができないようです。

 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。