Files
JJBB/Assets/Project/Script/GUI/Other/JoyStickLogic.cs

258 lines
9.2 KiB
C#
Raw Permalink Normal View History

2024-08-23 15:49:34 +08:00
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<Image>();
_joyStick = _background.transform.Find("JoyStickSprite").GetComponent<Image>();
_arrow = _background.transform.Find("Arrow").GetComponent<Image>();
_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);
// //}
//
// /// <summary>
// /// 发送摇杆状态
// /// </summary>
// 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();
// }
//
// /// <summary>
// /// 在满足边界范围的情况下移动目标RectTransform
// /// </summary>
// /// <param name="radius">目标半径</param>
// /// <param name="anchoredPosition">目标预期位置</param>
// /// <returns></returns>
// 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;
// }
}