最近看到了一个很新颖的摇杆,就是按下后,会出现在按下的位置,并且拖着走的时候,到一定距离整个摇杆也会跟着走,于是自己测试做了一下这种摇杆
首先,先说一下我的摇杆预设体结构
代码挂在哪里都无所谓,关键是需要知道我写的publice出去的GameObject对应的是哪些,用拖动或者代码查找都可以
到时候代码中会出现这些
public GameObject rockerOnOff;
public GameObject rockerStick;
public GameObject rockerFather;
public GameObject rockerControlGo;
RockerPosition其实是一张图片,这张图片透明度被我设置成了0,所以看不见,我为了将摇杆激活时候范围控制在这个图片里面
Rocker这个其实才是摇杆,通常状态下将它失活的,但是只要点击在RockerPosition图片范围内,就会被激活,所以rockerOnOff是场景中的Rocker
rockerStick是摇杆移动的那个杆,添加到 public 出来的rockerStick
rockerFather这个public出来的,添加的是场景中的RockerPosition,因为后面有个移动定位需要这个物体
好了,接下来就是代码
using UnityEngine; using UnityEngine.EventSystems; public class BarGroundMove : MonoBehaviour,IPointerDownHandler, IPointerUpHandler, IDragHandler { public GameObject rockerOnOff; //控制摇杆开关 public GameObject rockerStick; //摇杆的杆 public GameObject rockerFather; //摇杆父对象 public GameObject rockerControlGo; //摇杆需要控制的对象 float radius = 50; //摇杆的杆,和摇杆底图的距离 Vector2 dirV2; Vector3 dirV3; public void OnPointerDown(PointerEventData eventData) //点击事件的函数 IPointerDownHandler接口生成 { rockerOnOff.SetActive(true); //点击时候,将摇杆激活 Vector2 localPos; //这个Api:public static bool ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector2 localPoint); //rockerFather.transform as RectTransform,rockerFather为父类的本地坐标 //eventData.position这个事件触发的坐标点 //eventData.pressEventCamera这个事件触发时候的相机 //out localPos 这个参数就是相对于 RectTransform rect的Vector2坐标 RectTransformUtility.ScreenPointToLocalPointInRectangle( rockerFather.transform as RectTransform, eventData.position, eventData.pressEventCamera, out localPos ); rockerOnOff.transform.localPosition = localPos; //激活摇杆的位置,就是相对rockerFather的位置 } public void OnDrag(PointerEventData eventData) //拖拽事件的函数 IDragHandler 接口生成 { Vector2 localPos; //相对于摇杆的拖拽位置 RectTransformUtility.ScreenPointToLocalPointInRectangle( rockerOnOff.transform as RectTransform, eventData.position, eventData.pressEventCamera, out localPos ); Vector2 groundPos; //相对于摇杆父类的拖拽位置 RectTransformUtility.ScreenPointToLocalPointInRectangle( rockerFather.transform as RectTransform, eventData.position, eventData.pressEventCamera, out groundPos ); //得到杆相对摇杆的向量,写全的话是rockerOnOff.transform.localPositio - Vecter2.zero(对于杆,相当于父类摇杆本地坐标是(0,0)) Vector2 grV2 = rockerOnOff.transform.localPosition; dirV2 = localPos.normalized; //这里是记录拖动得到的单位向量,方便下面移动计算计算 if (localPos.magnitude > radius) //当长度大于半径的时候,则整个摇杆会跟着杆移动 { rockerOnOff.transform.localPosition = (grV2 - groundPos).normalized * radius + groundPos; rockerStick.transform.localPosition = localPos.normalized * radius; } else { rockerStick.transform.localPosition = localPos; } } public void OnPointerUp(PointerEventData eventData) //松开事件的函数 IPointerUpHandler 接口生成 { rockerStick.transform.localPosition = Vector3.zero; dirV2 = Vector2.zero; //这里是抬起时候,将单位向量置0,这样才能使得下面物体也不会根据向量进行移动 rockerOnOff.SetActive(false); } void Start() { } void Update() { dirV3.x = dirV2.x; dirV3.z = dirV2.y; dirV3.y = 0; rockerControlGo.transform.Translate(new Vector3(0, 0, dirV3.magnitude*Time.deltaTime*2.5f)); if (dirV3 != Vector3.zero) { rockerControlGo.transform.rotation = Quaternion.Lerp(rockerControlGo.transform.rotation, Quaternion.LookRotation(dirV3),0.05f); } } }