AR_EasyAR开发入门(三)—— 基本手势交互

AR手势交互,无非就是拖拽、旋转、缩放等功能

一、使用 EasyTouch 插件实现

Unity 官方AssetsStore上插件 5版本:

  • 插件链接:https://pan.baidu.com/s/1gPdbxD5u5a9OahAfR_U3FQ 提取码:6fbs

1、手势操作

  • 旋转:
    AR_EasyAR开发入门(三)—— 基本手势交互_第1张图片AR_EasyAR开发入门(三)—— 基本手势交互_第2张图片
  • 缩放
    AR_EasyAR开发入门(三)—— 基本手势交互_第3张图片

2、虚拟摇杆 Joystick

  • EasyTouch 插件中 EasyTouchControls/Prefab 中有虚拟摇杆的UI预制体,以 FirstPersonController-Simple 为例,只需根据 Tag 绑定要控制的对象即可:
    AR_EasyAR开发入门(三)—— 基本手势交互_第4张图片
  • 个人觉得其实这个Joystick 上下控制前进,左右控制旋转,不怎么好用,而且插件的第一人称和第三人称好像搞反了,不知是不是个人的理解有问题,既然用到这个插件,就顺便学习一下大佬们的成果

二、Unity 原生 API 实现

  • 一、单击、双击
void Update ()
{
    if (Input.touchCount <= 0)
    {
        return;
    }
    #region 单击、双击
    //touchCount:屏幕触点数量
    if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)
    {
        //单击  自旋转
        _isRotate = !_isRotate;

        //双击  销毁
        if (Input.GetTouch(0).tapCount == 2)
        {
            Destroy(gameObject);
        }
    }
    #endregion

    OneTapRotate();
}

private void OneTapRotate()
{
    if (_isRotate)
    {
        transform.Rotate(Vector3.up, Time.deltaTime * 20f);
    }
    else
    {
        transform.Rotate(Vector3.up, Time.deltaTime * 0f);
    }
}
  • 二、划动旋转
void Update()
{
	#region  划动 旋转(方法一)
    if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
    {
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = Input.GetAxis("Mouse Y");

        transform.Rotate(Vector3.up, -mouseY * Time.deltaTime * _rotateSpeed);
        transform.Rotate(Vector3.right, mouseX * Time.deltaTime * _rotateSpeed);
    }
    #endregion
}

#region  鼠标按下时每帧都调用(滑动旋转方法二)
private void OnMouseDrag()
{
    float mouseX = Input.GetAxis("Mouse X");
    float mouseY = Input.GetAxis("Mouse Y");

    transform.Rotate(Vector3.up, -mouseX * Time.deltaTime * _rotateSpeed);
    transform.Rotate(Vector3.right, -mouseY * Time.deltaTime * _rotateSpeed);
}
#endregion
  • 三、双手缩放
    原理:计算两手指移动前后两指之间的距离
public class AR_Scale : MonoBehaviour
{
    public float scaleValue = 0.025f;   //缩放值
    private float _scaleFactor;         //缩放系数
    private Vector2 _oldPoint1;         //目标点1
    private Vector2 _oldPoint2;         //目标点2

    private void Start()
    {
        _scaleFactor = 1 + scaleValue;
    }

    void Update () {

        #region  双手缩放
        //使用 Input.touchCount 需要打包到Android才能测试
        if (Input.touchCount == 2)
        {
            if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
            {
                Vector2 _tempPoint1 = Input.GetTouch(0).position;
                Vector2 _tempPoint2 = Input.GetTouch(1).position;
                float newScale = transform.localScale.x;

                //计算缩放值
                if (IsEnlarge(_oldPoint1, _oldPoint2, _tempPoint1, _tempPoint2))
                {
                    newScale *= _scaleFactor;       //放大  
                }
                else
                {
                    newScale /= _scaleFactor;       //缩小
                }

                //所防止赋值给模型
                if (newScale >= 0.05f)
                {
                    transform.localScale = Vector3.one * newScale;
                }

                _oldPoint1 = _tempPoint1;
                _oldPoint2 = _tempPoint2;
            }
        }
        #endregion
    }

