美文网首页
VR物体交互

VR物体交互

作者: xiaoxingyun | 来源:发表于2016-10-27 10:34 被阅读46次

    分享一个功能:用leap拉动一个固定位置的物体,拉动的同时使物体跟随手旋转,具体是这样的,手向上(下)运动,物体在世界坐标系中向上(下)旋转,手向右(左)运动,物体向右(左)旋转。手松开之后,物体要慢慢停下来,也就是模仿物理中的惯性。

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    [RequireComponent(typeof(AmeliGrabEventReceiver)), RequireComponent(typeof(SphereCollider))]
    public class GrabRotate : MonoBehaviour
    {
        public Camera cam;
        [Tooltip("Inertial falloff per second")]
        public float inertial = 0.99f;
        private Collider colObj;
        private Vector3 lastPos;
        private bool grab;
        private Vector3 lastAxis;
        private float lastAngle;
        public Text dbgText;
        void Start()
        {
            colObj = transform.GetComponent<Collider>();
        }
    
        /// <summary>
        /// 抓住的事件
        /// </summary>
        /// <param name="e"></param>
        void OnGrab(AmeliGrabEvent e)
        {
            lastPos = e.grabber.transform.position;//记录手的位置
            grab = true;
        }
        /// <summary>
        /// 手抓住球拖动的事件,这个事件是在update里面实现的
        /// </summary>
        /// <param name="e"></param>
        void OnGlobalGrabDrag(AmeliGrabEvent e)
        {
            if (e.grabbed != colObj)
                return;
            Vector3 newVec = Vector3.Normalize(e.grabber.position - transform.position);//实时的记录当前手与球位置的偏移差
            Vector3 lastVec = Vector3.Normalize(lastPos - transform.position);//计算球与手初始位置的偏移差
            Quaternion drot = Quaternion.FromToRotation(lastVec, newVec);//计算两个偏移差之间的旋转的角度
            Vector3 euler = drot.eulerAngles;
            Vector3 camfor = cam.transform.forward;
            Vector3 fwd = Vector3.Cross(camfor, Vector3.up);//(0,1,0)*(0,0,1)=(1,0,0)right方向
            transform.Rotate(cam.transform.up, euler.y, Space.World);//球绕着camera的y轴旋转角度的y分量
            transform.Rotate(fwd, -euler.x, Space.World);//这里根据实际情况判断取eular的x或y分量
            lastPos = e.grabber.transform.position;//每一帧都记录手的位置,用来求两帧之间的差值
            drot.ToAngleAxis(out lastAngle, out lastAxis);//把四元数转换成绕某个轴旋转的角度
        }
        void OnRelease(AmeliGrabEvent e)
        {
            grab = false;
        }
        /// <summary>
        /// 用来控制手松开之后球的惯性
        /// </summary>
        void Update()
        {
            if (grab)
                return;
            if (dbgText != null)
            {
                dbgText.text = "" + lastAngle + "\n" + transform.rotation.eulerAngles;
            }
            if (lastAngle < 0.1f)
                return;
    
            float dra = lastAngle;
            Vector3 camfor = cam.transform.forward;
            Vector3 fwd = Vector3.Cross(camfor, Vector3.up);
            transform.Rotate(lastAxis, dra, Space.World);//球绕着返回的轴转相应的角度
            lastAngle *= (1 - Time.deltaTime) * inertial;//角度按一定的参数递减,直到角度小于0.1
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:VR物体交互

          本文链接:https://www.haomeiwen.com/subject/blkjuttx.html