johnsoncodehk 发表于 2022-12-16 11:35

Unity3d轮子篇(1):48行代码撸一个商业级的JoyStick

本系列基于:BDFramework 、Unity3D 2018.4.0
BDFramework:Simple! Easy! Beautiful! This is a powerful Unity3d game workflow!
框架地址:
GayHub:yimengfan/BDFramework.Core,
码云 :yimengfan/BDFramework.Core,欢迎赏星。
第九艺术 、第十艺术讨论群 : 606667651
   我们是造轮子小分队,结果还写几篇造轮子文章。前两天我们游戏需要一个joystick效果,然后有小伙伴跟我推荐用easy touch,但是我看了下,笨重的一逼,所以就花半小时自己撸了一个,现在分享给大家看看:
代码已经提交在:
yimengfan/BDFramework.UniReact
先看下成品:


再看下代码:


下面我简单说一下整个实现流程:
主要知识点: Unity EventSystem、坐标系转换、向量归一化、向量乘法概念
1.准备资源
我们先建立好2张图的关系


因为Joystick 往往都在左下角,所以我们 把个根节点的对齐方式和锚点都设置到左下角


2.准备好所需要的计算数据


首先是2个节点,以及,我们Center点所需要的半径R,这个我们公开了,可以在外面设置
3.接入事件系统:
此时我们需要IPointerDownHandler, IPointerUpHandler, IDragHandler 这三个接口,
并且实现,unity的新事件系统就会把交互事件的数据传过来。
顺理成章的,我们就会想到Down和Drag直接把center Position设置过去。
然后UP的时候归零~完美


然而现实是残酷的~~


为啥有个偏差?
enmmm,我忘了说,实际上,这个eventdata 给过来的是ViewPoint,不是UI坐标系下的Point。
4.坐标系转换:
实际上,坐标系转换,学过GL的朋友都知道,我们就是乘一个转换矩阵就好了。
但是UI下比较复杂,有各种父子节点关系,子节点的坐标 ,是相对父节点的~
那么怎么办?我们利用现成的接口其实就能很好的做到~




然后再修改我们的事件接口函数~


再来看看效果~


我们发现虽然center的位置跟着鼠标移动了,但是有个相对位移。
5.算出准确的跟随坐标
我们想象发生了啥 ?
我们把bg的锚点在左下角,center在中心.center是以bg为父节点,然而我们算出的ui坐标,是以bg左下角为0,0的。所以这个差,其实就是bg.w /2 , bg.h/2;三行代码敬上:






再来看看 效果如何:


Nice!!
于是我们又成功了一大步~
但是 ,我们怎么约束Center的运动范围呢?
6.算出活动范围
事实上,经过上面一步,我们做过一个简单的坐标系转换。bg的左下角,到center的中心。
那么熟悉向量的朋友,就知道,我们怎么判断有没有超过圆外~
只要求一下pos的模跟R比较大小即可:


那么超出的范围怎么约束在圆边上?
这里就要用到归一化了,归一化后 乘以 R 即可:


看下效果:


完美,只要只差最后一步了~
7.加入对外接口:


这一步我就不赘述了.
那就结束我们的战斗吧,希望大家撸码开心~~

FeastSC 发表于 2022-12-16 11:44

非商业级的要多少行代码

Doris232 发表于 2022-12-16 11:49

这个不知道,老事件系统做这个比较蛋疼

rustum 发表于 2022-12-16 11:52

刚学unity时用的方法,后来果断弃了,效率垃圾,easytouch的实现方法才是正确的,我后来也是在easytouch方法上精简改进,效率提升很多

闲鱼技术01 发表于 2022-12-16 11:59

比方说,哪里的效率辣鸡?

johnsoncodehk 发表于 2022-12-16 12:01

那玩意用射线检测的,而且存在不断UI适应计算,效率很低,用unity自带的分析工具,看cpu消耗,多触摸,疯狂移动的时候,iphone6p手机cpu损耗顶峰能达到30%,而easytouch损耗稳定几%,一般只有2~3%蛮多了,主要就是那个EventSystem,消耗很大,一般动作类正常游戏情况,那玩意不该出现,easytouch内部就是,根本不是用UI实现的

IT圈老男孩1 发表于 2022-12-16 12:07

知其然,得知其所以然啊~
eventsystem 主要是下面两个接口消耗过大…
GraphicRaycaster.get_eventCamera();
Graphic.get_canvasRenderer();      
你们整个项目没对这个优化过?

Baste 发表于 2022-12-16 12:11

并没有,因为我本身unity也是新学的,经验不足,用在菜单这块性能本身也不是大问题,没去深入研究 ,然后看了下这个优化及别人文章里说的优化结果,依旧不可能达到easytouch设计方式的性能级别,easytouch从Input开始,后面也就一些数据计算,然后就输出结果,没其他复杂东西。

pc8888888 发表于 2022-12-16 12:20

另外我去看了下,可能unity版本升级了,你说的这两个已经不存在了,性能确实好了很多,没那么夸张,但性能依旧不敌easytouch这种方式
页: [1]
查看完整版本: Unity3d轮子篇(1):48行代码撸一个商业级的JoyStick