热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Unity3D学习笔记(三十八):VR开发

设备安装:HTCView驱动安装:Steam-SteamVR设备激活Unity开发下载安装开发包Ass
设备安装:HTC View
 
驱动安装:Steam - SteamVR

设备激活

Unity开发
下载安装开发包
Asset Store - SteamVR Plugin
SteamVRDemo1-镜头
SteamVRDemo2-交互场景
Demo1-交互基础部分
手柄按键
正面:
----系统
----触控盘(半径为1的二维坐标)
----手柄开关(单击激活,长按关闭)
侧面:
----侧面按键
背面:
----扳机键
 
场景摄像头设置
Camera添加SteamVR组件,即可完成头戴摄像机功能
按键输入设置
手部设备
代码逻辑
创建枚举类型,区分左右手柄
双手武器,需要获取另外一只手的引用
/// 
/// 手柄类型 用于初始化手柄设备
/// 
public HandType handType = HandType.LeftHand;
// 手上拿的武器是单手还是双手的
public ItemPackage.ItemPackageType itemType = ItemPackage.ItemPackageType.OneHanded;
public HandDevice otherHand = null;
/// 
/// 控制手柄的设备
/// 
public SteamVR_Controller.Device controller;
SteamVR_Controller类
通用按键(通过枚举类型和键值控制相应按键)
public bool GetPress(ulong buttonMask) { Update(); return (state.ulButtonPressed & buttonMask) != 0; }
public bool GetPressDown(ulong buttonMask) { Update(); return (state.ulButtonPressed & buttonMask) != 0 && (prevState.ulButtonPressed & buttonMask) == 0; }
public bool GetPressUp(ulong buttonMask) { Update(); return (state.ulButtonPressed & buttonMask) == 0 && (prevState.ulButtonPressed & buttonMask) != 0; }


public bool GetPress(EVRButtonId buttonId) { return GetPress(1ul <<(int)buttonId); }
public bool GetPressDown(EVRButtonId buttonId) { return GetPressDown(1ul <<(int)buttonId); }
public bool GetPressUp(EVRButtonId buttonId) { return GetPressUp(1ul <<(int)buttonId); }

触控盘(方法,枚举,轴值)

public bool GetTouch(ulong buttonMask) { Update(); return (state.ulButtonTouched & buttonMask) != 0; }
public bool GetTouchDown(ulong buttonMask) { Update(); return (state.ulButtonTouched & buttonMask) != 0 && (prevState.ulButtonTouched & buttonMask) == 0; }
public bool GetTouchUp(ulong buttonMask) { Update(); return (state.ulButtonTouched & buttonMask) == 0 && (prevState.ulButtonTouched & buttonMask) != 0; }

public bool GetTouch(EVRButtonId buttonId) { return GetTouch(1ul <<(int)buttonId); }
public bool GetTouchDown(EVRButtonId buttonId) { return GetTouchDown(1ul <<(int)buttonId); }
public bool GetTouchUp(EVRButtonId buttonId) { return GetTouchUp(1ul <<(int)buttonId); }

public Vector2 GetAxis(EVRButtonId buttOnId= EVRButtonId.k_EButton_SteamVR_Touchpad)
{
       Update();
       var axisId = (uint)buttonId - (uint)EVRButtonId.k_EButton_Axis0;
       switch (axisId)
       {
              case 0: return new Vector2(state.rAxis0.x, state.rAxis0.y);
              case 1: return new Vector2(state.rAxis1.x, state.rAxis1.y);
              case 2: return new Vector2(state.rAxis2.x, state.rAxis2.y);
              case 3: return new Vector2(state.rAxis3.x, state.rAxis3.y);
              case 4: return new Vector2(state.rAxis4.x, state.rAxis4.y);
       }
       return Vector2.zero;
}
震动方法,只有触控盘和侧面按键有
public void TriggerHapticPulse(ushort duratiOnMicroSec= 500, EVRButtonId buttOnId= EVRButtonId.k_EButton_SteamVR_Touchpad)
{
       var system = OpenVR.System;
       if (system != null)
       {
              var axisId = (uint)buttonId - (uint)EVRButtonId.k_EButton_Axis0;
              system.TriggerHapticPulse(index, axisId, (char)durationMicroSec);
       }
}

扳机键(方法,枚举,轴值)

public float hairTriggerDelta = 0.1f; // amount trigger must be pulled or released to change state
float hairTriggerLimit;
bool hairTriggerState, hairTriggerPrevState;
void UpdateHairTrigger()
{
       hairTriggerPrevState = hairTriggerState;
       var value = state.rAxis1.x; // trigger
       if (hairTriggerState)
       {
              if (value 0.0f)
                     hairTriggerState = false;
       }
       else
       {
              if (value > hairTriggerLimit + hairTriggerDelta || value >= 1.0f)
                     hairTriggerState = true;
       }
       hairTriggerLimit = hairTriggerState ? Mathf.Max(hairTriggerLimit, value) : Mathf.Min(hairTriggerLimit, value);
}
public bool GetHairTrigger() { Update(); return hairTriggerState; }
public bool GetHairTriggerDown() { Update(); return hairTriggerState && !hairTriggerPrevState; }
public bool GetHairTriggerUp() { Update(); return !hairTriggerState && hairTriggerPrevState; }
侧面按键(枚举)
 
Demo2-交互升级部分-射击
private void InputDebug()
    {
        if (cOntroller== null) return;
        // 按扳机键
        if (controller.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger)
            || controller.GetPressDown(EVRButtonId.k_EButton_Axis1))
        {
            Debug.Log("按下扳机键");
            GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            obj.transform.localScale = Vector3.one * 0.1f;
            obj.transform.position = transform.position;
            Rigidbody rig = obj.AddComponent();
            rig.AddForce(transform.forward * 400f);
            Destroy(obj, 2f);
        }
        //if (controller.GetTouch(EVRButtonId.k_EButton_Axis0))
        //{
        //    Debug.Log("接触了触控盘");
        //}
        if (controller.GetPressDown(EVRButtonId.k_EButton_SteamVR_Touchpad)
            || controller.GetPressDown(EVRButtonId.k_EButton_Axis0))
        {
            Debug.Log("按下触控盘");
        }
        // 获得触控盘轴值 轴值在半径为1的圆上
        Vector2 touchPad = controller.GetAxis();
        if (touchPad != Vector2.zero)
        {
            Debug.Log("touchPad : " + touchPad);
            GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            obj.transform.localScale = Vector3.one * 0.01f;
            obj.transform.position = new Vector3(touchPad.x, 0, touchPad.y);
        }
        if (controller.GetPressDown(EVRButtonId.k_EButton_Grip))
        {
            Debug.Log("Grip...侧面按键被按下");
            StartCoroutine(TriggerHapticPulse());
        }
    }
 
VR界面UI
世界坐标系,画布渲染模式改成世界空间
UI都需要改成3D的

 


推荐阅读
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
author-avatar
hqgj15087878726
缅甸环球国际开户:15087878726游戏网址:www.6662016.com
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有