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