游戏摇杆
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }