欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity实现简单虚拟摇杆

程序员文章站 2023-10-31 09:29:58
最近一直在倒腾用ugui做虚拟摇杆,网上普遍的的做法就是使用以下的代码,但是这个有些注意事项,第一点就是canvas的render mode必须是screen space overlay,第二点就是挂...

最近一直在倒腾用ugui做虚拟摇杆,网上普遍的的做法就是使用以下的代码,但是这个有些注意事项,第一点就是canvas的render mode必须是screen space overlay,第二点就是挂载这个脚本的锚点的x,y必须是0.5,如图下:

Unity实现简单虚拟摇杆

using unityengine;
using unityengine.eventsystems;
public class joystick : monobehaviour, idraghandler, ienddraghandler
{
 transform point;
 vector3 startpos;//开始位置
 vector3 dir;//方向
 float radius = 0;//需要移动的半径
 void start()
 {
 point = transform.getchild(0);
 radius = (transform as recttransform).sizedelta.x * 0.5f;
 startpos = point.position;
 }
 public void ondrag(pointereventdata eventdata)
 {
 point.position = eventdata.position;
 dir = (point.position - startpos).normalized;
 if (vector3.sqrmagnitude(point.position - startpos) > radius * radius)
 point.position = startpos + dir * radius;
 }
 public void onenddrag(pointereventdata eventdata)
 {
 point.localposition = vector3.zero;
 }
}

如果canvas的render mode是screen space camera,这样的话上面的代码是不能满足要求的,花了一点时间才发现是这个原因,导致上面的代码不适用的,最后把代码重写了一下,终于可以成功了!

public class joystick : monobehaviour, idragevent
{
 private canvas canvas;
 private recttransform recttransform;//坐标
 private static quaternion amendangle;
 private static float mradius = 0,v=0, h=0;
 private static transform point;
 private static vector3 initpos;
 private static vector2 startpos;
 private void start()
 {
 point = transform.getchild(0);
 canvas = gameobject.find("uiroot").getcomponent<canvas>();
 recttransform = transform as recttransform; //也可以写成this.getcomponent<recttransform>(),但是不建议;
 mradius = (transform as recttransform).sizedelta.x * 0.5f;
 initpos = point.localposition;
 h = v = 0;
 }
 
 public void onbegindrag(pointereventdata eventdata)
 {
 recttransformutility.screenpointtolocalpointinrectangle(recttransform, eventdata.position, canvas.worldcamera, out startpos);
 startpos = eventdata.position - startpos;
 h = v = 0; 
 }
 
 public void ondrag(pointereventdata eventdata)
 {
 point.localposition = eventdata.position - startpos;
 vector3 dir = (point.localposition - initpos).normalized;
 v = dir.normalized.x; h = dir.normalized.y;
 if (vector3.sqrmagnitude(point.localposition - initpos) > mradius * mradius)
 point.localposition = initpos + dir * mradius;
 }
 
 public void onenddrag(pointereventdata eventdata)
 {
 point.localposition = vector3.zero;
 h = v = 0; 
 }
}

recttransformutility.screenpointtolocalpointinrectangle(recttransform, eventdata.position, canvas.worldcamera, out startpos)这个的startpos返回的是点击屏幕的坐标,recttransform是这个脚本挂载物体上的recttransform的组件,然后减去eventdata.position就知道坐标的偏移值了,看一下代码应该都可以了解意思,这里就不过多的解释了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。