UGUI 实现屏幕方向输入 About

在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;
  }
}

Author:superzhan
Blog: http://www.superzhan.cn
Github: https://github.com/superzhan