VR物体交互

分享一个功能:用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
    }
}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 提起古代的宦官专权,一般人的脑海中都会想到东汉末年的十常侍乱政。如果细读唐史会发现,唐后期的宦官专权,比起东汉,那...
    034d10eb9128阅读 1,602评论 0 1
  • 前言:以前是不是很羡慕别人做的手工啊?今天,我就来教大家怎样简单几步就做成一个小盒子吧! 成品图: 材料: 4条或...
    唐小清呀阅读 743评论 0 1
  • 不知道从哪一年的新年开始,都会许下一个新年愿望,每次许愿的时候无比虔诚认真,总是希望自己在新的一年里能够达到某些自...
    西城小喵阅读 313评论 0 2
  • 到底是什么让我们心甘情愿的付出? 我们在这世间辛苦劳作的最终驱动力又是什么? 近段时间在重读金庸的《笑傲江湖》得到...
    怪鸭帆阅读 3,784评论 0 1