一般地,虚拟摇杆是放在UI层的。
所以先在Canvas建立一个空对象(这里被命名成MoveController),再在空对象里面放一个作为摇杆图片的Image。
然后通过覆盖重写UnityEngine.UI的ScrollRect成一个新的脚本,加载到Image对象上。
脚本代码:
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using UnityEngine.UI; 5 using UnityEngine.EventSystems; 6 7 public class MoveController : ScrollRect{ 8 float mMaxRadius; 9 public bool ifmove; 10 public Vector2 moveDelta = new Vector2(); 11 12 protected override void Start() 13 { 14 base.Start(); 15 //计算摇杆块的半径 = 摇杆的宽的一半 16 mMaxRadius = content.sizeDelta.x * 0.5f; 17 } 18 19 //拖动时 20 public override void OnDrag(UnityEngine.EventSystems.PointerEventData eventData) 21 { 22 base.OnDrag(eventData); 23 24 var contentPostion = this.content.anchoredPosition; 25 //如果超出摇杆范围 26 if (contentPostion.magnitude > mMaxRadius) 27 { 28 contentPostion = contentPostion.normalized * mMaxRadius; 29 SetContentAnchoredPosition(contentPostion); 30 } 31 //获取拖动的delta值 (-132 moveDelta.x = contentPostion.x/ mMaxRadius; 33 moveDelta.y = contentPostion.y/ mMaxRadius; 34 //表示正在移动摇杆 35 ifmove = true; 36 } 37 38 public void Update() 39 { 40 //,,,,,,, 41 //可根据moveDelta值做某些事情 42 } 43 44 //当结束拖动时 45 public override void OnEndDrag(PointerEventData eventData) 46 { 47 base.OnEndDrag(eventData); 48 49 moveDelta.x = 0; 50 moveDelta.y = 0; 51 //表示停止移动摇杆 52 ifmove = false; 53 //重置位置 54 SetContentAnchoredPosition(Vector3.zero); 55 } 56 }
在Unity面板调好脚本属性(如下图示例),然后将Image拖到脚本的Content属性里
我们可能还需要额外的公开变量放在MoveController里面,以便在Unity面板调用调试。
但是由于MoveController脚本是覆盖于ScrollRect的,无论你在MoveController脚本里写多少公开的成员变量。
在Unity的面板显示的永远是ScrollView的面板。
这时候可以额外写多一个辅助脚本,间接访问MoveController,从而让公开变量可以在面板调试。
(如下图的MoveController_CallBack示例)