赞
踩
嘿欢迎点开小熊的博客,让我们继续前行吧!
40行实现主要内容。
*提供工程样例,在本文最后。
Canvas:是整个屏幕的图层,其中这个Canvas会设置“按照屏幕大小缩放”。*
JoyBac:是一张图片,一个背景图。(使用PS作图)
*在后文还会提及。
————
请将这三个物体对应的拖拽到后文的代码Inspection中以此初始化。(您可以看完后面的再来看这里)
而Handle就是我们传说的摇杆,也是一张图片。
Handle:
注意:真实的图片中是png格式,周围或圈内是透明的,这里为了演示将图片染色。
判断用户的点击,是不是在上面的”JoyBac“里面。如果用户在这个区域进行点击,那么就将图片的Handle移动到那个位置。以此好像是,我们拖动了摇杆的感觉一样。
当我们停止触控的话,那么就立马将Handle设置为原点。
这里面还需要注意一个坑点,那就是,小心Canvas的缩放。这会导致在拖动的时候,感觉Handle好像不跟手一样。
您应该掌握的知识有EventSystems(不是事件驱动系统,在这里指的是UGUI的那一套EventSystems)。
同时您也应该明白“将脚本拖拽到物体上面”的这个行为,这里的行为是使得这个物体拥有了脚本所能处理到的能力。也就是,脚本的this.gameObject(注意,这里的gameObject是小写代表一个变量,而大写的GameObject则代表着一个类。)指的是被拖拽的这个物体。
好的,说完了前面的这些,我们来看看代码。其实很简单。
将代码放在JoyBac上面*(正如我们前面所述,这些接口需要在被点击的物体生效)
首先,由于我们需要处理一些触摸操作,比如按下,抬起,拖拽,所以我们需要集成这些接口。
IPointerDownHandler, IDragHandler, IPointerUpHandler
然后我们需要实现这些接口,当我们“按下”的时候,之间执行我们“拖拽”时候执行的代码:
(注意,为什么是OnPointerDown这些是接口要求的东西,您可以复习一下您手头的计算机教材。)
public void OnPointerDown(PointerEventData eventData) {
OnDrag(eventData);
}
当我们在移动的时候:
public void OnDrag(PointerEventData eventData) {
Vector2 to = ((Vector2)eventData.position - (Vector2)background.position) / canvas.scaleFactor;
if (to.magnitude <= radious)
handle.anchoredPosition = to;
else {
Vector2 to2;
to2 = (Vector2)to / (float)(to.magnitude / radious);
handle.anchoredPosition = to2;
}
}
这里就是核心的部分了。
to代表着Handle的中心点(anchoredPosition)在哪里。
而eventData是EventSystems返回给我们的事件数据,其中包含了触摸的位置,是否在托转dragged等参数。
background是我们的背景图片。
canvas.scaleFactor是图层的缩放尺度,请务必考虑在内,因为这会使得滑动屏幕的时候,Handle不跟手指。您可以移步至UGUI教程学习。
其实就一个to就是所有的核心内容啦!
通过to,我们就能知道相对于background中心点的偏移了。
然后,if (to.magnitude <= radious)
一个逻辑分支判断,判断我们的触摸点是否已经被拖拽到了别的地方去了(超出了bac)
如果超出去了,那么就通过简单的数学运算:to2 = (Vector2)to / (float)(to.magnitude / radious);
将to的长度改回最长的限制。
然后最后更正Handle的位置handle.anchoredPosition = to2;
当我们抬起手指的时候:
public void OnPointerUp(PointerEventData eventData) {
handle.anchoredPosition = Vector2.zero;
}
将Handle更正,至此,您的简单代码已经全部实现完成啦!
那么,我们该怎么去,判断方向呢。
其实根据to向量就可以了,这部分留给读者思考。
最近在写一款小游戏,只需要上下左右四个维度。
所以我的判断方法如下:
通过Handle靠近哪个点,那么就是用户想往哪个方向移动。
完整代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class JoyStickControl: MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler { enum Mode { None, Up, Down, Left, Right }; Mode mode; public Vector2 input = Vector2.zero; public RectTransform background = null; public RectTransform handle = null; public Canvas canvas; float radious; Vector2 up, down, left, right; void Start() { mode = Mode.None; radious = background.rect.width / 2.0f; up = new Vector2(0, radious); down = new Vector2(0, -radious); left = new Vector2(-radious, 0); right = new Vector2(radious, 0); } void Update() { MessageSend(); } public void OnDrag(PointerEventData eventData) { Vector2 to = ((Vector2)eventData.position - (Vector2)background.position) / canvas.scaleFactor; if (to.magnitude <= radious) handle.anchoredPosition = to; else { Vector2 to2; to2 = (Vector2)to / (float)(to.magnitude / radious); handle.anchoredPosition = to2; CalcDis(); } } void MessageSend() { switch (mode) { case Mode.None: break; case Mode.Up: break; case Mode.Left: break; case Mode.Down: break; } } void CalcDis() { float dis = 0f; if (Vector2.Distance(up, handle.anchoredPosition) < dis || dis == 0) { dis = Vector2.Distance(up, handle.anchoredPosition); mode = Mode.Up; } if (Vector2.Distance(down, handle.anchoredPosition) < dis) { dis = Vector2.Distance(down, handle.anchoredPosition); mode = Mode.Down; } if (Vector2.Distance(left, handle.anchoredPosition) < dis) { dis = Vector2.Distance(left, handle.anchoredPosition); mode = Mode.Left; } if (Vector2.Distance(right, handle.anchoredPosition) < dis) { dis = Vector2.Distance(right, handle.anchoredPosition); mode = Mode.Right; } } void EventSender(int mes) { } public void OnPointerDown(PointerEventData eventData) { OnDrag(eventData); } public void OnPointerUp(PointerEventData eventData) { handle.anchoredPosition = Vector2.zero; mode = Mode.None; } void OnGUI() { //The Label shows the current Rect settings on the screen GUI.Label(new Rect(20, 20, 150, 80), "Mode : " + mode); } }
https://download.csdn.net/download/qq_34013247/81949365
免积分。
参考资料:
【推荐阅读,有实现其他效果的摇杆】
https://zhuanlan.zhihu.com/p/266077243
【亮点之间距离计算】
https://blog.csdn.net/moonlightpeng/article/details/89949615
本熊写了一个小游戏,正在进行手机端适配,到时候请给位CSDN友来捧场哦!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。