【工作筆記】手勢——單指滑動+點擊+多指縮放滑動

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

//點擊到UI上是沒有效果的
public class GestureInput {

    //單指、多指、點擊 事件的觸發
    public Action<InputEventData> OnSingleFinger;
    public Action<InputEventData> OnMultipleFinger;
    public Action<InputEventData> OnShortClick;
    
    private int m_FingerState;//1-單指,2-多指   其實這裏用枚舉會更容易理解一點,不會滿屏的數字
    private float distance;
    private Vector2 m_OldMultiplePosition_0, m_OldMultiplePosition_1;
    private Vector2 m_LastSinglePosition;
    private InputEventData InputEventData;
    private float time;
    private Vector2 StayPos;
    
    public void Init()
    {
        InputEventData = new InputEventData();
    }


    public void OnDispose()
    {
        InputEventData = null;
    }

    //沒有加入自身MonoBehaviour,是因爲遊戲有打開界面暫停遊戲的需求,所以此處在外部系統裏調用最爲方便。
    public void Update(float deltaTime)
    {
        if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
        {
            if (Input.touchCount == 1)
            {
                if (Input.GetTouch(0).phase == TouchPhase.Began || m_FingerState == 2)
                {
                    if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId) && m_FingerState != 2)
                    {
                        m_FingerState = 0;
                    }
                    else
                    {
                        m_FingerState = 1;
                        m_LastSinglePosition = Input.GetTouch(0).position;
                        if (Input.GetTouch(0).phase == TouchPhase.Began)
                        {
                            StayPos = Input.GetTouch(0).position;
                            time = 0f;
                        }
                    }
                }
                if (m_FingerState == 1 && Input.GetTouch(0).phase == TouchPhase.Ended)
                {
                    Cal_ShortClick(Input.GetTouch(0).position);
                }
                if (m_FingerState == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
                {
                    Cal_SingleTouch(Input.GetTouch(0).position);
                    time += deltaTime;
                }
            }
            else if (Input.touchCount > 1)
            {
                if ((Input.GetTouch(0).phase == TouchPhase.Began && Input.GetTouch(1).phase == TouchPhase.Began) || m_FingerState == 1)
                {
                    if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)
                        && EventSystem.current.IsPointerOverGameObject(Input.GetTouch(1).fingerId) && m_FingerState != 1)
                    {
                        m_FingerState = 0;
                    }
                    else
                    {
                        m_FingerState = 2;
                        m_OldMultiplePosition_0 = Input.GetTouch(0).position;
                        m_OldMultiplePosition_1 = Input.GetTouch(1).position;
                    }
                }
                if (m_FingerState == 2 && (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved))
                {
                    Vector2 tmp_Position_0 = Input.GetTouch(0).position;
                    Vector2 tmp_Position_1 = Input.GetTouch(1).position;
                    float currentTouchDistance = Vector3.Distance(tmp_Position_0, tmp_Position_1);
                    float lastTouchDistance = Vector3.Distance(m_OldMultiplePosition_0, m_OldMultiplePosition_1);
                    distance = (currentTouchDistance - lastTouchDistance) * deltaTime;
                    m_OldMultiplePosition_0 = tmp_Position_0;
                    m_OldMultiplePosition_1 = tmp_Position_1;
                    InputEventData.distance = distance;
                    OnMultipleFinger(InputEventData);
                }
            }
        }
        else //除了手機端和編輯器模式,目前沒有其他平臺要求,所以我沒有多加限制。
        {
            if (Input.GetMouseButtonDown(0))
            {
                if (EventSystem.current.IsPointerOverGameObject())
                {
                    m_FingerState = 0;
                }
                else
                {
                    m_FingerState = 1;
                    StayPos = m_LastSinglePosition = Input.mousePosition;
                    time = 0f;
                }
            }
            if (m_FingerState == 1 && Input.GetMouseButtonUp(0))
            {
                Cal_ShortClick(Input.mousePosition);
            }
            if (Input.GetMouseButtonDown(1)) //模擬鏡頭遠近設置,此處是老大非要我用鼠標右鍵實現= =他不准我用滾輪。
            {
                if (EventSystem.current.IsPointerOverGameObject())
                {
                    m_FingerState = 0;
                }
                else
                {
                    m_FingerState = 2;
                }
            }
            if (m_FingerState == 1)
            {
                if (Input.GetMouseButton(0))
                {
                    Cal_SingleTouch(Input.mousePosition);
                    time += deltaTime;
                }
            }
            else if (m_FingerState == 2)
            {
                if (Input.GetMouseButton(1))
                {
                    InputEventData.distance = Input.GetAxis("Mouse Y");
                    OnMultipleFinger(InputEventData);
                }
            }
        }
    }
    //單指
    void Cal_SingleTouch(Vector2 tmp_SinglePosition)
    {
        Vector2 tmp = tmp_SinglePosition - m_LastSinglePosition;
        InputEventData.x = tmp.x * Time.deltaTime;
        InputEventData.y = tmp.y * Time.deltaTime;
        OnSingleFinger(InputEventData);
        m_LastSinglePosition = tmp_SinglePosition;
    }
    //點擊(根據手指觸屏or鼠標點擊的時間判斷,如果一直點在一個地方不動也算是點擊)
    void Cal_ShortClick(Vector2 vec)
    {
        if (time < 0.25f || StayPos == vec)
        {
            InputEventData.ShortClickPos = StayPos;
            OnShortClick(InputEventData);
            m_FingerState = 0;
        }
    }
}

//老大強烈要求單獨用一個類去傳遞數據,不過,目前我不太懂在這樣一個小功能裏這麼做的用意
public class InputEventData
{
    public float x; //單指狀態下,x軸每幀變化
    public float y; //單指狀態下,y軸每幀變化

    public float distance; //多指狀態下,上一幀手指的距離與此時手指的距離差
    public Vector2 ShortClickPos; //點擊位置
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章