(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

ボタンなどを押さなかった時のタッチイベントを取得する【Unity】【uGUI】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 5.3.4f1 Personal

はじめに

ボタンなどを押さなかった時のタッチイベントを処理したいって場合ありますよね。


例えば、画面をタップした時にシーンを移動したいけど、

ボタンを押した時は違う処理をしてシーンの移動はしたくない、みたいな時とかです。


イメージとしては以下のような感じ。


f:id:kan_kikuchi:20160622133949g:plain


ちなみに、NGUIだとfallThroughを使う事で簡単に実現できます。



残念ながらuGUIにはfallThroughのようなものはありません。

なので、UIの一番後ろにタッチイベントを取得するオブジェクトを配置し、

他のUIに触れなかった時のイベントを受け取とる事で、uGUIでも同じような事をしてみました。


f:id:kan_kikuchi:20160622132520j:plain


TouchEventHandler

では、早速コードです!





使い方は上記のTouchEventHandler.csとSingletonMonoBehaviour.csを作成し、

TouchEventHandlerとタッチイベントを取得する範囲を設定するためのImage

AddしたオブジェクトをUIの一番後ろに配置するだけです。


f:id:kan_kikuchi:20160622133334j:plain


この時注意が必要なのがRaycast Targetにチェックを入れる事です。

また、ColorのAを0にして透明にした方が良いかと思います。


イベントを他のスクリプトで受け取りたい時は以下のような感じで、

TouchEventHandler.Instance.on○○というイベントにメソッドを登録します。

イベント?デリゲート?って方はこちらをどうぞ!

using UnityEngine;
using System.Collections;

public class LogTest : MonoBehaviour {

  private void Start () {
    //TouchEventHandlerのイベントにメソッド登録
    TouchEventHandler.Instance.onPress += OnPress;
  }

  private void OnPress(bool isPressed){
    if(isPressed){
      Debug.Log ("タップされた!");
    }
    else{
      Debug.Log ("タップ終わった!");
    }
  }
}


ちなみに最初のイメージ画像はこのLogTestを使ったものです。


f:id:kan_kikuchi:20160622133949g:plain


上記の例では、タップされたorタップが終わった時のイベントを受け取っていますが、

タップ以外にもドラッグやピンチのイベントも取れますし、

現在タップ中かどうかのフラグも参照できます。

/*各動作をした時のイベント*/

TouchEventHandler.Instance.onPress += (isPressed) => {};//タップ開始時と終了時に実行

TouchEventHandler.Instance.onBeginPress += () => {};//タップ開始時に実行
TouchEventHandler.Instance.onEndPress   += () => {};//タップ終了時に実行

TouchEventHandler.Instance.onDrag     += (delta) => {};//ドラッグ中に実行
TouchEventHandler.Instance.onDragIn3D += (delta) => {};//ドラッグ中に実行(deltaはワールド座標)

TouchEventHandler.Instance.onBeginDrag += () => {};//ドラッグ開始時に実行
TouchEventHandler.Instance.onEndDrag   += () => {};//ドラッグ終了時に実行

TouchEventHandler.Instance.onPinch += (delta) => {};//ピンチ中に実行

TouchEventHandler.Instance.onBeginPinch += () => {};//ピンチ開始時に実行
TouchEventHandler.Instance.onEndPinch   += () => {};//ピンチ終了時に実行

/*各動作をしているかのフラグ*/

if(TouchEventHandler.Instance.IsPressing){
  //タップ中
}
if(TouchEventHandler.Instance.IsDragging){
  //ドラック中か
}
if(TouchEventHandler.Instance.IsPinching){
  //ピンチ中
}


ただ、Raycast TargetがTrueになっているImageなどが

TouchEventHandlerより前に表示されていると、

TouchEventHandlerのイベントは発火しなくなる点には注意が必要です。


おわりに

説明は省きましたが、入力イベントはIPointerEnterHandlerなどの

インターフェースを実装することで受け取れるようにしています。



NGUIより若干面倒でしたが、同じような事が出来たので、めでたしめでたし(:3っ)∋〜