Files
JJBB/Assets/Project/Script/GUI/Other/JoyStickLogic.cs
2024-08-23 15:49:34 +08:00

258 lines
9.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
// }
}