Unity_HTC_VIVE_VR_demo场景(二)_苏祁风_新浪博客

四、添加抓取功能

上一步做完之后,如果想和物体进行交互

那么你会大失所望——什么也不会发生。

 

选中两个手柄,给这两个手柄添加刚性体,并且勾上 Is Kinematic,反选 Use Gravity。

然后为两个手柄添加一个盒子碰撞体并勾上 Is Trigger。

默认的碰撞体太大了,需要重新指定大小和位置。

 Unity_HTC_VIVE_VR_demo场景(二)



拿起一只手柄,仔细观察。每个控制器上有这些按钮:

Unity_HTC_VIVE_VR_demo场景(二)

 

1 - 菜单键

6 - 系统键(按下后手柄断开连接,再次按下手柄再次连接上)

7 - 扳机键

8 - 握持键

9 - 触摸板键

 

 

现在让我们给手柄加上脚本。

新建一个文件夹,取名为Scripts。在里面新建一个C#脚本,取名为ViveControllerGrabObject

 

 

代码思路:

1、       获取手柄的引用

2、       储存与手柄碰撞的对象

3、       设置触发器碰撞时相关状态的事件(Enter、Stay、Exit)

4、       设置抓取物体建立连接和放开(投掷)物体的方法

5、       设置按下按钮时调用相关方法的事件

 

 

usingUnityEngine;

 

public class ViveControllerGrabObject : MonoBehaviour {

 

    //对正在被跟踪的对象进行一个引用,这里指的是一只手柄。

    privateSteamVR_TrackedObject trackedObj;

    //保存与之碰撞的组件,之后通过该组件抓取该对象

    privateGameObject CollidingObject;

    //保存玩家抓住的对象

    privateGameObject ObjectInHand;

 

 

    //Device 属性能够很方便地访问到这个手柄。通过所跟踪的对象的索引来访问控制器的 input,并返回这个 input。

    privateSteamVR_Controller.Device Controller

    {

        get { returnSteamVR_Controller.Input((int)trackedObj.index); }

    }

 

    void Awake()

    {

        trackedObj = GetComponent();

    }

   

 

 

    //获取对象模块

    private voidSetCollidingObject(Collider col)

    {

        //如果该对象已被抓取或者没有刚体组件,则不将该gameObject作为可抓取目标

        if (CollidingObject || !col.GetComponent())

        {

            //这种return的用法作用类似于break

            return;

        }

 

        //将这个对象作为可抓取的目标

        CollidingObject = col.gameObject;

    }

 

 

 

    //触发器模块

    //当触发器碰撞体进入另一个碰撞体时将其作为可抓取目标

    public void OnTriggerEnter(Collider other)

    {

        SetCollidingObject(other);

    }

    //保存那个持续停留的碰撞体(不写这个会导致异常)

    public void OnTriggerStay(Collider other)

    {

        SetCollidingObject(other);

    }

    //当碰撞体退出一个对象,将 collidingObject 设为 null 以删除目标对象。

    public void OnTriggerExit(Collider other)

    {

        if(!CollidingObject)

        {

            return;

        }

 

        CollidingObject = null;

    }

   

 

 

    //抓取模块

    private void GrabObject()

    {

        //将gameObject转移到ObjectInHand中,将 collidingObject 中保存的 gameObject 移除

        ObjectInHand = CollidingObject;

        CollidingObject = null;

        //给gameObject添加一个连接对象,并将gameObject和手柄连接起来

        var joint = AddFixedJoint();

        joint.connectedBody = ObjectInHand.GetComponent();

    }

    //创建固定连接并加到手柄中

    privateFixedJoint AddFixedJoint()

    {

        FixedJoint fx = gameObject.AddComponent();

        fx.breakForce = 20000;          //固定连接的断开力

        fx.breakTorque = 20000;         //断开扭矩,设置断开关节所需要的转矩

        return fx;

    }

 

 

 

    //释放物体模块

    private void ReleaseObject()

    {

        //确定控制器上有一个固定连接

        if(GetComponent())

        {

            //删除该连接所连的对象并删除该连接

            GetComponent().connectedBody = null;

            Destroy(GetComponent());

            //将放开物体时手柄的速度和角度赋给此物体,以形成一个抛物线

            ObjectInHand.GetComponent().velocity = Controller.velocity;

            ObjectInHand.GetComponent().angularVelocity = Controller.angularVelocity;

        }

        ObjectInHand = null;

    }

 

 

 

    //最后,在Update中处理手柄的输入

    void Update () {

 

        //按下扳机时调用抓取模块

        if(Controller.GetHairTriggerDown())

        {

            GrabObject();

        }

        //松开扳机时调用释放物体模块

        if(Controller.GetHairTriggerUp())

        {

            ReleaseObject();

        }

    }

}

 

写好脚本之后,保存退出,选中两个手柄,将脚本拖给它们

Unity_HTC_VIVE_VR_demo场景(二)

好了,现在你可以打开游戏,用你的手柄,按下扳机键抓起方块或者小球,左右互抛或者扔出去~

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值