在Unity中实现屏幕输入方向(例如摇杆),一般会用到 Input 类来获取触摸点的屏幕位置,然后根据触摸点的位置变动,计算出输入方向。 但是会存在一个问题,如果游戏界面中有按钮,对按钮的点击事件,也会影响到Input 的触摸点输入,我们希望能避免这个问题。
一个比较好的实现方案就是,不使用Input,而是使用UGUI的触摸事件。
这个方案比较简单,新建一个DirectionInput 继承MonoBehaviour,并且继承IPointerDownHandler,IPointerUpHandler,IDragHandler 三个接口。然后在代码中实现 OnPointerDown,OnDrag,OnPointerUp三个方法。
具体代码如下,可以在其他模块中,读取该对象的direction字段来获取方向。
using UnityEngine; using UnityEngine.EventSystems; /// <summary> /// 玩家屏幕方向输入 /// </summary> public class DirectionInput : MonoBehaviour ,IPointerDownHandler,IPointerUpHandler,IDragHandler { private const float MIN_MOVE_DISTANCE = 30f; public static DirectionInput Instance = null; public bool enableTouch = true; public bool isTouching = false; public Vector3 direction=Vector3.zero; private Vector2 touchBeginPos, touchEndPos; private void Awake() { Instance = this; Init(); } public void Init() { Input.multiTouchEnabled = false; } private bool IsCanTouch() { return enableTouch; } void Update() { if(!enableTouch){ return; } #if UNITY_EDITOR KeyBoardInput(); #endif } /// <summary> /// 获取键盘方向输入 /// </summary> private void KeyBoardInput(){ #if UNITY_EDITOR if(isTouching== true) { return; } Vector3 dir = Vector3.zero; bool keyTouch = false; if(Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)){ dir+= Vector3.forward; keyTouch = true; } if(Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)){ dir+= Vector3.left; keyTouch = true; } if(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)){ dir+= Vector3.right; keyTouch = true; } if(Input.GetKey(KeyCode.S)|| Input.GetKey(KeyCode.DownArrow) ){ dir+= Vector3.back; keyTouch = true; } direction = dir; #endif } public void OnPointerDown(PointerEventData data){ isTouching = true; touchBeginPos = (data.position); } public void OnDrag (PointerEventData eventData) { if (!isTouching) return; touchEndPos = (eventData.position); Vector2 dir = (touchEndPos - touchBeginPos).normalized; direction.x = dir.x; direction.y=0; direction.z = dir.y; //Debug.Log(touchBeginPos.ToString() +" "+touchEndPos.ToString()+" Dir:"+direction.ToString()); } public void OnPointerUp(PointerEventData data){ isTouching = false; } }