虽说有个叫EasyTouch的插件,但还是尽量少用插件吧,不然版本更新维护一定会是个坑(当然对于我这种菜鸡还谈不上这种东西);
不过,既然在做这项功能的之前稍微有点想法,感觉不算特别难,感觉也用不上啥EasyTouch,所以何不自己实现下呢~

这里我要做的轴不是固定在左下方的方向按键,我需要他随着我的手指点击位置自行显示在点击手指下方,拿开时轴按键消失;

note:在移动端,触摸点相当于鼠标左键位置,如果需要多点触控,则参照Input.GetTouch

所以,思路很简单,在触摸屏幕时,激活做好的虚拟轴UI,显示在触摸位置( Input.mousePosition),但是输出的点是世界坐标,因此需要转换为UI的2D坐标,如下图方法:编辑有点问题,可能图片看不清,请放大浏览器

codesys 虚拟单轴_codesys 虚拟单轴


参数1:锚点Object,因为UI的坐标(AnchoredPosition)是相对锚点的坐标,因此虚拟键的父物体是画布,所以这里设置画布为参照物体;

参数2:即为点击屏幕输入的位置;

参数3:需要转换到哪个相机想关联的控件坐标,虽然canvas下当前版本看不见相机组件,但其实是有的,我们当然是要转换到UI相机下的坐标罗~

参数4:输出坐标,既然是转换到平面UI空间下,这里就需要创建一个二维参数

codesys 虚拟单轴_codesys 虚拟单轴_02

所以如上图的按钮,当触摸时,虚拟按键会显示在手指按下位置;
在没有松开手时滑动手指,其背景不动,中间的非透明实心圆会跟随手指移动,当然也需要上述函数转换,当然此时的相对标点参照物也不是画布了,变成虚拟键背景这个父级物体;

另外,会设定一个距离,虚拟轴键离开背景圈时不再跟随手指向外移动,而是只会转动角度;
以及当在进行其他按钮操作时,不应该显示该虚拟键,参照EventSystem.current.IsPointerOverGameObject();运用这个UGUI特有的事件系统函数,可以判定当前触摸的位置是否有其他UI;

具体实例见下面源码:

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class Touch : MonoBehaviour
{
    public Canvas canvas;
    public RectTransform uiButtonBG; //按键背景
    public RectTransform uiButton;//按键图标

    Vector2 AnchoredPosition = Vector2.zero;
    Vector2 touchAxis = Vector2.zero;
    public Vector2 TouchAxis { get { return touchAxis; } }

    void Start ()
    {

    }

    void Update()
    {
        if (Input.GetMouseButton(0))
        {

            RectTransformUtility.ScreenPointToLocalPointInRectangle(uiButtonBG, Input.mousePosition, canvas.worldCamera, out AnchoredPosition);
            if ((Input.mousePosition - uiButtonBG.position).magnitude <= 55)
            {
                uiButton.anchoredPosition = AnchoredPosition;
            }
            else
            {
                uiButton.anchoredPosition = (Input.mousePosition - uiButtonBG.position).normalized * 55;
            }

            touchAxis = new Vector2(uiButton.anchoredPosition.x / 55f, uiButton.anchoredPosition.y / 55f);
            //print(touchAxis);
        }
    }

   public void ActiveTouchAxis()//激活触摸轴按钮(Uguimanager调用)
    {
        if (EventSystem.current.IsPointerOverGameObject()) //当点击其他按钮时不执行
        {
        }
        else
        {
            Vector2 tempAnchoredPosition = Vector2.zero; 
            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, canvas.worldCamera, out tempAnchoredPosition);
            uiButtonBG.anchoredPosition = tempAnchoredPosition;
            uiButtonBG.gameObject.SetActive(true);
        }

    }
    public void InActiveTouchAxis()  //禁用触摸轴按钮
    {
        InitTouchAxis();
        uiButtonBG.gameObject.SetActive(false);
    }

    void InitTouchAxis()
    {
        uiButton.anchoredPosition = Vector2.zero;
        touchAxis = Vector3.zero;
    }
}