using Unity.VisualScripting; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; /// /// 移动摇杆类型 /// public enum E_RockerType { /// /// 固定 /// Fixed, /// /// 跟随固定 /// FollowFixed, /// /// 跟随 /// Follow, } /// /// 移动摇杆 /// public class Rocker : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler, IEndDragHandler { /// /// 边界 /// public float maxBoundary; /// /// 是否开始拖拽 /// private bool isDrag; /// /// 摇杆底图 /// public Image rockerBM; /// /// 事件触发区域 /// public Image touchRect; /// /// 摇杆控制 /// public Image control; /// /// 摇杆类型 /// public E_RockerType e_RockerType; /// /// 方向监听 /// public UnityAction dirListener; /// /// 抬起按下监听 /// public UnityAction liftPressListener; /// /// 角度监听 /// public UnityAction angleListener; public void Start() { rockerBM.gameObject.SetActive(e_RockerType == E_RockerType.Fixed); } /// /// 是否拖拽 /// /// public bool GetIsDrag() { return isDrag; } /// /// 返回摇杆控制到中心点的模长 /// /// public Vector3 GetMagnitude() { return control.transform.position - rockerBM.transform.position; } public virtual void OnDrag(PointerEventData eventData) { isDrag = true; Vector2 localPos; Vector3 vector= this.transform.position + Vector3.one * maxBoundary - control.transform.position; RectTransformUtility.ScreenPointToLocalPointInRectangle(rockerBM.rectTransform, (eventData as PointerEventData).position, (eventData as PointerEventData).pressEventCamera, out localPos); if (localPos.magnitude > maxBoundary) { if (e_RockerType == E_RockerType.Follow) { rockerBM.transform.localPosition += (Vector3)localPos.normalized * (localPos.magnitude - maxBoundary); } control.transform.localPosition = localPos.normalized * maxBoundary; } else { control.transform.localPosition = localPos; } dirListener?.Invoke(localPos.normalized); float angel = Mathf.Atan2(localPos.x, localPos.y); angleListener?.Invoke(angel * Mathf.Rad2Deg); } public void OnEndDrag(PointerEventData eventData) { isDrag = false; control.rectTransform.anchoredPosition = Vector2.zero; dirListener?.Invoke(Vector2.zero); } public void OnPointerDown(PointerEventData eventData) { Vector2 localPos; liftPressListener?.Invoke(true); rockerBM.gameObject.SetActive(true); if (e_RockerType != E_RockerType.Fixed) { RectTransformUtility.ScreenPointToLocalPointInRectangle(touchRect.rectTransform, (eventData as PointerEventData).position, (eventData as PointerEventData).pressEventCamera, out localPos); rockerBM.transform.localPosition = localPos; } } public void OnPointerUp(PointerEventData eventData) { liftPressListener?.Invoke(false); if (e_RockerType != E_RockerType.Fixed) { rockerBM.gameObject.SetActive(false); } } }