152 lines
3.9 KiB
C#
152 lines
3.9 KiB
C#
using Unity.VisualScripting;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// 移动摇杆类型
|
|
/// </summary>
|
|
public enum E_RockerType
|
|
{
|
|
/// <summary>
|
|
/// 固定
|
|
/// </summary>
|
|
Fixed,
|
|
/// <summary>
|
|
/// 跟随固定
|
|
/// </summary>
|
|
FollowFixed,
|
|
/// <summary>
|
|
/// 跟随
|
|
/// </summary>
|
|
Follow,
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移动摇杆
|
|
/// </summary>
|
|
public class Rocker : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler, IEndDragHandler
|
|
{
|
|
/// <summary>
|
|
/// 边界
|
|
/// </summary>
|
|
public float maxBoundary;
|
|
|
|
/// <summary>
|
|
/// 是否开始拖拽
|
|
/// </summary>
|
|
private bool isDrag;
|
|
|
|
/// <summary>
|
|
/// 摇杆底图
|
|
/// </summary>
|
|
public Image rockerBM;
|
|
|
|
/// <summary>
|
|
/// 事件触发区域
|
|
/// </summary>
|
|
public Image touchRect;
|
|
|
|
/// <summary>
|
|
/// 摇杆控制
|
|
/// </summary>
|
|
public Image control;
|
|
|
|
/// <summary>
|
|
/// 摇杆类型
|
|
/// </summary>
|
|
public E_RockerType e_RockerType;
|
|
|
|
/// <summary>
|
|
/// 方向监听
|
|
/// </summary>
|
|
public UnityAction<Vector2> dirListener;
|
|
|
|
/// <summary>
|
|
/// 抬起按下监听
|
|
/// </summary>
|
|
public UnityAction<bool> liftPressListener;
|
|
|
|
/// <summary>
|
|
/// 角度监听
|
|
/// </summary>
|
|
public UnityAction<float> angleListener;
|
|
|
|
public void Start()
|
|
{
|
|
rockerBM.gameObject.SetActive(e_RockerType == E_RockerType.Fixed);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否拖拽
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool GetIsDrag()
|
|
{
|
|
return isDrag;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回摇杆控制到中心点的模长
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Vector3 GetMagnitude()
|
|
{
|
|
return control.transform.position - rockerBM.transform.position;
|
|
}
|
|
|
|
public virtual void OnDrag(PointerEventData eventData)
|
|
{
|
|
isDrag = true;
|
|
Vector2 localPos;
|
|
Vector3 vector= this.transform.position + Vector3.one * maxBoundary - control.transform.position;
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(rockerBM.rectTransform, (eventData as PointerEventData).position, (eventData as PointerEventData).pressEventCamera, out localPos);
|
|
|
|
if (localPos.magnitude > maxBoundary)
|
|
{
|
|
if (e_RockerType == E_RockerType.Follow)
|
|
{
|
|
rockerBM.transform.localPosition += (Vector3)localPos.normalized * (localPos.magnitude - maxBoundary);
|
|
}
|
|
control.transform.localPosition = localPos.normalized * maxBoundary;
|
|
}
|
|
else
|
|
{
|
|
control.transform.localPosition = localPos;
|
|
}
|
|
dirListener?.Invoke(localPos.normalized);
|
|
|
|
float angel = Mathf.Atan2(localPos.x, localPos.y);
|
|
angleListener?.Invoke(angel * Mathf.Rad2Deg);
|
|
}
|
|
|
|
public void OnEndDrag(PointerEventData eventData)
|
|
{
|
|
isDrag = false;
|
|
control.rectTransform.anchoredPosition = Vector2.zero;
|
|
dirListener?.Invoke(Vector2.zero);
|
|
}
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
Vector2 localPos;
|
|
liftPressListener?.Invoke(true);
|
|
rockerBM.gameObject.SetActive(true);
|
|
if (e_RockerType != E_RockerType.Fixed)
|
|
{
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(touchRect.rectTransform, (eventData as PointerEventData).position, (eventData as PointerEventData).pressEventCamera, out localPos);
|
|
rockerBM.transform.localPosition = localPos;
|
|
}
|
|
}
|
|
|
|
public void OnPointerUp(PointerEventData eventData)
|
|
{
|
|
liftPressListener?.Invoke(false);
|
|
if (e_RockerType != E_RockerType.Fixed)
|
|
{
|
|
rockerBM.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|