using GCGame; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; // 注:JoyStickLogic运动范围由JoyStickRoot决定 // 默认JoyStickRoot左下角 = 屏幕(0,0)位置,如有修改,给ScenePointToRootOffset函数加上对应偏移 public class JoyStickLogic : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUpHandler { private const float _idleAlpha = 0.7f; private const float _activeAlpha = 1f; public int? CurrentPointerId { get; private set; } // 摇杆输入 public Vector2? input { get; private set; } private RectTransform _rectTransform; // 自适应位置范围 private RectTransform _flexibleArea; // 可移动部分根节点 private Image _background; // 方向箭头 private Image _arrow; // 方向球 private Image _joyStick; // 摇杆左下角位置偏移 private Vector2 _anchorPos; // 摇杆可运动区域最小xy,最大xy private Vector4 _joyStickArea; // 摇杆原始位置 private Vector2 _originPos; private float _joyStickRadius; private void Awake() { _rectTransform = (RectTransform)transform; _flexibleArea = (RectTransform)_rectTransform.Find("FlexibleArea"); _background = _rectTransform.Find("BackGround").GetComponent(); _joyStick = _background.transform.Find("JoyStickSprite").GetComponent(); _arrow = _background.transform.Find("Arrow").GetComponent(); _originPos = _background.rectTransform.anchoredPosition; _anchorPos = _rectTransform.anchoredPosition; } // Use this for initialization private void Start() { SetPressed(false); SetMoving(false); var flexibleRect = _flexibleArea.rect; var joyStickRect = _background.rectTransform.rect; _joyStickArea = new Vector4(joyStickRect.size.x * 0.5f, joyStickRect.size.y * 0.5f, flexibleRect.size.x - joyStickRect.size.x * 0.5f, flexibleRect.size.y - joyStickRect.size.y * 0.5f); if (_joyStickArea.x > _joyStickArea.z) _joyStickArea.z = _joyStickArea.x; if (_joyStickArea.y > _joyStickArea.w) _joyStickArea.w = _joyStickArea.y; _joyStickRadius = _background.rectTransform.rect.width * 0.5f - _joyStick.rectTransform.rect.width * 0.5f; } public void OnPointerDown(PointerEventData eventData) { if (PlayerPreferenceData.SystemUseJoyStick && CurrentPointerId == null && ProcessInput.Instance != null && !ProcessInput.Instance.isBlocked) { CurrentPointerId = eventData.pointerId; SetPressed(true); var uiPos = UIManager.Instance().ScreenPointToUiPoint(eventData.position, false) - _anchorPos; uiPos.x = Mathf.Clamp(uiPos.x, _joyStickArea.x, _joyStickArea.z); uiPos.y = Mathf.Clamp(uiPos.y, _joyStickArea.y, _joyStickArea.w); _background.rectTransform.anchoredPosition = uiPos; } } // // public void OnBeginDrag(PointerEventData eventData) // { // if (CurrentPointerId == eventData.pointerId) // SetMoving(true); // } public void OnDrag(PointerEventData eventData) { if (PlayerPreferenceData.SystemUseJoyStick && CurrentPointerId == eventData.pointerId) { var uiPos = UIManager.Instance().ScreenPointToUiPoint(eventData.position, false) - _anchorPos; var delta = uiPos - _background.rectTransform.anchoredPosition; if (delta == Vector2.zero) { input = Vector2.zero; SetMoving(false); } else { input = delta.normalized; var magnitude = delta.magnitude; delta = input.Value * Mathf.Min(magnitude, _joyStickRadius); SetMoving(true); // 注:箭头图标原始方向是向右的 _arrow.rectTransform.localRotation = Quaternion.FromToRotation(Vector3.right, (Vector3)input.Value); } _joyStick.rectTransform.anchoredPosition = delta; } } public void OnPointerUp(PointerEventData eventData) { if (CurrentPointerId == eventData.pointerId) ReleaseJoyStick(); } // // //private void OnEnable() // //{ // // GameManager.AddLateUpdate(UpdateJoyStick, GameManager.joyStickUpdateOrder); // //} // // //private void OnDisable() // //{ // // GameManager.RemoveLateUpdate(UpdateJoyStick, GameManager.joyStickUpdateOrder); // //} // // /// // /// 发送摇杆状态 // /// // private void SendMoveDirection() // { // CurrentInput = mRect_JoySticSprite.anchoredPosition; // if (CurrentInput != Vector2.zero) // CurrentInput = CurrentInput.normalized; // } // private Vector2 ScenePointToRootOffset(Vector2 screenPoint) // { // // 按照100单位比,JoyStickRoot左下角 = 屏幕(0,0)位置; // // 如果有特殊Ui尺寸或者其他修改,需要额外处理; // return UIManager.Instance().ScreenPointToUiPoint(screenPoint, false); // } public void CloseWindow() { ReleaseJoyStick(); gameObject.SetActive(false); } public void OpenWindow() { gameObject.SetActive(true); } public void ReleaseJoyStick() { input = null; CurrentPointerId = null; SetPressed(false); SetMoving(false); _background.rectTransform.anchoredPosition = _originPos; _joyStick.rectTransform.anchoredPosition = Vector2.zero; } private void SetPressed(bool isActive) { SetImageAlpah(_background, isActive); SetImageAlpah(_joyStick, isActive); } private void SetMoving(bool isMoving) { _arrow.gameObject.SetActive(isMoving); } private static void SetImageAlpah(Graphic image, bool isActive) { var color = image.color; color.a = isActive ? _activeAlpha : _idleAlpha; image.color = color; } // // public bool IsInBackClick(Vector3 clickPoint) // { // var pointVec = Utils.PositionToRectLocal(mRect_backClick, clickPoint); // return mRect_backClick.rect.Contains(pointVec); // } // // public void OnPointerDown(Vector2 point) // { // if (!IsCloseWindow) // { // IsActive = true; // // 拖动时重设精灵透明度 // SetImageAlpah(m_JoyStickSprite, 1); // SetImageAlpah(m_BackGround2, 1); // mRect_JoySticSpriteArrow.gameObject.SetActive(true); // OnDrag(point); // } // } // // public void ArrowDirect() // { // Vector3 localPos = mRect_JoySticSpriteParent.InverseTransformPoint(mRect_JoySticSprite.position); // float angle = Vector3.Angle(localPos, new Vector3(1, 0, 0)); // int dir = localPos.y < 0 ? -1 : 1; // mRect_JoySticSpriteArrow.localEulerAngles = new Vector3(0, 0, angle * dir); // } // // public void OnDrag(Vector2 point) // { // if (!IsCloseWindow) // { // var newPos = ScenePointToRootOffset(point); // // 小球尚未超出偏移范围时 // if ((newPos - mRect_JoySticSpriteParent.anchoredPosition).magnitude < _parentRadius) // mRect_JoySticSprite.anchoredPosition = newPos - mRect_JoySticSpriteParent.anchoredPosition; // // 小球超出偏移范围,需要移动外圈时 // else // { // // 算法比较麻烦 - 先用小球移动外圈的位置,然后用外圈和偏移值确定小球位置 // var offset = newPos - mRect_JoySticSpriteParent.anchoredPosition; // // 圈内预期偏移数值 // var offsetInCircle = offset.normalized * _parentRadius; // // 外圈预期位置,然后用边界进行校正 // var newParentPos = newPos - offsetInCircle; // newParentPos = GetSpritePosInBoundary(_parentRadius, newParentPos); // mRect_JoySticSpriteParent.anchoredPosition = newParentPos; // // 重新对齐小球位置 // mRect_JoySticSprite.anchoredPosition = offsetInCircle; // } // ArrowDirect(); // } // } // // public void OnPointerUp() // { // // 恢复摇杆精灵透明度 // ReleaseJoyStick(); // } // // /// // /// 在满足边界范围的情况下,移动目标RectTransform // /// // /// 目标半径 // /// 目标预期位置 // /// // private Vector2 GetSpritePosInBoundary(float radius, Vector2 anchoredPosition) // { // var maxPos = _rectTransform.rect.size - Vector2.one * radius; // var minPos = Vector2.one * radius; // anchoredPosition.x = Mathf.Clamp(anchoredPosition.x, minPos.x, maxPos.x); // anchoredPosition.y = Mathf.Clamp(anchoredPosition.y, minPos.y, maxPos.y); // return anchoredPosition; // } // // private void UpdateJoyStick() // { // if (IsActive) // SendMoveDirection(); // else // CurrentInput = Vector2.zero; // } }