实现简单摇杆
Contents
using ProjectBase.EventCenter;
using ProjectBase.UI;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using EventType = ProjectBase.EventCenter.EventType;
namespace UI.JoyStick
{
public class JoystickPanel : BasePanel
{
private Image mJoystickBg;
private Image mJoystickControl;
private Image mJoystickPanel;
/// <summary>
/// 遥杆初始位置
/// </summary>
private Vector2 mInitLocalPos;
/// <summary>
/// 摇杆按钮移动的最大位置
/// </summary>
private Vector2 mMaxLoaclPos;
/// <summary>
/// 鼠标位置在Bg下的局部坐标
/// </summary>
private Vector2 mLocalPos;
/// <summary>
/// 鼠标位置在面板下的局部坐标
/// </summary>
private Vector2 mBgLocalPos;
void Start()
{
GetChildControl<Image>();
mJoystickBg = GetControl<Image>("JoystickBg");
mJoystickControl = GetControl<Image>("JoystickControl");
mJoystickPanel = GetControl<Image>("JoystickPanel");
mInitLocalPos = mJoystickBg.rectTransform.localPosition;
//为面板添加自定义事件
UIMgr.Instance.AddCustomizeEventListener(gameObject, EventTriggerType.PointerDown,
OnPointerDown);
UIMgr.Instance.AddCustomizeEventListener(gameObject, EventTriggerType.PointerUp, OnPointerUp);
UIMgr.Instance.AddCustomizeEventListener(gameObject, EventTriggerType.Drag, OnDrag);
}
/// <summary>
/// 更新位置数据
/// </summary>
/// <param name="data"></param>
private void UpdatePos(BaseEventData data)
{
mLocalPos = UIMgr.Instance.ScreenPointToLocalPoint(data as PointerEventData, mJoystickBg.rectTransform);
mMaxLoaclPos = mLocalPos.normalized * mJoystickBg.rectTransform.rect.width * 0.5f;
mBgLocalPos =
UIMgr.Instance.ScreenPointToLocalPoint(data as PointerEventData, mJoystickPanel.rectTransform);
}
private void OnPointerDown(BaseEventData data)
{
UpdatePos(data);
if (mLocalPos.sqrMagnitude > mMaxLoaclPos.sqrMagnitude)
{
//如果超过最大距离 让摇杆在手指下方
mJoystickBg.rectTransform.localPosition = mBgLocalPos;
}
}
private void OnPointerUp(BaseEventData data)
{
mJoystickControl.transform.localPosition = Vector2.zero;
mJoystickBg.rectTransform.localPosition = mInitLocalPos;
//分发摇杆抬起事件
EventMgr.Instance.EventTrigger(EventType.JoyStickUp, Vector2.zero);
}
private void OnDrag(BaseEventData data)
{
UpdatePos(data);
if (mLocalPos.sqrMagnitude > mMaxLoaclPos.sqrMagnitude)
{
mJoystickControl.transform.localPosition = mMaxLoaclPos;
//让摇杆跟着手指
mJoystickBg.transform.localPosition = mBgLocalPos - mMaxLoaclPos;
}
else
{
mJoystickControl.transform.localPosition = mLocalPos;
}
//分发摇杆拖拽事件
EventMgr.Instance.EventTrigger(EventType.JoyStickUpdate, mLocalPos.normalized);
}
}
}测试
using ProjectBase.EventCenter;
using ProjectBase.UI;
using UI.JoyStick;
using UnityEngine;
using EventType = ProjectBase.EventCenter.EventType;
public class Move : MonoBehaviour
{
public float Speed = 20;
private Vector3 mDir;
private bool mIsMove;
void Start()
{
UIMgr.Instance.ShowPanel<JoystickPanel>("JoystickPanel",EUiLayer.Top);
EventMgr.Instance.AddEventListener<Vector2>(EventType.JoyStickUpdate, (data) =>
{
mIsMove = true;
ChangeDir(data);
});
EventMgr.Instance.AddEventListener<Vector2>(EventType.JoyStickUp, (data) => { mIsMove = false; });
}
void Update()
{
if (mIsMove)
{
// transform.LookAt(transform.position + mDir);
transform.rotation = Quaternion.LookRotation(mDir);
// transform.Translate(Vector3.forward*Time.deltaTime*Speed,Space.Self);//通过自身的坐标向前移动
transform.Translate(mDir*Time.deltaTime*Speed,Space.World);//通过世界坐标
}
}
private void ChangeDir(Vector2 vector2)
{
mDir.x = vector2.x;
mDir.z = vector2.y;
}
}使用了前面写的事件中心和UI框架,要注意不同坐标系之间的转换,比较容易弄乱。