Unity UniRxをつかって似非ピンチ処理を作ってみる

raharu(仮名)(プログラマー)
これがダイバージェンス1%の先の世界か。。。

ピンチインアウトって本来2点座標の中間地点を拡大縮小する機能な気がするんですけど、
今回似非なのでカメラの中心点を拡大する形になります。

またエディター上ではマルチタッチが再現できないので、
スペースキー + スワイプで代用します。

前回のソースに追記するので流れがわからない人はこちら

raharu0425.hatenablog.com

これに、ピンチ処理を作ってみます。

using UnityEngine;
using System.Collections;
using System;
using UniRx;
public class CameraMove : MonoBehaviour {
//メインカメラ
public Camera MainCamera;
// Update
void Update () {
#if UNITY_EDITOR
// マウスが押された場合
if (Input.GetMouseButtonUp(0)) {
}else if(Input.GetKey(KeyCode.Space) && Input.GetMouseButton(0)){
//エディターではマルチタッチが再現できないので適当にスペースキー+スワイプでピンチを再現します。
MapPinch();
} else if (Input.GetMouseButton(0)) {
MapSwipe();
}
#elif UNITY_IOS || UNITY_ANDROID
if (Input.touchCount == 0) {
} else if (Input.touchCount == 1) {
MapSwipe();
} else if (Input.touchCount >= 2) {
MapPinch();
}
#endif
}
//スワイプの処理は省略
~Skip
//ピンチの処理
public void MapPinch()
{
#if UNITY_EDITOR
//エディターではマウスポジションで判定する(検証用)
var pinch = Observable.EveryUpdate ().Select (pos_dist => Input.mousePosition.x);
var stop = Observable.EveryUpdate ().Where(_ => Input.GetMouseButtonUp(0));
#elif UNITY_IOS || UNITY_ANDROID
//2点の距離を取得
var pinch = Observable.EveryUpdate ()
.Select (pos_dist => Vector2.Distance(Input.GetTouch (0).position, Input.GetTouch (1).position));
//タッチカウントが2では無くなったら購読停止
var stop = Observable.EveryUpdate ().Where (_ => Input.touchCount != 2);
#endif
//次フレームのポジションを取得して2点座標の差分を取得
IDisposable onPinch = pinch.Zip(pinch.Skip(1), (dist1, dist2) => new { diff = dist2 - dist1})
.TakeUntil(stop)
.Subscribe(distanceParam => {
// カメラのfieldOfViewを変更することでピンチを再現する
MainCamera.fieldOfView -= distanceParam.diff / 30;
//0以下になると反転してしまうので限界値を設ける
if(MainCamera.fieldOfView < 4){
MainCamera.fieldOfView = 4;
}
if(MainCamera.fieldOfView > 70){
MainCamera.fieldOfView = 70;
}
});
}
}

若干動きがあやしいです、
本来はスワイプ > ピンチの状態管理はもっと適切に行う必要があります。


ピンチ - YouTube

ご意見マサカリ歓迎しています!