一. Unity实现虚拟摇杆及屏幕自适应功能

一. Unity实现虚拟摇杆及屏幕自适应功能一般虚拟摇杆的组成都是由轮盘和遥感的点组成 轮盘控制位移 限制在某个区域内 而点则是控制旋转 限制在轮盘内 因此需要用到的是 Unity 自带的 UI 事件 因此创建一个名为 UIEventListe 的

大家好,欢迎来到IT知识分享网。

手游里面很多类型的游戏都需要用到遥感功能,例如王者荣耀,和平精英等,之前的摇杆功能都是用类似于Easy Touch的插件进行开发的,今天不借助任何插件来实现虚拟摇杆的功能。

在这里插入图片描述

一般虚拟摇杆的组成都是由轮盘和遥感的点组成,轮盘控制位移,限制在某个区域内,而点则是控制旋转,限制在轮盘内,因此需要用到的是Unity自带的UI事件,因此创建一个名为UIEventListener的类,去实现IPointerDownHandler,IPointerUpHandler,IDragHandler方法,通过事件监听回调来处理。

using UnityEngine; using UnityEngine.EventSystems; namespace CS { 
    [AddComponentMenu("UI/UIEventListener")] public class UIEventListener : MonoBehaviour,IPointerDownHandler,IPointerUpHandler,IDragHandler { 
    public Action<PointerEventData> OnDownEvent; public Action<PointerEventData> OnUpEvent; public Action<PointerEventData> OnDargEvent; public static UIEventListener Get(GameObject go) { 
    UIEventListener listener = null; if (go != null) { 
    listener = go.GetComponent<UIEventListener>(); if (listener == null) { 
    listener = go.AddComponent<UIEventListener>(); } } return listener; } public void OnPointerDown(PointerEventData eventData) { 
    OnDownEvent?.Invoke(eventData); } public void OnPointerUp(PointerEventData eventData) { 
    OnUpEvent?.Invoke(eventData); } public void OnDrag(PointerEventData eventData) { 
    OnDargEvent?.Invoke(eventData); } } 

下面贴出完整代码,接下来对虚拟摇杆进行处理,监听这三个事件,其中mTouchMaxDir是虚拟摇杆的点距离轮盘中心的最大距离,也就是你遥感点能拉到多远,而由于在不同分辨率下,这个距离其实并非是固定的,因此就和我上一篇Unity实现经验条动态自适应一样,以实际画布的高比屏幕的高得到当前高的比值,然后乘以固定的最远拉伸距离,就能得到当前分辨率下的自适应拉伸距离。为了限制轮盘的位置,因此需要设置一张矩形的底图,将其aplha设置为0,表示轮盘可移动的范围。

在这里插入图片描述

在我们按下的时候,记录开始按下的位置,已经显示遥感点,将按下的位置赋值给轮盘,而抬起的时候,隐藏摇杆点,重置轮盘的位置,这个都很简单,然后我们在OnDrag拖拽事件中,首先我们得到遥感的方法,通过遥感的最终位置-开始位置 = 方向,由于我们遥感点是需要限定在轮盘内的,因此需要用距离来判断,因此通过方向的magnitude得到当前遥感点的距离,来判断是否超过我们之前设定的最大遥感距离,如果超出了就用 Vector2.ClampMagnitude(dir, mTouchMaxDir) API限制在这个mTouchMaxDir最大距离内,然后我们遥感点的位置就是我们开始位置+限制在最大距离的Dir ,如果没有超出就直接等于我们Drag传出的位置即可,这里的位置需要注意,都是postion,也就是世界坐标的位置,因为我们UIEvent事件中传出的eventData中的Position是世界坐标位置

 public class UI_MainCityPanel : View<UI_MainCityPanel, MainCityScene> { 
    private Image mDirBgImg; private Image mDirPointImg; private Vector2 mStartPos = Vector2.zero; private Vector2 mDefaultPos = Vector2.zero; private float mTouchMaxDir; public override void IAwake() { 
    base.IAwake(); InitComponment(); OnTouchEvent(); } private void InitComponment() { 
    mPowerImg = transform.Index<Image>("F_PowerImg"); mDirBgImg= transform.Index<Image>("F_DirBg"); } private void OnTouchEvent() { 
    mTouchMaxDir = Screen.height * 1.0f / Consts.ScreenHeight * Consts.TouchPointMaxLen; mDirPointImg.SetActiveState(false); mUIEvtListener = UIEventListener.Get(gameObject); mUIEvtListener.OnDownEvent += (eventData => { 
    mStartPos = eventData.position; mDirPointImg.SetActiveState(true); mDirBgImg.transform.position = eventData.position; }); mUIEvtListener.OnUpEvent += (eventData => { 
    mDirPointImg.transform.localPosition = mDefaultPos; mDirPointImg.SetActiveState(false); mDirBgImg.transform.localPosition = mDefaultPos; }); mUIEvtListener.OnDargEvent += (eventData => { 
    Vector2 dir = eventData.position - mStartPos; float length = dir.magnitude; if (length > mTouchMaxDir) { 
    Vector2 clampDir = Vector2.ClampMagnitude(dir, mTouchMaxDir); mDirPointImg.transform.position = mStartPos + clampDir; } else { 
    mDirPointImg.transform.position = eventData.position; } }); } } 

下面看演示效果

在这里插入图片描述

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/125890.html

(0)
上一篇 2025-09-23 15:15
下一篇 2025-09-23 15:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信