258 lines
9.2 KiB
C#
258 lines
9.2 KiB
C#
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;
|
||
// }
|
||
} |