【工作笔记】手势——单指滑动+点击+多指缩放滑动

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; //点击位置
}

 

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