VR第二天

本文介绍如何在虚拟现实环境中实现手柄射线的曲线与直线切换,包括脚本编写和功能封装,以及物体抓取的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 实现曲线和直线的切换

1.头衔手柄的控制采取VRTK自带场景里的升级版的预设体,不同于第一天学习的预制体,如下图所示在这里插入图片描述
2.为有手柄RightController添加脚本,更改VRTK中的Pointer Renderer即可改变射线形状
在这里插入图片描述
3.以下是Bezier曲线,可以为其添加特效。注意setting的设置,颜色,箭头图标,最远距离。
在这里插入图片描述

2 功能的封装实例

   public class VrController : MonoBehaviour 
   {

    public SteamVR_TrackedObject tObje;  //面板拖拽赋值
    SteamVR_Controller.Device dev;


    private VRTK_Pointer pointer;
    private VRTK_StraightPointerRenderer strainghtPointerARender;
    private VRTK_BezierPointerRenderer bezierPointerRenderer;


    public GoodsTypes goodsTypes;

    bool flag = false; //是否振动

    ButtonController BtnCtrl;


    void Awake()
    {

        pointer = GetComponent<VRTK_Pointer>();
        strainghtPointerARender = GetComponent<VRTK_StraightPointerRenderer>();
        bezierPointerRenderer = GetComponent<VRTK_BezierPointerRenderer>();
        GetComponent<VRTK_Pointer>().DestinationMarkerEnter += new DestinationMarkerEventHandler(DoPointerIn);
        GetComponent<VRTK_Pointer>().DestinationMarkerSet += new DestinationMarkerEventHandler(DoPointerDestinationSet);
        BtnCtrl = this.gameObject.transform.Find("[VRTK][AUTOGEN][Controller][CollidersContainer]/Head").GetComponent<ButtonController>(); 
        //Head是手柄上头部的位置,提前在资源找到预制体,加入ButtonController控制脚本,这个脚本是自己写的,用来实现一些功能,手柄触碰不同的物品,会有枚举记录下来。注意路径的查询
    }




    void Update()
    {

        if ((int)tObje.index >= 0)  //排除index = -1的情况,这个很重要,测试时需排除!!!!
        {
            dev = SteamVR_Controller.Input((int)tObje.index);
            if (dev.GetPressDown(SteamVR_Controller.ButtonMask.Trigger))
            {
                JudeTypes(BtnCtrl.types);
            }         
        }

    }

    /// <summary>
    /// 根据手柄接触的物体,触发不同的方法
    /// </summary>
    /// <param name="types"></param>
    public  void JudeTypes(GoodsTypes types)
    {

        switch (types)
        {
            case GoodsTypes.CanGrab:
                BtnCtrl.OnTriggerGet();     //抓取拆卸
                break;
            case GoodsTypes.FunctionBtn:
                BtnCtrl.OnChangeWupin();    //触发面板上按钮的脚本                          
                break;
            case GoodsTypes.NumBtn:
                BtnCtrl.ChangeWendu();      //触发面板上数字按钮的脚本
                break;
            case GoodsTypes.None:

                break;
            default:
                break;
        }
    }

    /// <summary>
    /// 手柄振动方法
    /// </summary>
    IEnumerator HpaticPulse(float time,bool bl)
    {
        flag = bl;
        while (flag)
        {
            Invoke("StopHapticPulse", time);
            dev.TriggerHapticPulse(1000);
            //等待帧结束执行,等待所有的摄像机和GUI渲染接受后渲染(在屏幕显示之前)
            yield return new WaitForEndOfFrame();
        }
    }
    public void StopHapticPulse()
    {
        flag = false;
    }

    /// <summary>
    /// 外界调用手柄振动方法
    /// </summary>
    public void ShowShok(float t)
    {
        StartCoroutine(HpaticPulse(t, true));
    }

    /// <summary>
    /// 更改射线的类型和颜色
    /// </summary>
    private void DoPointerIn(object sender, DestinationMarkerEventArgs e)
    {

        if (e.target.tag == "Plane"  || e.target.tag == "ZhuoMian") //曲线
        {
            pointer.pointerRenderer = bezierPointerRenderer;
            pointer.enableTeleport = true;
            strainghtPointerARender.enabled = false;
            bezierPointerRenderer.enabled = true;
        }
        else 
        {
            pointer.pointerRenderer = strainghtPointerARender;
            pointer.enableTeleport = false;
            strainghtPointerARender.enabled = true;
            bezierPointerRenderer.enabled = false;

        }
          
    }

    /// <summary>
    /// 圆盘抬起时,高亮触发事件
    /// </summary>
    private void DoPointerDestinationSet(object sender, DestinationMarkerEventArgs e)
    {


        bool isFlashing;
        HighLighter liter = e.target.GetComponent<HighLighter>();
        if (liter)
        {
            isFlashing = liter.isFlashIng;
        }
        else
        {
            isFlashing = false;
        }


        if (isFlashing)  //高亮即可触发事件
        {
           InputHandler inputHander = e.target.GetComponent<InputHandler>();

            if (inputHander) 
             {
                bool juedeHand = e.target.gameObject.layer == LayerMask.NameToLayer("CanGrab") && e.target.GetComponent<Rigidbody>();//手柄上有物体
                if (!juedeHand) 
                {
                  inputHander.OnVRClick(Click.ray);
                }


             }
            
             if (e.target.gameObject.layer == LayerMask.NameToLayer("NumBtn"))
             {
                string num = e.target.gameObject.GetComponent<NumBtnCtroller>().GetNum();
                YIQIUIHandler._instances.ChangeWendu(num);
             }
          }
        }
     }

3 新版实现物体的抓取

1.手柄添加如下脚本
在这里插入图片描述
2.被抓物体添加如下脚本
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
抓取物体后可以设置物体的位置,指定某个点和向指定方向旋转
在这里插入图片描述
另外通过铰链也可以实现抓取,物体被抓时的高光颜色,边缘颜色
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

井队Tell

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值