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

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

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

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

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

raharu0425.hatenablog.com

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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

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