2014年7月20日日曜日

【Unity、UniRx】ダブルクリックを検知する


@Baiteen

ReactiveExtensionsがUnityでも使えるってのを今更知ったので、今更ながら使ってみた。

環境

・Unity 4.5.1f3
・UniRx 4.3 (AssetStoreから”UniRx”で検索してインポートしました)

やりたいこと

ReactiveExtensionsを使ってダブルクリックイベントを検知する。

やったこと

(UniRxはインポート済み)
まずは、ダブルクリックするためのCubeを追加(Cubeじゃなくてもいい)
それからC#Scriptを作成してコードを以下のように変更(今回はTestScriptにしました)
そしてTestScriptをCubeにドラッグ&ドロップしたら出来上がり
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UniRx;

public class TestScript : ObservableMonoBehaviour
{
  ///  クリック間隔 
  public class ClickInterval
  {
    public TimeSpan Interval { get; set; }
    public Vector3 Location { get; set; }
  }

  ///  ダブルクリックイベント引数 
  public class DoubleClickEventArgs : EventArgs
  {
  ///  クリック間隔リスト 
    public IList ClickIntervals { get; private set; }

    public DoubleClickEventArgs(IList clickIntervals){
      this.ClickIntervals = clickIntervals;
    }
  }

  ///  ダブルクリックイベントハンドラ 
  public event EventHandler DoubleClickEventHander;

  ///  ダブルクリックイベントを発生させます 
  private void OnDoubleClick (IList clickIntervals)
  {
    if (this.DoubleClickEventHander != null) {
      this.DoubleClickEventHander(this, new DoubleClickEventArgs(clickIntervals));
    }
  }

  ///  RXのサンプルがAwakeだったので、ここに書きました。 
  public override void Awake ()
  {
    //参考サイト:http://neue.cc/2010/07/28_269.html

    //今回の場合、この変数は必要ない
    var mouseDoubleClickObservable = 
      //マウスダウンされると値が発行される
      OnMouseDownAsObservable()
        //発行された値と前回の時間との差分を包んだオブジェクトを返す
        .TimeInterval()
        //マウスダウンされた位置もほしいので、自作のクラスにして後続に渡す
        .Select(i => new ClickInterval(){ Interval = i.Interval, Location = Input.mousePosition })
        //ダブルクリックなので2回マウスダウンされるまで貯めこむ
        //トリプルクリックを検知したければここを3にすればいけるんじゃないかな
        .Buffer(2)
        //”1回目のマウスダウン”の”前回の時間との差分”が1秒以上であること
        //これをしないと3クリックで2回ダブルクリックイベントが発生してしまう(1,2と2,3)
        .Where(l => l.First().Interval.TotalSeconds > 1)
        //”1回目のマウスダウン”以外のマウスダウンの”前回の時間との差分”が全て1秒未満であること
        //せっかちの人は0.5とかにしてあげればいいかな
        .Where(l => l.Skip(1).All(i=>i.Interval.TotalSeconds < 1))
        //発行される値の監視を開始。値が発行されたらダブルクリックイベントを発行させる
        .Subscribe(l => this.OnDoubleClick(l));

    this.DoubleClickEventHander += (sender, e) => Debug.Log("double click");

    // If you use ObservableMonoBehaviour, must call base method ← サンプルにこう書いてますので、そのまま。
    base.Awake ();
  }

}

実行してCubeをダブルクリックするとログが吐かれることを確認できる。はず。
こんな感じ。
って、あれ?うに部屋から埋め込みタグをコピー出来なくてサンプル貼れない。。。
まぁいいや。

UniRxの記事が少なすぎて焦った。


スポンサーリンク

Related Posts Plugin for WordPress, Blogger...