zoukankan      html  css  js  c++  java
  • Unity手机端手势基本操作

    主要有单指移动3D物体、单指旋转3D物体、双指缩放3D物体。

    基类

    using UnityEngine;
    using System.Collections;
    /// <summary>
    /// 手势操作父类,并用于互斥三种手势
    /// </summary>
    public class GestureControl : MonoBehaviour
    {
        //记录手势状态:
        //-1——没有任何手势在操作
        //0——移动手势正在操作
        //1——旋转手势正在操作
        //2——缩放手势正在操作
        public static int status = -1;
        //用于记录触碰物体的时间(区分同为单指时移动与旋转,详见相应代码)
        public static float TouchTime = 0;
     
        protected bool isSelected = false;
     
        //判断是否事先选择到了某物体
        protected void OnMouseDown() {
            isSelected = true;
        }
     
        //手指抬起,记录归零
        protected void OnMouseUp() {
            isSelected = false;
            status = -1;
            TouchTime = 0;
        }
        // Update is called once per frame
         protected void Update()
        {
            if (!isSelected)
            {
                return;
            }
            else if(status == -1)
            {
                InputCheck();
            }
        }
        /// <summary>
        /// 之类相应操作
        /// </summary>
         protected virtual void InputCheck() { }
    }

    单指移动3D物体

    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
    using System;
     
    public class MoveControl : GestureControl
    {  
        protected override void InputCheck()
        {
            //单指移动
            if (Input.touchCount == 1)
            {
                //触碰按住3D物体不动1秒后物体随手指一起移动
                if (Input.GetTouch(0).phase == TouchPhase.Stationary)
                {
                    TouchTime += Time.deltaTime;
                    if (TouchTime > 1)
                    {
                        status = 0;
                    }
                }
                if (status == 0)
                {
                    StartCoroutine(CustomOnMouseDown());
                }
            }
        }
        IEnumerator CustomOnMouseDown()
        {
            //将物体由世界坐标系转化为屏幕坐标系,由vector3 结构体变量ScreenSpace存储,以用来明确屏幕坐标系Z轴的位置
            Vector3 ScreenPoint = Camera.main.WorldToScreenPoint(transform.position);
     
            //由于鼠标的坐标系是二维的,需要转化成三维的世界坐标系;
            Vector3 WorldPostion = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, ScreenPoint.z));
     
            //三维的情况下才能来计算鼠标位置与物体的距离
            Vector3 distance = transform.position - WorldPostion;
     
            //当鼠标左键按下时
            while (Input.GetMouseButton(0))
            {
                //得到现在鼠标的二维坐标系位置
                Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, ScreenPoint.z);
                //将当前鼠标的2维位置转化成三维的位置,再加上鼠标的移动距离
                Vector3 CurPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + distance;
                //CurPosition就是物体应该的移动向量赋给transform的position属性        
                transform.position = CurPosition;
                //鼠标释放前都起作用
                yield return new WaitForFixedUpdate();
            }
        }
    }

    单指旋转3D物体

    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
    using System;
     
    public class RotateControl : GestureControl
    {
     
        protected override void InputCheck()
        {
            #region  单点触发旋转(真实模型旋转)
            if (Input.touchCount == 1)
            {
                //触摸为移动类型
                if (Input.GetTouch(0).phase == TouchPhase.Moved)
                {
                    status = 1;
                    try
                    {
                        StartCoroutine(CustomOnMouseDown());
                    }
                    catch (Exception e)
                    {
                        Debug.Log(e.ToString());
                    }
                }
                
            }
            #endregion
     
            #region   键盘A、D、W、S模拟旋转(真实模型旋转)
            if (Input.GetKeyDown(KeyCode.A))
            {
                transform.Rotate(Vector3.up, 45 * Time.deltaTime, Space.World);
            }
     
            if (Input.GetKeyDown(KeyCode.D))
            {
                transform.Rotate(Vector3.up, -45 * Time.deltaTime, Space.World);
            }
     
            if (Input.GetKeyDown(KeyCode.W))
            {
                transform.Rotate(Vector3.left, 45 * Time.deltaTime, Space.World);
            }
     
            if (Input.GetKeyDown(KeyCode.S))
            {
                transform.Rotate(Vector3.left, -45 * Time.deltaTime, Space.World);
            }
            #endregion
        }
     
        IEnumerator CustomOnMouseDown()
        {
            //当检测到一直触碰时,会不断循环运行
            while (Input.GetMouseButton(0))
            {
                //判断是否点击在UI上
    #if UNITY_ANDROID || UNITY_IPHONE
                if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
    #else
                    if (EventSystem.current.IsPointerOverGameObject())
    #endif
                {
                    Debug.Log("当前点击在UI上");
                }
                else
                {
                    float XX = Input.GetAxis("Mouse X");
                    float YY = Input.GetAxis("Mouse Y");
                    #region
                    //判断左右滑动的距离与上下滑动距离大小
                    if (Mathf.Abs(XX) >= Mathf.Abs(YY))
                    {
                        //单指向左滑动情况
                        if (XX < 0)
                        {
                            transform.Rotate(Vector3.up, 45 * Time.deltaTime, Space.World);
                        }
                        //单指向右滑动情况
                        if (XX > 0)
                        {
                            transform.Rotate(-Vector3.up, 45 * Time.deltaTime, Space.World);
                        }
                    }
                    else
                    {
                        //单指向下滑动情况
                        if (YY < 0)
                        {
                            transform.Rotate(Vector3.left, 45 * Time.deltaTime, Space.World);
                        }
                        //单指向上滑动情况
                        if (YY > 0)
                        {
                            transform.Rotate(-Vector3.left, 45 * Time.deltaTime, Space.World);
                        }
                    }
                    #endregion
                }
                yield return new WaitForFixedUpdate();
            }
        }
    }

    双指缩放3D物体

    using UnityEngine;
    using System.Collections;
     
    public class ZoomControl : GestureControl
    {
        //记录上一次手机触摸位置判断用户是在左放大还是缩小手势  
        private Vector2 oldPosition1;
        private Vector2 oldPosition2;
        //实时大小
        Vector3 RealScale = new Vector3(1f, 1f, 1f);
        //原始大小
        float InitialScale = 0;
        //缩放速度
        public float ScaleSpeed = 0.1f;
        //缩放比例
        public float MaxScale = 2.5f;
        public float MinScale = 0.5f;
     
        void Start()
        {
            //获取物体最原始大小
            InitialScale = this.transform.localScale.x;
        }
     
        protected override void InputCheck()
        {
            #region 多点触摸缩放(真实模型缩放)
            
            if (Input.touchCount > 1)
            {
                status = 2;
                StartCoroutine(CustomOnMouseDown());
            }
            #endregion
        }
     
        IEnumerator CustomOnMouseDown()
        {
            //当检测到一直触碰时,会不断循环运行
            while (Input.GetMouseButton(0))
            {
                //实时记录模型大小
                RealScale = this.transform.localScale;
                if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
                {
                    //触摸位置
                    Vector3 tempPosition1 = Input.GetTouch(0).position;
                    Vector3 tempPosition2 = Input.GetTouch(1).position;
     
                    //函数返回真为放大,返回假为缩小 
                    if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
                    {
                        //判断是否超过边界
                        if (RealScale.x < InitialScale * MaxScale)
                        {
                            this.transform.localScale += this.transform.localScale * ScaleSpeed;
                        }
                    }
                    else
                    {
                        //判断是否超过边界
                        if (RealScale.x > InitialScale * MinScale)
                        {
                            this.transform.localScale -= this.transform.localScale * ScaleSpeed;
                        }
                    }
                    //备份上一次的触摸位置
                    oldPosition1 = tempPosition1;
                    oldPosition2 = tempPosition2;
                }
     
                yield return new WaitForFixedUpdate();
            }
        }
     
        //记录手指位置与初始位置是缩小或放大
        bool isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
        {
            float leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
            float leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));
            if (leng1 < leng2)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
  • 相关阅读:
    lintcode-453-将二叉树拆成链表
    qcow2虚拟磁盘映像转化为vmdk
    wiki
    oracle
    mysql配置记录
    consul命令记录
    Prometheus监控elasticsearch集群(以elasticsearch-6.4.2版本为例)
    centos7修改网卡名称为eth0
    linux下将普通用户加入到docker组,使它可以运行docker命令
    CentOS配置history记录每个用户执行过的命令
  • 原文地址:https://www.cnblogs.com/unity3ds/p/10983038.html
Copyright © 2011-2022 走看看