游戏摇杆

using System;
using UnityEngine;
using UnityEngine.EventSystems;

public class JoyStick : MonoBehaviour
{
    enum JoyStickState
    {
        None,
        OnEnter,
        OnStay,
        OnLeave,
    }

    public Transform m_background;
    public Transform m_foreground;
    public Transform m_arrow;

    public float m_radius;

    public Action onEnter;
    public Action<Vector2> onMove;
    public Action onLeave;

    private JoyStickState _js_state;
    private JoyStickState js_state
    {
        get
        {
            return _js_state;
        }
        set
        {
            if (_js_state != value)
            {
                switch (value)
                {
                    case JoyStickState.OnEnter:
                        m_timer = Time.time;
                        break;
                    case JoyStickState.OnStay:
                        SetActive(true, point_pre);
                        break;
                    case JoyStickState.OnLeave:
                        SetActive(false, Vector3.zero);
                        break;
                    default:
                        break;
                }
                _js_state = value;
            }
        }
    }

    private Touch m_touch;
    private int m_touch_ID;

    private float m_timer;
    private Vector3 m_position;

    private Vector2 point_pre;
    private Vector2 point_now;

    public bool m_force = true;

    private void Awake()
    {
        SetActive(false, Vector3.zero);
    }

    private void Update()
    {
#if UNITY_IPHONE || UNITY_ANDROID && !UNITY_EDITOR
        if (Input.touchCount > 0)
        {
            for (int i = 0; i < Input.touchCount; i++)
            {
                m_touch = Input.GetTouch(i);

                switch (m_touch.phase)
                {
                    case TouchPhase.Began:
                        if (!EventSystem.current.IsPointerOverGameObject(m_touch.fingerId))
                        {
                            if (m_touch.position.x <= Content.screen_width_half)
                            {
                                if (PlayerController.instance.canMove)
                                {
                                    m_touch_ID = m_touch.fingerId;
                                    if (onEnter != null)
                                    {
                                        onEnter();
                                    }
                                    js_state = JoyStickState.OnEnter;
                                }
                            }
                        }
                        break;
                    case TouchPhase.Stationary:
                        if (m_touch.fingerId == m_touch_ID)
                        {
                            if (js_state == JoyStickState.OnEnter)
                            {
                                if (Time.time - m_timer > Time.deltaTime)
                                {
                                    point_pre = m_touch.position;
                                    js_state = JoyStickState.OnStay;
                                }
                            }
                            else if (js_state == JoyStickState.OnStay)
                            {
                                point_now = m_touch.position;
                                Vector2 vector = Get_Postion(point_now, point_pre);
                                Vector3 rotation = Get_Rotation(vector);
                                m_foreground.localEulerAngles = rotation;
                                m_arrow.localPosition = vector;

                                if (m_force && onMove != null)
                                {
                                    onMove(vector / m_radius);
                                }
                            }
                        }
                        break;
                    case TouchPhase.Moved:
                        goto case TouchPhase.Stationary;
                    case TouchPhase.Canceled:
                        if (m_touch.fingerId == m_touch_ID)
                        {
                            if (js_state != JoyStickState.OnLeave)
                            {
                                if (onLeave != null)
                                {
                                    onLeave();
                                }
                                js_state = JoyStickState.OnLeave;
                            }
                        }
                        break;
                    case TouchPhase.Ended:
                        goto case TouchPhase.Canceled;
                    default:
                        break;
                }
            }
        }
#else
        if (Input.GetMouseButtonDown(0))
        {
            if (!EventSystem.current.IsPointerOverGameObject())
            {
                //实现左半屏触发
                if (Input.mousePosition.x <= Content.screen_width_half)
                {
                    if (PlayerController.instance.canMove)
                    {
                        if (onEnter != null)
                        {
                            onEnter();
                        }
                        js_state = JoyStickState.OnEnter;
                    }
                }
            }
        }
        if (Input.GetMouseButton(0))
        {
            if (js_state == JoyStickState.OnEnter)
            {
                //等待一帧,区别射线的触发
                if (Time.time - m_timer > Time.deltaTime)
                {
                    point_pre = Input.mousePosition;
                    js_state = JoyStickState.OnStay;
                }
            }
            else if (js_state == JoyStickState.OnStay)
            {
                point_now = Input.mousePosition;
                Vector2 vector = Get_Postion(point_now, point_pre);
                Vector3 rotation = Get_Rotation(vector);
                m_foreground.localEulerAngles = rotation;
                m_arrow.localPosition = vector;

                if (m_force && onMove != null)
                {
                    onMove(vector / m_radius);
                }
            }
        }
        if (Input.GetMouseButtonUp(0))
        {
            if (js_state != JoyStickState.OnLeave)
            {
                if (onLeave != null)
                {
                    onLeave();
                }
                js_state = JoyStickState.OnLeave;
            }
        }
#endif
    }

    /// <summary>
    ///强制中断操纵杆[优先级小于攻击]
    /// </summary>
    public void BreakeJoyStick()
    {
        if (js_state != JoyStickState.OnLeave)
        {
            if (onLeave != null)
            {
                onLeave();
            }
            js_state = JoyStickState.OnLeave;
        }
    }

    private void SetActive(bool state, Vector3 pos)
    {
        if (state)
        {
            pos.x -= Content.screen_width_half;
            pos.y -= Content.screen_height_half;
            pos.x *= Content.screen_width_ratio;
            pos.y *= Content.screen_height_ratio;
            m_background.localPosition = pos;
        }

        GameObject go = m_background.gameObject;
        if (go.activeSelf != state)
        {
            go.SetActive(state);
        }
    }

    private Vector3 Get_Postion(Vector3 point_now, Vector3 point_pre)
    {
        Vector3 vector = point_now - point_pre;

        float ratio = 1;
        float distance = Vector3.Distance(point_now, point_pre);
        if (distance >= m_radius)
        {
            ratio = m_radius / distance;
        }

        return vector * ratio;
    }

    private Vector3 Get_Rotation(Vector2 position)
    {
        Vector3 dir = new Vector3(position.x, 0, position.y);
        Vector3 angle = Quaternion.LookRotation(dir, Vector3.up).eulerAngles;
        return Vector3.forward * angle.y * -1f;
    }
}
View Code
原文地址:https://www.cnblogs.com/Joke-crazy/p/9947196.html