    /// 
    /// 判断手势缩小 or 放大
    /// 
    /// 
    private bool IsEnlarge(Vector2 oldPoint1, Vector2 oldPoint2, Vector2 newPoint1, Vector2 newPoint2)
    {
        Vector2 oldDistance = oldPoint1 - oldPoint2;
        Vector2 newDistance = newPoint1 - newPoint2;

        if (newDistance.magnitude > oldDistance.magnitude)
        {
            //放大
            return true;
        }
        else
        {
            //缩小
            return false;
        }
    }
}

/// 
/// 双指缩放
/// 
private void TwoTouchScale()
{
    if (Input.touchCount > 1)
    {
        if (Input.GetTouch(1).phase == TouchPhase.Began)
        {
            delayTime = 0;
            isTwoTouch = true;

            //初始双指间距
            firstTouch = Input.GetTouch(0).position;
            secondTouch = Input.GetTouch(1).position;

            lastDistance = Vector2.Distance(firstTouch, secondTouch);
        }

        if (isTwoTouch)
        {
            //当前双指间距
            firstTouch = Input.GetTouch(0).position;
            secondTouch = Input.GetTouch(1).position;
            curDistance = Vector2.Distance(firstTouch, secondTouch);

            //获取当前地图缩放值
            Vector3 curMapScale = transform.localScale;

            //计算缩放偏移量
            float scaleValue = (curDistance - lastDistance) / 100 * 0.5f;
            Vector3 changeVector = new Vector3(scaleValue, scaleValue, 0);

            curMapScale += changeVector;

            curMapScale.x = Mathf.Clamp(curMapScale.x, 1f, 5f);
            curMapScale.y = Mathf.Clamp(curMapScale.y, 1f, 5f);
            transform.localScale = curMapScale;

            lastDistance = curDistance;
        }

        if (Input.GetTouch(1).phase == TouchPhase.Ended)
        {
            isTwoTouch = false;
            firstTouch = Vector2.zero;
            secondTouch = Vector2.zero;
        }
    }
}
  • 四、拖拽移动
public class AR_Drag : MonoBehaviour
{
    private Vector3 _mouseScreenPos;    //鼠标屏幕坐标
    private Vector3 _mouseWorldPos;     //鼠标世界坐标
    private Vector3 _targetScreenPos;   //物体屏幕坐标
    private Vector3 _offset;            //偏移量

    /// 
    /// 鼠标按下时每帧都调用
    /// 
    /// 
    //private IEnumerator OnMouseDown(){}
    private IEnumerator OnMouseDrag()
    {
        #region   拖拽  移动
        //物体世界坐标转到屏幕坐标
        _targetScreenPos = Camera.main.WorldToScreenPoint(transform.position);

        //鼠标屏幕坐标(Z轴为物体屏幕坐标)
        _mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _targetScreenPos.z);

        //鼠标的屏幕坐标只有X和Y,Z为0所以赋予物体的屏幕Z轴坐标
        //Debug.Log("测试" + Input.mousePosition.z + "结果" + _mouseWorldPos.z);

        //计算鼠标和物体之间的世界空间偏移量
        _offset = transform.position - Camera.main.ScreenToWorldPoint(_mouseScreenPos);

        //鼠标左键按下
        while (Input.GetMouseButton(0))
        {
            //获取鼠标此时的屏幕坐标
            _mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _targetScreenPos.z);

            //计算鼠标此时的世界坐标
            _mouseWorldPos = Camera.main.ScreenToWorldPoint(_mouseScreenPos);

            //更新物体的位置
            transform.position = _mouseWorldPos + _offset;

            yield return new WaitForFixedUpdate();
        }
        #endregion
    }
}

你可能感兴趣的:(AR)