この記事でのバージョン
Unity 5.2.2f1 Personal
NGUI 3.9.2
はじめに
ボタンなどが無いところのタップを処理したいって場合ありますよね。
例えば、画面をタップして次のシーンへとかそんな感じの時です。
NGUIではそんな時にUICamera.fallThroughを使うと便利です。。
UICamera.fallThroughとは以下の通りで、
どのUICameraから見てもタッチできるオブジェクトがなかった場合に、このfallThroughで指定したGameObjectにメッセージが飛ぶようになります
以下のようにGameObjectをfallThroughに登録すると、
いちいちColliderを設定しなくてもタッチを取得できる優れもの。
UICamera.fallThrough = gameObject;
ただ、このfallThroughを受け取れるオブジェクトは一つだけなので、
そのまま使ってしまうと一つのクラスが肥大化してしまいそうです。
そこで、fallThroughを受け取るクラスにタッチイベントが起こった時に実行するEventを作成し、
そのEventに他のクラスからメソッドを登録するようにしてみました。
具体的にいうと以下のような感じ
private void Start(){ //イベントにメソッドを登録 FallThroughCatcher.Instance.onPressStart += OnPressStart; } //タップした瞬間に実行される private void OnPressStart(){ Debug.Log ("タップ!"); }
これでfallThroughを受け取るクラスが無闇に肥大化する事も無いと思います。
なお、EventとかDelegateなんぞ知らんって方は以下の記事をどうぞ。
Eventを知らずとも次で紹介するFallThroughCatcherを使う事はできますが、
EventにしろDelegateにしろ匿名関数にしろ、かなり便利なので習得?をおすすめします。
FallThroughCatcher
ではでは肝心のコードです。
この、FallThroughCatcher はSingletonMonoBehaviourというクラスを継承しているので、
そんなの知らない!って方はこちらもご確認ください。
使い方はFallThroughCatcher をてきとうなオブジェクトに付けて、
以下のようにイベントにメソッドを追加したり削除したりするだけです。
//イベントにメソッドを追加 FallThroughCatcher.Instance.onPressStart += OnPressStart; //イベントからメソッドを削除 FallThroughCatcher.Instance.onPressStart -= OnPressStart;
基本的に一度追加したらそのままで大丈夫だとは思いますが、
イベント登録したあと、そのオブジェクトがDestoryされてしまうとエラーになるので、
Destoryする場合はイベントからメソッドを削除しましょう。
また、マルチタッチを有効にしている場合はUICamera.currentTouchIDを使うことで、
それぞれの指を識別できます。
private void Start(){ //イベントにメソッドを登録 FallThroughCatcher.Instance.onPressStart += OnPressStart; } //タップした瞬間に実行される private void OnPressStart(){ Debug.Log ("タップした指のID : " + UICamera.currentTouchID); }
さらに、
IsRunningPinchで現在ピンチ中か、
IsRunningDragで現在ドラック中か、
IsPressingで現在プレス(タップ)中か
を判別することが出来ます。
if(FallThroughCatcher.Instance.IsRunningPinch){ //ピンチ中 } if(FallThroughCatcher.Instance.IsRunningDrag){ //ドラック中 } if(FallThroughCatcher.Instance.IsPressing){ //プレス中 }
イベント一覧
以下がFallThroughCatcher にあるイベント一覧です。
//========================================== //クリックorタップ(スマホでのタッチを取得可能) //========================================== //画面を押したor押して離した時 Action<bool> onPress = delegate {}; //画面を押した時(OnPress(true)時) Action onPressStart = delegate {}; //画面を離した時(OnPress(false)時) Action onPressEnd = delegate {}; //オブジェクトを押した時or離した時、ただし同じものを連続で選択しても実行されない Action<bool> onSelect = delegate {}; //クリックされた時(OnPress(false)時) Action onClick = delegate {}; //ダブルクリックされた時(OnClickも同時に呼ばれる) Action onDoubleClick = delegate {}; //========================================== //ドラッグorスワイプ(スマホでのタッチを取得可能) //========================================== //ドラッグ開始時 Action onDragStart = delegate {}; //ドラッグ終了時 Action onDragEnd = delegate {}; //OnPress(true)とOnPress(false)の間に起きた移動を取得、deltaにフレーム間に移動した距離が渡される。 Action<Vector2> onDrag = delegate {}; //別のオブジェクトでドラッグを開始した際に、このオブジェクト上にポインタが初めて重なったときに実行。 //draggedObject にはドラッグを開始したオブジェクトが渡される。 Action<GameObject> onDragOver = delegate {}; //OnDragOver 後に、このオブジェクト上からポインタが外れた場合に実行。 //draggedObject にはドラッグを開始したオブジェクトが渡される。 //このオブジェクト上でドラッグを終了した場合も実行される。 Action<GameObject> onDragOut = delegate {}; //ピンチ中 Action<float> onPinch = delegate {}; //ピンチ開始時 Action onPinchStart = delegate {}; //ピンチ終了時 Action onPinchEnd = delegate {}; //========================================== //入力装置関係 //========================================== //カーソルがコライダーの上に乗ったor離れた時 Action<bool> onHover = delegate {}; //マウスのホイールを動かした時 Action<float> onScroll = delegate {}; //キーボードが押された時 Action<KeyCode> onKey = delegate {}; //========================================== //詳細不明、いつ呼ばれるのかよく分からないけどとりあえず実装 //========================================== //OnPress(false)のタイミングに下にあるオブジェクト側で呼ばれる。 //goには、上にあるオブジェクトが渡される。 //FallThroughCatcherじゃ呼ばれない??? Action<GameObject> onDrop = delegate {}; //テキストがインプットされた時??? Action<string> onInput = delegate {}; //??? Action<bool> onTooltip = delegate {}; //サブミットした時??? Action onSubmit = delegate {};
onPressStart 、onPressEnd、onPinch, onPinchStart, onPinchEnd
はNGUIのデフォルトであるものではなく、独自に作ったものです。
なおタッチしてる指が2本以上だとOnPinchが呼ばれOnDrag は呼ばれない事に注意が必要です。
おわりに
ただでさえ便利なNGUIがfallThroughを使う事でさらに便利になる記事でした。
とは言え、時代はuGUIなんですかね〜完全に乗り換えるタイミングを逃した今日この頃です(:3っ)∋〜