《SteamVR2.2.0快速入门》 |
版本 |
作者 |
参与者 |
完成日期 |
备注 |
SteamVR2.2.0_QuickStart_V01_1.0 |
严立钻 |
|
2019.03.26 |
|
|
|
|
|
|
++++“SteamVR2.2.0快速入门”:是对“SteamVR2.2.0”的快速入门(Quick Start);(2019年度的重点技术突破点确立为:“SteamVR”)(前面已经有了一个“V2.0”和“V2.2.0”开发指南了:https://blog.csdn.net/VRunSoftYanlz/article/details/86618187,https://blog.csdn.net/VRunSoftYanlz/article/details/88784527,这个快速入门是基于前面两个操作指南的一个拓展,所以可以先粗略查阅一下这两篇博文;
++++“SteamVR2.2.0快速入门”:定位在熟悉SteamVR框架;
++++OpenVR的Github:https://github.com/ValveSoftware/openvr
++++OpenXR官网:https://www.khronos.org/openxr
++++SteamVR的Github:https://github.com/ValveSoftware/steamvr_unity_plugin
++++SteamVR的QuickStart:https://valvesoftware.github.io/steamvr_unity_plugin/
++++SteamVR的Releases:https://github.com/ValveSoftware/steamvr_unity_plugin/releases
++++SteamVR2.2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++SteamVR2.2.0交互系统:https://blog.csdn.net/VRunSoftYanlz/article/details/89199778
++++SteamVR2.2.0传送机制:https://blog.csdn.net/VRunSoftYanlz/article/details/89390866
++++SteamVR2.2.0官方教程:https://blog.csdn.net/VRunSoftYanlz/article/details/89324067
##《SteamVR2.2.0快速入门》目录
#第一篇:v2.2.0快速入门
#第二篇:v2.2.0示例教程
#第三篇:v2.2.0的API
#第四篇:v2.2.0框架结构
#第五篇:立钻哥哥对SteamVR的拓展
推广:【XR游戏开发QQ群:784477094】
#第一篇:v2.2.0快速入门 |
#第一篇:v2.2.0快速入门
++++立钻哥哥:”Valve” maintains a “Unity plugin” to smoothly interface “SteamVR” with Unity. With “SteamVR” developers can target one API that all the popular VR headsets can connect to. The modern “SteamVR Unity Plugin” manages three main things for developers: loading 3d models for VR controllers, handling input from those controllers, and estimating what your hand looks like while using those controllers. On top of managing those things we have an “Interaction System example” to help get your VR application off the ground. Proving concrete examples of interacting with the virtual world and our APIs.(立钻哥哥:“Valve”维护了一个“Unity插件”,使“SteamVR”与Unity的界面更加流畅。使用“SteamVR”,开发者可以将所有流行的VR头盔连接到一个API上。现代的“SteamVR Unity插件”为开发者管理了三件主要的事情:为VR控制器加载3d模型,处理来自这些控制器的输入,以及在使用这些控制器时估计你的手的样子。在管理这些事情之上,我们有一个“交互系统示例”来帮助您的VR应用程序起步。证明与虚拟世界和我们的api交互的具体例子。)
++++A.1、Quickstart
++++A.2、Render Models
++++A.3、SteamVR Input
++++A.4、Skeleton Input
++++A.5、Interaction System
++++A.6、Skeleton Poser
++++A.7、立钻哥哥带您v2.2.0快速入门
++++https://valvesoftware.github.io/steamvr_unity_plugin/
##A.1、Quickstart |
++A.1、Quickstart
++++立钻哥哥:There’s a quickstart guide here that will lead you through the process of getting setup with the “SteamVR Unity Plugin” and into a scene.(立钻哥哥:这里有一个快速入门指南,将带领你通过“SteamVR Unity插件”的安装过程进入一个场景。)
++++https://valvesoftware.github.io/steamvr_unity_plugin/articles/Quickstart.html
++Quickstart(快速入门)
++++立钻哥哥:You’ll need to have “SteamVR” installed and a “SteamVR” compatible headset. If you have a “VR HMD” it’s probably compatible. (立钻哥哥:您需要安装“SteamVR”和一个兼容“SteamVR”的头盔。如果你有一个“VR HMD”,它需要是兼容的。)
++++You can download SteamVR here: https://store.steampowered.com/app/250820/SteamVR/.(立钻哥哥:您可以在这里下载SteamVR: https://store.steampowered.com/app/250820/SteamVR/。)
++Download(下载)
++++立钻哥哥:Download the “SteamVR Unity Plugin” from the asset store here: https://assetstore.unity.com/packages/tools/integration/steamvr-plugin-32647.(立钻哥哥:从这里的资源商店下载“SteamVR Unity Plugin”:https://assetstore.unity.com/packages/tools/integration/steamvr-plugin-32647。)
++SteamVR Input Window(SteamVR输入窗口)
++++立钻哥哥:Once imported open the “SteamVR Input window” under the “Window” file menu.(立钻哥哥:导入后,打开“窗口”文件菜单下的“SteamVR输入窗口”)
++Copy JSONs(复制Json)
++++立钻哥哥:Click Okay to copy the default “SteamVR Input JSON” files. These are actions and bindings that will help the “Interaction System” work and give you examples of how to get started.(立钻哥哥:单击ok复制默认的“SteamVR Input JSON”文件。这些操作和绑定将帮助“交互系统”工作,并为您提供如何开始的示例。)
++Save and Generate(保存并生成)
++++立钻哥哥:After those files copy and the window has opened click the “Save and Generate” button at the bottom. This will save your actions and generate some classes to initialize them and give you easy access to them in the editor and through code.(立钻哥哥:当这些文件复制并打开窗口后,点击底部的“保存并生成”按钮。这将保存您的操作并生成一些类来初始化它们,并使您能够在编辑器中通过代码轻松地访问它们。)
++Interaction System(交互系统)
++++立钻哥哥:Once that’s done go ahead and open the “Interaction System” sample scene. You’ll find it in “Assets/SteamVR/InteractonSystem/Samples/Interaction_Example”.(立钻哥哥:完成之后,打开“交互系统”示例场景。您可以在“Assets/SteamVR/InteractonSystem/Samples/Interaction_Example”中找到它。)
++++Then connect your headset, controllers, hit play, and explore the “Interaction System” example scene!(立钻哥哥:然后连接您的头盔,控制器,点击播放,并探索“交互系统”的例子场景!)
##A.2、Render Models |
++A.2、Render Models
++++立钻哥哥:”SteamVR” works with a wide array of headsets and controllers. When you have a tracked device in VR it’s nice to have an accurate visualization of that device. Instead of shipping each individual model and texture for each controller with each application, “SteamVR” can manage this for you. We include a “SteamVR_RenderModel” component that you can put on a gameobject that will auto load whatever device “SteamVR” detects for a given Pose. Put a “SteamVR_Behaviour_Pose” on a gameobject to get the position and rotation of a controller and then a “SteamVR_RenderModel” to show the 3d model for that controller that will animate with button presses. See the simple sample scene or the “SteamVR/Prefabs/CameraRig” prefab for an example.(立钻哥哥:“SteamVR”与各种头盔和控制器配合使用。当你在VR中拥有一个被跟踪的设备时,拥有该设备的精确可视化效果是很好的。“SteamVR”可以为您管理这一点,而不是为每个应用程序为每个控制器提供每个单独的模型和纹理。我们包括了一个“SteamVR_RenderModel”组件,你可以把它放在一个gameobject(游戏对象)上,它会自动加载任何设备“SteamVR”检测到的给定姿势。在gameobject(游戏物体)上放置一个“SteamVR_Behavior_Pose”来获取控制器的位置和旋转,然后是一个“SteamVR_RenderModel”来显示控制器的3d模型,该模型将通过按键来动画。参见简单的场景示例或“SteamVR/Prefabs/CameraRig”预制件作为示例。)
++++https://valvesoftware.github.io/steamvr_unity_plugin/articles/Render-Models.html
++Render Models(渲染模型)
++++立钻哥哥:Since your whole field of vision is covered when immersed in “Virtual Reality” it’s helpful to have virtual representations of the controllers you’re holding. “SteamVR” provides an easy way to get not just a general controller model but models with individually actuating components. So when you pull the trigger on your controller in real life you can see it pull in the virtual world as well. This helps with usability as well as strongly encourages the feeling of presence.(立钻哥哥:因为当你沉浸在“虚拟现实”中时,你的整个视野都被覆盖了,所以拥有你所持有的控制器的虚拟表示是很有帮助的。“SteamVR”提供了一种简单的方法,不仅可以获得一般的控制器模型,还可以获得具有单独驱动组件的模型。所以,当你在现实生活中按下控制器上的触发器时,你可以看到它在虚拟世界中也在按下。这有助于提高可用性,并强烈地鼓励存在感。)
++The Component(组件)
++++立钻哥哥:Both the “Interaction System” and the Simple Sample scenes have rigs that use render models. In the Simple Sample scene look in the [Camera Rig] prefab, you’ll find Controller(left) and Controller(right). These GameObjects have a “SteamVR_Behaviour_Pose” component on them which sets the position and rotation of the transform. Under those objects you’ll see GameObjects called Model which hold our “SteamVR_RenderModel” component. It has a few members: Index、Model Override、Shader、Verbose、Create Components、Update Dynamically。(立钻哥哥:“交互系统”和简单的示例场景都有使用呈现模型的平台。在[Camera Rig]预置的简单场景示例中,您将找到Controller(左)和Controller(右)。这些游戏对象上有一个“SteamVR_Behaviour_Pose”组件,用于设置转换的位置和旋转。在这些对象下面,你会看到一个叫做Model的GameObjects,它包含了我们的“SteamVR_RenderModel”组件。它有几个成员:索引、模型覆盖、着色器、详细、创建组件、动态更新。)
++++[Index(索引)]:this is the “tracked device index” for the controller. It’s an integer id used by the render model system to identify the controller to the underlying system. In previous iterations of SteamVR this was also used to access inputs on that controller, but now that is done through the “Input System”.(立钻哥哥:(索引):这是“跟踪装置索引”的控制器。它是一个整数id,呈现模型系统使用它来标识底层系统的控制器。在之前的SteamVR迭代中,这也被用于访问控制器上的输入,但现在这是通过“输入系统”完成的。)
++++[Model Override(模型覆盖)]:Generally for testing purpose you can specify what model you would like to display instead of dynamically assessing the type of device connected.(立钻哥哥:(模型覆盖):通常用于测试目的可以指定您想显示而不是动态评估模型装置连接的类型。)
++++[Shader(着色器)]:If you would prefer to use a different shader to render the model you can specify it here. By default, Unity’s Standard Shader is used.(立钻哥哥:(着色器):如果您更愿意使用不同的材质渲染模型在这里您可以指定。默认情况下,使用Unity的标准着色器。)
++++[Verbose(详细)]:Will output debug logs to tell you what’s happening with the script.(立钻哥哥:(详细)]:将输出调试日志与脚本告诉你发生了什么。)
++++[Create Components(创建组件)]:Create individual GameObjects for each component where available.(立钻哥哥:(创建组件):为每个组件创建个人GameObjects可用。)
++++[Update Dynamically(动态更新)]:Will move the individual components inline with their physical counterparts.(立钻哥哥:(动态更新):将各个组件内联与物理同行。)
++Attaching Objects(附属对象)
++++立钻哥哥:Developers commonly want to attach GameObjects to specific points on controllers. For this we have placed a GameObject called “attach” under each part of the controller that is centered on the part in question. For ease of access you can get access to the “SteamVR_RenderModel” script and call “CetComponentTransform(string componentName)” which will return \a Transform (without doing any GC alloc). The componentName parameter here is case sensitive so make sure you pass in the component name exactly as it appears in the hierarchy at runtime.(立钻哥哥:开发人员通常希望将gameobject附加到控制器上的特定点。为此,我们在控制器的每个部分下都放置了一个名为“attach”的GameObject(游戏对象),该对象以所讨论的部分为中心。为了方便访问,您可以访问“SteamVR_RenderModel”脚本并调用“CetComponentTransform(string componentName)”,它将返回\a转换(不执行任何GC alloc)。这里的componentName参数是区分大小写的,所以请确保您传递的组件名称与运行时在层次结构中出现的名称完全相同。)
++Notes
++++立钻哥哥:The “SteamVR_RenderModel” component needs to be on the same gameobject as something that will set its Index. In the [CameraRig] prefab this is done by the “SteamVR_Behaviour_Pose” script.(立钻哥哥:“SteamVR_RenderModel”组件需要与设置其索引的东西位于相同的gameobject上。在[CameraRig]预置中,这是由“SteamVR_Behavior_Pose”脚本完成的。)
##A.3、SteamVR Input |
++A.3、SteamVR Input
++++立钻哥哥:Since “SteamVR” works with so many different input devices we’ve simplified the process of accommodating all these devices. Instead of referencing the individual buttons on one controller, with “SteamVR Input” you reference an action. Instead of writing the code to recognize “pulling the trigger button down 75% of the way to grab the block” you can now just focus on the last bit of that, “grab the block”. You still configure the default for what “grab” means but the user can rebind it to their preference in a standard interface. And when a new input device comes out your users can publish bindings to share for that device with no code changes on your end.(立钻哥哥:因为“SteamVR”可以与许多不同的输入设备一起工作,所以我们简化了容纳所有这些设备的过程。使用“SteamVR Input”引用一个动作,而不是引用一个控制器上的单个按钮。不需要编写代码来识别“在抓取物体的过程中按下75%的触发按钮”,现在只需将注意力集中在最后一点上,即“抓取物体”。您仍然可以为“grab”的含义配置默认值,但是用户可以在标准界面中将其重新绑定到他们的首选项。当一个新的输入设备出现时,您的用户可以发布绑定来共享该设备,而不需要您更改代码。)
++++https://valvesoftware.github.io/steamvr_unity_plugin/articles/SteamVR-Input.html
++Input System(输入系统)
++++立钻哥哥:The heart of the “SteamVR Unity Plugin” is actions. Virtual Reality is evolving at a rapid rate and we need our software to be able to evolve with the hardware. “SteamVR Input” abstracts away the device specific parts of your code so you can focus on the intent of the user-their actions. Instead of writing the code to recognize “pulling the button down 75% of the way to grab the block” you can now just focus on the last bit of that, “grab the block”. You still configure the default for what “grab” means but the user can rebind it to their preference in a standard interface. And when a new input device comes out your users can publish bindings to share for that device with no code changes on your end.(立钻哥哥:“SteamVR Unity插件”的核心是动作。虚拟现实正在快速发展,我们需要我们的软件能够随着硬件的发展而发展。“SteamVR输入”抽象出代码中设备特定的部分,这样你就可以关注用户的意图——他们的行为。不需要编写代码来识别“向下拉75%的按钮来抓取物体”,现在只需将注意力集中在最后一点上,即“抓取物体”。您仍然可以为“grab”的含义配置默认值,但是用户可以在标准界面中将其重新绑定到他们的首选项。当一个新的输入设备出现时,您的用户可以发布绑定来共享该设备,而不需要您更改代码。)
++++This style of abstracting input is similar to how many other companies are thinking about it. Members from most of the major “Virtual Reality” hardware companies have joined “Khronos” to create the OpenXR standard which is still under development. For more information in participating in this organization and contributing to industry standards like this see: https://www.khronos.org/openxr. (立钻哥哥:这种抽象输入的风格与许多其他公司正在考虑的类似。来自大多数主要“虚拟现实”硬件公司的成员加入了“Khronos”,创建了仍在开发中的OpenXR标准。要了解更多信息,请参见https://www.khronos.org/openxr。)
++++”SteamVR” has separated actions out into 6 different types of input and once output type.(立钻哥哥:“SteamVR”将动作分为6种不同的输入类型和一种输出类型。)
++++[Boolean]:true or false(立钻哥哥:(布尔):真或假);
++++[Single]:an analog value(立钻哥哥:(一):一个模拟值);
++++[Vector2]:two analog values(立钻哥哥:(Vector2):两个模拟值);
++++[Vector3]:three analog values(立钻哥哥:[Vector3]:三个模拟值);
++++[Pose]:position, rotation, velocity, and angular velocity(立钻哥哥:[姿态]:位置、旋转速度和角速度);
++++[Skeleton]:Orientations for each bone in a hand(立钻哥哥:(骨架):方向为每个手骨);
++++[Vibration]:Actuating haptic motors(立钻哥哥:(振动):主动触觉马达);
++Boolean(布尔运算)
++++立钻哥哥:Boolean actions are values that are either true or false. For example, Grab is a common action that is either true or false. You’re either intending to hold something or you aren’t, there is no in between. With a “Vive Wand” this may mean pulling the trigger 75%, with an “Oculus Touch” this may mean pulling the grip trigger 25%, with “Knuckles” this may be some combination of capacitive sensing and force sensing. But in the end it breaks down to a true or false value.(立钻哥哥:布尔操作是为真或为假的值。例如,Grab是一个常见的操作,它要么为真,要么为假。你要么打算持有某样东西,要么不打算持有,两者之间没有中间地带。用“Vive魔杖”,这可能意味着扣动75%的扳机,用“Oculus Touch”,这可能意味着扣动25%的手柄扳机,用“Knuckles”,这可能是电容感应和力感应的某种结合。但最终它分解为一个真值或一个假值。)
++Single(单一向量)
++++立钻哥哥:Single actions are analog values from 0 to 1. These are scenarios where you need more data than just a true or false. These are fewer of these than you’d expect. If previously you were reading a 0 to 1 value and then waiting for it to get to a certain point, a threshold, then you can accomplish the same thing with a boolean action, making it easier for your end user to customize. A good example of a “Single” action is the “Throttle for the RC car” in the “SteamVR Interaction System”. The action your taking as a user can vary depending on how fast you want the car to travel.(立钻哥哥:单个动作是从0到1的模拟值。这些场景需要更多的数据,而不仅仅是真假。这些比你想象的要少。如果您以前读取0到1的值,然后等待它到达某个特定的点(阈值),那么您可以使用布尔操作完成相同的操作,使您的最终用户更容易自定义。“单一”动作的一个很好的例子是“SteamVR交互系统”中的“RC车油门”。您作为用户所采取的操作可能会根据您希望汽车行驶的速度而有所不同。)
++Vector2(二维向量)
++++立钻哥哥:Vector2 actions are a combination of two analog values. An X and a Y. Generally in VR so far these sort of actions are best represented by the radial menus or 2D positioning. In the “SteamVR Interaction System” we have an example of steering an “RC car” as well as a platformer type character. On the “Vive Wand” this is mapped to the touchpad but on “Oculus Touch” and “Knuckles” this is mapped to the “joystick”. With the “RC car” we’re using the y axis to determine forward or backward direction and the x axis to determine turning. With the “platformer” we’re mapping the x/y input onto the direction and magnitude of the character’s movement.(立钻哥哥:Vector2动作是两个模拟值的组合。在VR中,X和y通常用径向菜单或2D定位来表示。在“SteamVR交互系统”中,我们有一个驾驶“RC车”的例子,以及一个平台型角色。在“Vive魔杖”这是映射到触摸板,但在“Oculus Touch”和“Knuckles”这是映射到“操纵杆”。对于“RC car”,我们使用y轴来确定前进或后退的方向,使用x轴来确定转弯。使用“platformer”,我们将x/y输入映射到角色移动的方向和大小。)
++Vector3(三维向量)
++++立钻哥哥:Vector3 actions are pretty uncommon. In “SteamVR Home” this is used for scrolling, x, y, and z is the number of pages to scroll.(立钻哥哥:Vector3操作非常不常见。在“SteamVR Home”中,这用于滚动,x、y和z是要滚动的页面数量。)
++Pose(姿势)
++++立钻哥哥:Pose actions are a representation of a position and rotation in 3d space. This is used to track your VR controllers. The user can customize these bindings by setting the point on the controller that the pose represents. Some users may find a slightly different tracked position or rotation feels better for them.(立钻哥哥:姿态动作是三维空间中位置和旋转的一种表示。这是用来跟踪你的VR控制器。用户可以通过设置姿态表示的控制器上的点来定制这些绑定。一些用户可能会发现稍微不同的跟踪位置或旋转对他们来说感觉更好。)
++Skeleton(骨骼)
++++立钻哥哥:Skeleton actions use “SteamVR Skeleton Input” to get our best estimation of the orientation of your fingers while holding your VR controllers. This provides one standard to get joint positions and rotations for every controller regardless of tracking fidelity. Controllers with the capacity for higher fidelity finger tracking will be more accurate than those without.(立钻哥哥:骨骼动作使用“SteamVR骨骼输入”来获得我们在握住VR控制器时对手指方向的最佳估计。这提供了一个标准来获取每个控制器的关节位置和旋转,而不管跟踪保真度如何。具有更高保真度手指跟踪能力的控制器将比那些没有的更精确。)
++Vibration
++++立钻哥哥:Vibration actions are used to trigger haptic feedback on VR devices. This could be a controller, a vest, or even a chair.(立钻哥哥:振动动作用于在VR设备上触发触觉反馈。这可以是一个控制器,一件背心,甚至一把椅子。)
++Using actions
++++立钻哥哥:Once you’ve created your actions you can use them in your own scripts or you can use the unity components we’ve created that handle some common tasks. These are named “SteamVR_Behaviour_Boolean”, “SteamVR_Behaviour_Single”, “SteamVR_Behaviour_Vector2”, “SteamVR_Behaviour_Vector3”, “SteamVR_Behaviour_Pose”, and “SteamVR_Behaviour_Skeleton”. Drag those onto a GameObject to see what they can do.(立钻哥哥:一旦创建了操作,就可以在自己的脚本中使用它们,或者使用我们创建的unity组件来处理一些常见的任务。它们分别被命名为“SteamVR_Behaviour_Boolean”、“SteamVR_Behaviour_Single”、“SteamVR_Behaviour_Vector2”、“SteamVR_Behaviour_Vector3”、“SteamVR_Behaviour_Pose”和“SteamVR_Skeleton”。把它们拖到GameObject(游戏物体)上看看它们能做什么。)
##A.4、Skeleton Input |
++A.4、Skeleton Input
++++立钻哥哥:Inline with the “Knuckles Valve” has released a system to get skeletal hand data independent from the controller you’re using. Some controllers have a high fidelity for hand tracking data with individual joints, some controllers only have buttons that we use to approximate joint data. We use whatever is available and give you two major sets of data: “With Controller”, “Without Controller”.(立钻哥哥:内联的“关节阀”已经发布了一个系统,以获得骨骼手数据独立于你使用的控制器。有些控制器对单个关节的手部跟踪数据有很高的保真度,有些控制器只有我们用来近似关节数据的按钮。我们使用所有可用的数据,并给出两组主要的数据:“带控制器”和“不带控制器”。)
++++[With Controller]: Our best approximation of where the joints in your hand are wrapped around your controller in the real world.(立钻哥哥:[带控制器]:我们的最佳近似值,在现实世界中,您手中的关节是围绕在控制器周围的。)
++++[Without Controller]: Based on the “With Controller” data we estimate how open or closed your hand it as if you were trying to hold your hand flat or make a fist.(立钻哥哥:[不带控制器]:根据“有控制器”的数据,我们估计你的手张开或闭合的程度,就像你试图把你的手放平或握紧拳头一样)
++++Included in this plugin are example models of gloves that you can freely use in your products. In addition we have a helper component that takes the data from “SteamVR” and applies it to these gloves: “SteamVR_Behaviour_Skeleton”. For an example of this in action see the “Interaction System” sample scene.(立钻哥哥:这个插件包括手套的例子模型,你可以在你的产品中免费使用。此外,我们还有一个助手组件,它从“SteamVR”获取数据并将其应用于这些手套:“SteamVR_Behaviour_Skeleton”。有关实际操作的示例,请参见“交互系统”示例场景。)
++++https://valvesoftware.github.io/steamvr_unity_plugin/articles/Skeleton-Input.html
++Skeleton Input(骨架的输入)
++++立钻哥哥:Seeing your physical controllers in VR is nice but what people really want is to be able to see their hands. As VR controllers advance we’re seeing wildly different capabilities. Some controllers only get button presses(on touch), some give good finger estimates even mid-air, and we’re starting to see gloves and cameras that have full per joint position/rotation tracking. “SteamVR Skeleton Input” gives you one API to get per joint data for all of these different types of devices. For devices with less data we estimate finger positions based on what buttons are being pressed while with more advanced controllers the data is just passed through.(立钻哥哥:在VR中看到你的物理控制器很好,但是人们真正想要的是能够看到他们的手。随着VR控制器的发展,我们看到了截然不同的功能。有些控制器只能(在触摸时)按下按钮,有些甚至在半空中也能给出良好的手指估计,我们开始看到手套和摄像机每个关节位置/旋转跟踪都是完整的。“SteamVR骨架输入”为您提供了一个API来获取所有这些不同类型设备的每个关节数据。对于数据较少的设备,我们根据按下的按钮来估计手指的位置,而对于更高级的控制器,数据只是通过。)
++Range Of Motion(活动范围)
++++立钻哥哥:We have two ranges of motion that you can get bone data for. If you’re looking for accurate-to-real-world data you can use the “WithController” range of motion. This means we try and estimate where your fingers are in the real world as best as the controller will allow. “WithoutController” gives you a full range from a flat hand with fingers spread out to a balled fist.(立钻哥哥:我们有两种运动范围你可以得到骨骼数据。如果您正在寻找精确到真实世界的数据,您可以使用“WithController”运动范围。这意味着我们要在控制器允许的范围内尽可能地估计你的手指在现实世界中的位置。“无控制器”给你一个完整的范围,从一个扁平的手与手指展开到一个揉成一团的拳头。)
++Skeletal Transform Space(骨骼变换空间)
++++立钻哥哥:Depending on what your use case is for this data you may want to get the positions and rotations relative to different things. By default we get positions and rotations relative to their “Parent”. But you can alse get them relative to the Model.(立钻哥哥:根据这个数据的用例,您可能希望获得相对于不同事物的位置和旋转。默认情况下,我们得到的位置和旋转相对于他们的“父”。但你也可以让它们相对于模型。)
++Finger Curls(手指弯曲)
++++立钻哥哥:For some things it may be more useful to access a summary of how curled the finger is as opposed to the position and rotation for 4 joints on each finger. These values range from 0 to 1, with 1 being fully curled. You can access curl information at “skeletonAction.fingerCurls[]” as an array, or individually named at “skeletonAction.indexCurl”, “skeletonAction.middleCurl”, “skeletonAction.RingCurl”, “skeletonAction.pinkyCurl”, and “skeletonAction.thumbCurl”. (立钻哥哥:对于某些情况,相对于每个手指上4个关节的位置和旋转,总结一下手指是如何弯曲的可能更有用。这些值的范围从0到1,其中1是完全卷曲的。您可以通过“skeletonAction.fingerCurls[]”数组访问curl信息,或单独命名在“skeletonAction.indexCurl”、“skeletonAction.middleCurl”、“skeletonAction.RingCurl”、“skeletonAction.pinkyCurl”、“skeletonAction.thumbCurl”。)
++Finger Splays(手指张开)
++++立钻哥哥:Knowing the gaps between fingers can also be a commonly used piece of information. For this we provide data in a similar fashion to the curls. A range from 0 to 1 representing the size of the gap between fingers. “skeletonAction.fingerSplays[]” as an array, or individually named as “skeletonAction.thumbIndexSplay”, “indexMiddleSplay”, “middleRingSplay”, and “ringPinkySplay”.(立钻哥哥:知道手指之间的间隙也是一个常用的信息。为此,我们以与张开类似的方式提供数据。范围从0到1表示手指之间的间隙大小。“skeletonAction.fingerSplays[]”作为数组,或单独命名为“skeletonAction.thumbIndexSplay”、“indexMiddleSplay”、“middleRingSplay”和“ringPinkySplay”。)
++Skeletal Tracking Level(骨骼跟踪级别)
++++立钻哥哥:Different controllers have different abilities to track the individual joints of your fingers. Here we provide an overview value that should give you a general idea what level of fidelity your current controller has.(立钻哥哥:不同的控制器有不同的能力来跟踪你手指的各个关节。在这里,我们提供一个概览值,让您大致了解当前控制器的保真度级别。)
++++[Estimated]:Body part location can’t be directly determined by the device. Any skeletal pose provided by the device is estimated based on the active buttons, triggers, joysticks, or other input sensors. Examples include the “Vive Controller” and gamepads.(立钻哥哥:(预估):身体部位位置不能直接由设备。该设备提供的任何骨骼姿态都是基于活动按钮、触发器、操纵杆或其他输入传感器来估计的。例如“Vive Controller”和gamepads。)
++++[Partial]: Body part location can be measured directly but with fewer degrees of freedom than the actual body part. Certain body part positions may be unmeasured by the device and estimated from other input data. Examples include “Knuckles” or gloves that only measure finger curl.(立钻哥哥:[部分]:人体部位位置可以直接测量,但自由度小于实际人体部位。某些身体部位的位置可以不被设备测量,并从其他输入数据估计。例如,“指节”或手套只能测量手指弯曲度。)
++++[Full]: Body part location can be measured directly throughout the entire range of motion of the body part. Example include hi-end mocap systems, or gloves that measure the rotation of each finger segment.(立钻哥哥:[Full]:可以直接测量身体部位的整个运动范围。例如,高端mocap系统,或测量每个手指节旋转的手套。)
++SteamVR_Behaviour_Skeleton
++++立钻哥哥:The skeleton behaviour is a component to make common “Skeleton Input” tasks easier in unity. By setting the “skeletonAction” and “inputSource” you can then let the behaviour do a lot of work for you.(立钻哥哥:骨架行为是一个组件,它使unity中常见的“骨架输入”任务变得更容易。通过设置“skeletonAction”和“inputSource”,您可以让行为为您做很多工作。)
++++[updatePose]: Setting this to true will orient the GameObject in your playspace every time the skeleton is updated.(立钻哥哥:[updatePose]:将此设置为true将会在每次骨架更新时在你的游戏空间中定位GameObject。)
++++[mirroring]: If this bone data should be mirrored across the x axis.(立钻哥哥:[镜像]:如果骨数据应该在x轴上镜像。)
++++[setRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds=0.1f)]: Gives you an easy way to blend to a new range of motion.(立钻哥哥:[setRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds=0.1f)]:提供一种简单的方法来混合到一个新的运动范围。)
++++[BlendToSkeleton(float overTime=0.1f)]: Fully blend to using the skeleton data to animate the bones.(立钻哥哥:[BlendToSkeleton(float overTime=0.1f)]:完全混合使用骨骼数据来动画骨骼。)
++++[BlendToPoser(SteamVR_Skeleton_Poser poser, float overTime=0.1)]: Fully blend to using the Poser to animate the bones.(立钻哥哥:[BlendToPoser(SteamVR_Skeleton_Poser poser, float overTime=0.1)]:完全混合到使用poser动画骨骼。)
++++[BlendToAnimation(float overTime=0.1f)]: Fully blend to a predefined Unity animation.(立钻哥哥:[BlendToAnimation(float overTime=0.1f)]:完全混合到预定义的Unity动画中。)
++++[BlendTo(float blendToAmount, float overTime)]: Lets you specify how much to blend between poser/animation data and skeleton input data.(立钻哥哥:[BlendTo(float blendToAmount, float overTime)]:让您指定要在poser/animation数据和骨架输入数据之间混合多少。)
++++[Transform GetBone(int joint)]: Returns a specific bone’s Transform by the joint index.(立钻哥哥:[Transform GetBone(int joint)]:通过关节索引返回特定的骨转换。)
++++[ForceToReferencePose(EVRSkeletalReferencePose referencePose)]: Forced the bones to a specific reference pose as defined by “SteamVR”. Generally used for debugging purposes.(立钻哥哥:[ForceToReferencePose(EVRSkeletalReferencePose referencePose)]:强迫骨头摆出一个特定的参照姿势,这是由“SteamVR”定义的。通常用于调试目的。)
++++[Vector3[] GetBonePositions()]: Gives you an array of all the bone position in the space you requested.(立钻哥哥:[Vector3 [] GetBonePositions()]:提供一个数组,其中包含您请求的空间中的所有骨位置。)
++++[Quaternion[] GetBoneRotations()]: Gives you an array of all the bone rotations in the space you requested.(立钻哥哥:[Quaternion[] GetBoneRoations()]:为您提供所需空间中所有骨旋转的数组。)
++++\Assets\SteamVR\Input\SteamVR_Behaviour_Skeleton.cs
using System; using System.Collections; using UnityEngine; using UnityEngine.Events; using Valve.VR;
namespace Valve.VR{ public class SteamVR_Behaviour_Skeleton : MonoBehaviour{ //The action this component will use to update the model. Must be a Skeleton type action.(立钻哥哥:此组件将用于更新模型的操作。必须是骨架类型的操作。) public SteamVR_Action_Skeleton skeletonAction;
public SteamVR_Input_Sources inputSource; public EVRSkeletalMotionRange rangeOfMotion = EVRSkeletalMotionRange.WithoutController; public Transform skeletonRoot; public Transform origin; public bool updatePose = true; public bool onlySetRotations = false;
[Range(0, 1)] public float skeletonBlend = 1f;
public SteamVR_Behaviour_SkeletonEvent onBoneTransformsUpdated; public SteamVR_Behaviour_SkeletonEvent onTransformUpdated; public SteamVR_Behaviour_SkeletonEvent onTransformChanged; public SteamVR_Behaviour_Skeleton_ConnectedChangedEvent onConnectedChanged; public SteamVR_Behaviour_Skeleton_TrackingChangedEvent onTrackingChanged;
public UpdateHandler onBoneTransformsUpdatedEvent; public UpdateHandler onTransformUpdatedEvent; public ChangeHandler onTransformChangedEvent; public DeviceConnectedChangeHandler onConnectedChangedEvent; public TrackingChangeHandler onTrackingChangedEvent;
protected SteamVR_Skeleton_Poser blendPoser; protected SteamVR_Skeleton_PoseSnapshot blendSnapshot;
public MirrorType mirroring;
public bool isActive{}
public float[] fingerCurls{} public float thumbCurl{} public float indexCurl{} public float middleCurl{} public float ringCurl{} public float pinkyCurl{}
public Transform[] proximals{} public Transform[] middles{} public Transform[] distals{} public Transform[] tips{} public Transform[] auxs{}
protected Coroutine blendRoutine; protected Coroutine rangeOfMotionBlendRoutine; protected Coroutine attachRoutine;
protected Transform[] bones;
protected EVRSkeletalMotionRange? temporaryRangeOfMotion = null;
public EVRSkeletalTrackingLevel skeletalTrackingLevel{} public bool isBlending{} public float predictedSecondsFrowNow{}
public SteamVR_ActionSet actionSet{} public SteamVR_ActionDirections direction{}
protected virtual void Awake(){} protected virtual void CheckSkeletonAction(){} protected virtual void AssignBonesArray(){}
protected virtual void OnEnable(){} protected virtual void OnDisable(){}
private void OnDeviceConnectedChanged(SteamVR_Action_Skeleton fromAction, bool deviceConnected){} private void OnTrackingChanged(SteamVR_Action_Skeleton fromAction, ETrackingResult trackingState){} protected virtual void SteamVR_Input_OnSkeletonsUpdated(bool skipSendingEvents){} protected virtual void UpdateSkeleton(){}
public void SetTemporaryRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds=0.1f){} public void ResetTemporaryRangeOfMotion(float blendOverSeconds=0.1f){} public void SetRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds=0.1f){} public void BlendToSkeleton(float overTime=0.1f){} public void BlendToPoser(SteamVR_Skeleton_Poser poser, float overTime=0.1f){} public void BlendToAnimation(float overTime=0.1f){} public void BlendTo(float blendToAmout, float overTime){}
protected IEnumerator DoBlendRoutine(float blendToAmout, float overTime){} protected void RangeOfMotionBlend(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds){} protected void TemporaryRangeOfMotionBlend(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds){} protected void ResetTemporaryRangeOfMotionBlend(float blendOverSeconds){} protected IEnumerator DoRangeOfMotionBlend(EVRSkeletalMotionRange oldRangeOfMotion, EVRSkeletalMotionRange newRangeOfMotion, float overTime){} protected virtual Quaternion GetBlendPoseForBone(int boneIndex, Quaternion skeletonRotation){} protected virtual void UpdateSkeletonTransforms(){} protected virtual void SetBonePosition(int boneIndex, Vector3 localPosition){} protected virtual void SetBoneRotation(int boneIndex, Quaternion localRotation){}
public virtual Transform GetBone(int joint){} public Vector3 GetBonePosition(int joint, bool local=false){} public Quaternion GetBoneRotation(int joint, bool local=false){}
protected Vector3[] GeetBonePositions(){} protected Quaternion rightFlipAngle = Quaternion.AngleAxis(180, Vector3.right); protected Quaternion[] GetBoneRotations(){} protected virtual void UpdatePose(){}
public void ForceToReferencePose(EVRSkeletalReferencePose referencePose){}
protected bool IsMetacarpal(int boneIndex){}
public enum MirrorType{ None, LeftToRight, RightToLeft }
public delegate void ActiveChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, bool active){} public delegate void ChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource){} public delegate void UpdateHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource){} public delegate void TrackingChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, ETrackingResult trackingState){} public delegate void ValidPoseChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, bool validPose){} public delegate void DeviceConnectedChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, bool deviceConnected){}
} //立钻哥哥:public class SteamVR_Behaviour_Skeleton:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR{} |
++SteamVR_Behaviour_Skeleton Events(事件)
++++立钻哥哥:There’s five helpful events on the skeleton behaviour that have two forms. You can subscribe to the unity event or the more traditional C# event. The benefit of the C# events is most IDEs will automatically create a function with named parameters for you based on the event type.(立钻哥哥:在骨架行为上有五个有用的事件,它们有两种形式。您可以订阅unity事件或更传统的c#事件。c#事件的好处是,大多数ide会根据事件类型自动为您创建带有命名参数的函数。)
++++[onBoneTransformsUpdated]: After the bone transforms have been updated this will fire.(立钻哥哥:[onBoneTransformsUpdated]:在更新了骨转换之后,将会触发。)
++++[onTransformUpdated]: After the root transform has been updated this will fire.(立钻哥哥:[onTransformUpdated]:在更新了根转换之后,将触发。)
++++[onTransformChanged]: After the root transform has been changed this will fire(moved/rotated).(立钻哥哥:[onTransformChanged]:根变换更改后,将触发(移动/旋转)。)
++++[onConnectedChanged]: Whenever a device is connected or disconnected from this action.(立钻哥哥:[onConnectedChanged]:每当设备连接或断开此操作时。)
++++[onTrackingChanged]: Executes whenever the state of the tracking for this device changes.(立钻哥哥:[onTrackingChanged]:每当该设备的跟踪状态发生变化时执行。)
##A.5、Interaction System |
++A.5、Interaction System
++++立钻哥哥:After “Valve” released “The Lab” we took the learning form that project and created an “Interaction System” that others could use in their own projects. This system has been updated since then to use “SteamVR Input” and the new “SteamVR Skeleton Input” systems. This system can serve as an example of how to use the these new systems. It includes the following examples: (立钻哥哥:在“Valve”发布了“The Lab”之后,我们采用了该项目的学习形式,并创建了一个“交互系统”,其他人可以在他们自己的项目中使用。从那时起,该系统已经更新为使用“SteamVR输入”和新的“SteamVR骨架输入”系统。这个系统可以作为如何使用这些新系统的一个例子。它包括以下例子:)
++++[Interaction with Unity UI elements]: 与Unity UI元素的交互;
++++[Pickup, Drop, and Throw]: 拾起,放下,扔出去;
++++[Multiple variations on throwing velocities]: 投掷速度的多种变化;
++++[Bow and Arrow]: 弓箭;
++++[Wheel interactions]: 轮交互;
++++[Proximity button]: 邻近按钮;
++++[Variety of Skeleton Input example]: 各种骨架输入示例;
++++[Teleporting]: 传送;
++++[Using held objects]: 使用抓握对象;
++++[Using Skeleton Input to from a hand around a held object]: 使用手持物体的手的骨架输入;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++https://valvesoftware.github.io/steamvr_unity_plugin/articles/Interaction-System.html
++Interaction System form The Lab
++++立钻哥哥:The “Interaction System” is a series of scripts, prefabs and other assets that were the basis of all the minigames and other scenes in “The Lab”. This system was initially designed to be designed to be lightweight and flexible so that it could support all the experiments that we were working on at the time. Since then it has been updated to be an example of the new features we’ve added to “SteamVR”. Including “SteamVR Input”(actions/action sets) and “Skeleton Input(hands)”. Hopefully it can serve as a good starting point for your own experiments and help you in developing your projects.(立钻哥哥:交互系统”是一系列脚本、预制件和其他资源,是《实验室》中所有迷你游戏和其他场景的基础。这个系统最初被设计成轻量级和灵活的,这样它就可以支持我们当时正在进行的所有实验。从那时起,它被更新为我们添加到“SteamVR”的新功能的一个例子。包括“SteamVR输入”(动作/动作集)和“骨架输入(手)”。希望它能成为你自己实验的一个很好的起点,并帮助你开发你的项目。)
++Getting started(入门指南)
++++立钻哥哥:With these basic building blocks you can then go on and create some fairly complex objects. For some examples take a look at the “Interactions_Example” scene in “Assets/SteamVR/InteractionSystem/Samples/Scenes”.(立钻哥哥:使用这些基本的构建块,您可以继续创建一些相当复杂的对象。要获得一些示例,请查看“Assets/SteamVR/InteractionSystem/Samples/Scenes”中的“Interactions_Example”场景。)
++++[1、Create a new scene]: 新建场景;
++++[2、Delete the “Main Camera” object]: 删除“主摄像机”对象;
++++[3、Drag in the “Player” prefab from Core/Prefabs into your scene. This prefab sets up the main Player component and the hands. It also hooks into all the relevant “SteamVR Input” actions needed.]: 将“Player”预置从Core/Prefabs拖到场景中。这个预置设置了主要的播放器组件和指针。它还挂钩到所有相关的“SteamVR输入”行动需要;
++++[4、You should be able to see the scene in the headset now along with your controllers being tracked in the scene.]: 您现在应该可以看到头盔中的场景,以及您的控制器在场景中被跟踪。
++++[5、If you have controllers that support “Skeleton Input” you’ll also see hands that touch and press the buttons on your controllers.]: 如果你有支持“骨架输入”的控制器,你还会看到双手触摸并按下控制器上的按钮。
++++[6、Add the “Interactable” component to any object in the scene. All the other components on this object will then start receiving relevant messages from the player’s hands.(Look at Samples/Scripts/InteractableExample.cs for example usage)]: 将“Interactable”组件添加到场景中的任何对象中。该对象上的所有其他组件将开始从玩家手中接收相关消息。(查看示例/脚本/InteractableExample.cs示例用法)
++++[7、We have included a few commonly used interactable classes such as the Throwable. Adding this component to your object will allow it to be picked up and thrown by the player.]: 我们已经包含了一些常用的可交互类,比如Throwable。将此组件添加到对象中,将允许玩家拾取并抛出该物体。
++++[8、You can then add the “Skeleton Poser” component to a GameObject with an “Interactable” and pose how you want the hand to look when interacting with it.]: 然后你可以将“Skeleton Poser”组件添加到带有“Interactable”的GameObject(游戏物体)中,并在与之交互时摆出你想要的手的样子。
++++[9、To add teleporting to your scene drag in the Teleporting prefab from Teleport/Prefabs into your scene. This will set up all the teleport logic.]:要将传送到场景中,请将传送预制块从传送口/预制块拖拽到场景中。这将设置所有的传送逻辑。
++++[10、Drag in some TeleportPoint prefabs from Teleport/Prefabs to add locations that the player can teleport to.]: 从Teleport/ prefabs中拖入一些TeleportPoint prefabs,添加玩家可以传送到的位置.
++++[11、You can also add the TeleportArea component to any object in your scene. This will allow the player to teleport anywhere along the collider for that object.]: 您还可以将TeleportArea组件添加到场景中的任何对象。这将允许玩家在碰撞体的任何地方传送该物体。
++++\Assets\SteamVR\InteractionSystem\Samples\Scripts\InteractableExample.cs
//Purpose: Demonstrates how to create a simple interactable object(立钻哥哥:目的:展示了如何创建一个简单的interactable对象)
using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem.Sample{ [RequireComponent(typeof(Interactable))] public class InteractableExample : MonoBehaviour{ private TextMesh generalText; private TextMesh hoveringText; private Vector3 oldPosition; private Quaternion oldRotation;
private float attachTime;
private Interactable interactable;
void Awake(){}
//Called when a Hand starts hovering over this object.(立钻哥哥:当一只手开始悬停在该对象上时调用。) private void OnHandHoverBegin(Hand hand){}
//Called when a Hand stops hovering over this object.(立钻哥哥:当一只手停止悬停在该对象上时调用.) private void OnHandHoverEnd(Hand hand){}
//Called every Update() while a Hand is hovering over this object.(立钻哥哥:当一只手悬停在此对象上时调用每个Update()) private void HandHoverUpdate(Hand hand){}
//Called when this GameObject becomes attached to the hand.(立钻哥哥:当GameObject(游戏物体)与手相连时调用.) private void OnAttachedToHand(Hand hand){}
//Called when this GameObject is detached from the hand.(立钻哥哥:当GameObject(游戏物体)与手分离时调用.) private void OnDetachedFromHand(Hand hand){}
//Called every Update() while this GameObject is attached to the hand.(立钻哥哥:调用每个Update(),而这个GameObject则被附加到指针上.) private void HandAttachedUpdate(Hand hand){}
private bool lastHovering = false; private void Update(){}
//Called when this attached GameObject becomes the primary attached object.(立钻哥哥:当这个附属游戏对象成为主要附属对象时调用) private void OnHandFocusAcquired(Hand hand){}
//Called when another attached GameObject becomes the primary attached object.(立钻哥哥:当另一个附加游戏对象成为主要附加对象时调用.) private void OnHandFocusLost(Hand hand){}
} //立钻哥哥:public class InteractableExample:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem.Sample{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Interactable.cs
//Purpose: This object will get hover events and can be attached to the hands.(立钻哥哥:用途:此对象将获得悬停事件,并可以附加到指针上)
using UnityEngine; using UnityEngine.Events; using System.Collections; using System.Collections.Generic;
namespace Valve.VR.InteractionSystem{ public class Interactable : MonoBehaviour{ [Tooltip(“Activates an action set on attach and deactivates on detach.(立钻哥哥:在连接时激活一个动作集,在分离时禁用该动作集.)”)] public SteamVR_ActionSet activateActionSetOnAttach;
[Tooltip(“Hide the whole hand on attachment and show on detach.(立钻哥哥:在连接时隐藏整个手,在分离时显示.)”)] public bool hideHandOnAttach = true;
[Tooltip(“Hide the skeleton part of the hand on attachment and show on detach.(立钻哥哥:将手的骨骼部分隐藏在附件中,并在分离时显示出来.)”)] public bool hideSkeletonOnAttach = false;
[Tooltip(“The integer in the animator to trigger on pickup. 0 for none.(立钻哥哥:)”)] public int handAnimationOnPickup = 0;
[Tooltip(“The range of motion of set on the skeleton. None for no change.(立钻哥哥:骨架的运动范围。没有任何改变.)”)] public SkeletalMotionRangeChange setRangeOfMotionOnPickup = SkeletalMotionRangeChange.None;
public delegate void OnAttachedToHandDelegate(Hand hand); public delegate void OnDetachedFromHandDelegate(Hand hand);
public event OnAttachedToHandDelegate onAttachedToHand; public event OnDetachedFromHandDelegate onDetachedFromHand;
[Tooltip(“Specify whether you want to snap to the hand’s object attachment point, or just the raw hand.(立钻哥哥:)”)] public bool useHandObjectAttachmentPoint = true;
//The skeleton pose to apply when grabbing. Can only set this or handFollowTransform.(立钻哥哥:抓取时的骨架姿势。只能设置此或handFollowTransform) [HideInInspector] public SteamVR_Skeleton_Poser skeletonPoser;
[Tooltip(“Should the rendered hand lock on to and follow the object.(立钻哥哥:呈现的手应该锁定并跟随对象)”)] public bool handFollowTransform = true;
[Tooltip(“Set whether or not you want this interactible to highlight when hovering over it.(立钻哥哥:设置是否要在悬停时突出显示此可交互项.)”)] public bool highlightOnHover = true; protected MeshRenderer[] highlightRenderers; protected MeshRenderer[] existingRenderers; protected GameObject highlightHolder; protected SkinnedMeshRenderer[] highlightSkinnedRenderers; protected SkinnedMeshRenderer[] existingSkinnedRenderers; protected static Material highlightMat;
[Tooltip(“An array of child gameObjects to not render a highlight for. Things like transparent parts, vfx, etc.”)] public GameObject[] hideHighlight;
[System.NonSerialized] public Hand attachedToHand;
[System.NonSerialized] public Hand hoveringHand;
public bool isDestroying{} public bool isHovering{} public bool wasHovering{}
private void Awake(){} protected virtual void Start(){} protected virtual bool ShouldIgnoreHighlight(Componet component){} protected virtual bool ShouldIgnore(GameObject check){} protected virtual void CreateHighlightRenderers(){} protected virtual void UpdateHighlightRenderers(){}
//Called when a Hand starts hovering over this object.(立钻哥哥:当一只手开始悬停在该对象上时调用.) protected virtual void OnHandHoverBegin(Hand hand){}
//Called when a Hand stops hovering over this object.(立钻哥哥:当一只手停止悬停在该对象上时调用.) private void OnHandHoverEnd(Hand hand){}
protected virtual void Update(){}
protected float blendToPoseTime = 0.1f; protected float releasePoseBlendTime = 0.2f;
protected virtual void OnAttachedToHand(Hand hand){} protected virtual void OnDetachedFromHand(Hand hand){} protected virtual void OnDestroy(){} protected virtual void OnDisable(){}
} //立钻哥哥:public class Interactable:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Throwable.cs
//Purpose: Basic throwable object.(立钻哥哥:用途:基本抛掷物)
using UnityEngine; using UnityEngine.Events; using System.Collections;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] [RequireComponent(typeof(Rigidbody))] [RequireComponent(typeof(VelocityEstimator))] public class Throwable : MonoBehaviour{ [EnumFlags] [Tooltip(“The flags used to attach this object to the end.(立钻哥哥:用于将此对象附加到末尾的标志.)”)] public Hand.AttachmentFlags attachmentFlags = Hand.AttachmentFlags.ParentToHand | Hand.AttachmentFlags.DetachFromOtherHand | Hand.AttachmentFlags.TurnOnKinematic;
[Tooltip(“The local point which acts as a positional and rotational offset to use while held.(立钻哥哥:局部点,在保持时起位置偏移和旋转偏移的作用.)”)] public Transform attachmentOffset;
[Tooltip(“How fast must this object be moving to attach due to a trigger hold instead of a trigger hold instead of a trigger press?(-1 to disable)(立钻哥哥:由于触发器保持而不是触发器按下,该对象移动到附着时的速度必须有多快?(1禁用))”)] public float catchingSpeedThreshold = -1;
public ReleaseStyle releaseVelocityStyle = ReleaseStyle.GetFromHand;
[Tooltip(“The time offset used when releasing the object with the RawFromHand option.(立钻哥哥:使用RawFromHand选项释放对象时使用的时间偏移量.)”)] public float releaseVelocityTimeOffset = -0.011f;
public float scaleReleaseVelocity = 1.1f;
[Tooltip(“When detaching the object, should it return to its original parent?(立钻哥哥:当分离对象时,它应该返回到原来的父对象吗?)”)] public bool restoreOriginalParent = false;
public UnityEvent onPickup; public UnityEvent onDetachFromHand; public UnityEvent<Hand> onHeldUpdate;
protected RigidbodyInterpolation hadInterpolation = RigidbodyInterpolation.None; protected new Rigidbody rigidbody;
[HideInInspector] public Interactable interactable;
protected virtual void Awake(){} protected virtual void OnHandHoverBegin(Hand hand){} protected virtual void OnHandHoverEnd(Hand hand){} protected virtual void HandHoverUpdate(Hand hand){} protected virtual void OnAttachedToHand(Hand hand){} protected virtual void OnDetachedFromHand(Hand hand){}
public virtual void GetReleaseVelocities(Hand hand, out Vector3 velocity, out Vector3 angularVelocity){}
protected virtual void HandAttachedUpdate(Hand hand){} protected virtual IEnumerator LateDetach(Hand hand){} protected virtual void OnHandFocusAcquired(Hand hand){} protected virtual void OnHandFocusLost(Hand hand){}
} //立钻哥哥:public class Throwable:MonoBehaviour{}
public enum ReleaseStyle{ NoChange, GetFromHand, ShortEstimation, AdvancedEstimation, } //立钻哥哥:public enum ReleaseStyle{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\Input\SteamVR_Skeleton_Poser.cs
using System; using System.Collections; using UnityEngine; using Valve.VR; using System.Collections.Generic; using System.Linq;
namespace Valve.VR{ public class SteamVR_Skeleton_Pose : MonoBehaviour{ #region Editor Storage public bool poseEditorExpanded = true; public bool blendEditorExpanded = true; public string[] poseNames; #endregion
public GameObject previewLeftHandPrefab; public GameObject previewRightHandPrefab;
public SteamVR_Skeleton_Pose skeletonMainPose; public List<SteamVR_Skeleton_Pose> skeletonAdditionalPose = new List<SteamVR_Skeleton_Pose>();
[SerializeField] protected bool showLeftPreview = false; protected bool showRightPreview = true; protected GameObject previewLeftInstance; protected GameObject previewRightInstance; protected int previewPoseSelection = 0;
public int blendPoseCount{}; public List<PoseBlendingBehaviour> blendingBehaviours = new List<PoseBlendingBehaviour>(); public SteamVR_Skeleton_PoseSnapshot blendedSnapshotL; public SteamVR_Skeleton_PoseSnapshot blendedSnapshotR; private SkeletonBlendablePose[] blendPoses; private int boneCount; private bool poseUpdatedThisFrame; public float scale;
protected void Awake(){}
//Set the blending value of a blendingBehaviour. Works best on Manual type behavioiurs.(立钻哥哥:设置混合行为的混合值。最适用于手动类型的行为.) public void SetBlendingBehaviourValue(string behaviourName, float value){}
//Get the blending value of a blendingBehaviour.(立钻哥哥:获取混合行为的混合值.) public float GetBlendingBehaviourValue(string behaviourName){}
//Enable or disable a blending behaviour.(立钻哥哥:启用或禁用混合行为.) public void SetBlendingBehaviourEnabled(string behaviourName, bool value){}
//Check if a blending behaviour is enabled.(立钻哥哥:检查是否启用了混合行为.) public bool GetBlendingBehaviourEnabled(string behaviourName){}
//Get a blending behaviour by name.(立钻哥哥:通过名称获得混合行为.) public PoseBlendingBehaviour GetBlendingBehaviour(string behaviourName){}
public SteamVR_Skeleton_Pose GetPoseByIndex(int index){} private SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Sources inputSource){}
//Retrieve the final animated pose, to be applied to a hand skeleton.(立钻哥哥:检索要应用于手部骨骼的最终动画姿势.) public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources handType){} public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Behaviour_Skeleton skeletonBehaviour){}
//Updates all pose animation and blending. Can be called from different places without performance concerns, as it will only let itself run once per frame.(立钻哥哥:更新所有的姿态动画和混合。可以从不同的地方调用,而不需要考虑性能问题,因为它只允许自己在每帧中运行一次.) public void UpdatePose(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource){}
protected void ApplyBlenderBehaviours(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource, SteamVR_Skeleton_PoseSnapshot snapshot){}
protected void LateUpdate(){}
//Wighted average of n vector3s.(立钻哥哥:平均n个向量.) protected Vector3 BlendVectors(Vector3[] vectors, float[] weights){}
//Weighted average of n quaternions.(立钻哥哥:n个四元数的加权平均.) protected Quaternion BlendQuaternions(Quaternion[] quaternions, float[] weights){}
//A SkeletonBlendablePose holds a reference to a Skeleton_Pose scriptableObject, and also contains some helper functions.(立钻哥哥:SkeletonBlendablePose持有对Skeleton_Pose脚本对象的引用,并且还包含一些帮助函数.) //Also handles pose-specific animation like additive finger motion.(立钻哥哥:还处理特定位置的动画,如添加手指运动.) public class SkeletonBlendablePose{ public SteamVR_Skeleton_Pose pose; public SteamVR_Skeleton_PoseSnapshot snapshotR; public SteamVR_Skeleton_PoseSnapshot snapshotL;
//Get the snapshot of this pose with effects such as additive finger animation applied.(立钻哥哥:使用添加手指动画等效果获取此姿态的快照.) public SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Soures inputSource){}
public void UpdateAdditiveAnimation(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource){}
//Init based on an existing Skeleton_Pose.(立钻哥哥:初始化基于一个现有的骨架姿态.) public SkeletonBlendablePose(SteamVR_Skeleton_Pose p){}
//Copy the base pose into the snapshots.(立钻哥哥:将基本姿势复制到快照中.) public void PoseToSnapshots(){}
public SkeletonBlendablePose(){}
} //立钻哥哥:public class SkeletonBlendablePose{}
//A filter applied to the base pose. Blends to a secondary pose by a certain weight. Can be masked per-finger.(立钻哥哥:用于基本位姿的滤波器。通过一定的重量调整到第二个姿势。每个手指都可以蒙面.) [System.Serializable] public class PoseBlendingBehaviour{ public string name; public bool enabled = true; public float influence = 1; public int pose = 1; public float value = 0; public SteamVR_Action_Single action_single; public SteamVR_Action_Boolean action_bool; public float smoothingSpeed = 0; public BlenderTypes type; public bool useMask; public SteamVR_Skeleton_HandMask mask = new SteamVR_Skeleton_HandMask(); public bool previewEnabled;
//Performs smoothing based on deltaTime parameter.(立钻哥哥:基于deltaTime参数执行平滑.) public void Update(float deltaTime, SteamVR_Input_Sources inputSource){}
//Apply blending to this behaviour’s pose to an existing snapshot.(立钻哥哥:将混合应用于此行为的姿态到现有快照.) public void ApplyBlending(SteamVR_Skeleton_PoseSnapshot snapshot, SkeletonBlendablePose[] blendPoses, SteamVR_Input_Sources inputSource){}
public PoseBlendingBehaviour(){}
public enum BlenderTypes{ Manual, AnalogAction, BooleanAction } //立钻哥哥:public enum BlenderTypes{}
} //立钻哥哥:public class PoseBlendingBehaviour{}
//PoseSnapshots hold a skeleton pose for one hand, as well as storing which hand they contain. They have several functions for combining BlendablePoses.(立钻哥哥:PoseSnapshots为一只手保留一个骨架的姿势,同时也保存了它们包含哪只手。他们有几个功能,以结合可调和的姿势。) public class SteamVR_Skeleton_PoseSnapshot{ public SteamVR_Input_Sources inputSource; public Vector3 position; public Quaternion rotation; public Vector3[] bonePositions; public Quaternion[] boneRotations;
public SteamVR_Skeleton_PoseSnapshot(int boneCount, SteamVR_Input_Sources source){}
//Perform a deep copy from one poseSnapshot to another.(立钻哥哥:执行从一个位置到另一个位置的深度复制.) public void CopyFrom(SteamVR_Skeleton_PoseSnapshot source){}
} //立钻哥哥:public class SteamVR_Skeleton_PoseSnapshot{} } //立钻哥哥:public class SteamVR_Skeleton_Pose:MonoBehaviour{}
//Simple mask for fingers.(立钻哥哥:简单的手指遮罩。) [System.Serializable] public class SteamVR_Skeleton_HandMask{ public bool palm; public bool thumb; public bool index; public bool middle; public bool ring; public bool pinky; public bool[] values = new bool[6];
public bool SetFinger(int i, bool value){} public bool GetFinger(int i){} public SteamVR_Skeleton_HandMask(){}
//All elements on.(立钻哥哥:所有的元素。) public void Reset(){}
protected void Apply(){}
public static readonly SteamVR_Skeleton_HandMask fullMask = new SteamVR_Skeleton_HandMask();
} //立钻哥哥:public class SteamVR_Skeleton_HandMask{}
} //立钻哥哥:namespace Valve.VR{} |
++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\Teleport.cs
//Purpose: Handles all the teleport logic.(立钻哥哥:用途:处理所有的传送逻辑.)
using UnityEngine; using UnityEngine.Events; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class Teleport : MonoBehaviour{ public SteamVR_Action_Boolean teleportAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>(“Teleport”);
public LayerMask traceLayerMask; public LayerMask floorFixupTraceLayerMask;
private Coroutine hintCoroutine = null;
SteamVR_Events.Action chaperoneInfoInitializedAction;
//Events public static SteamVR_Events.Event<float> ChangeScene = new SteamVR_Events.Event<float>(); public static SteamVR_Events.Action<float> ChangeSceneAction(UnityAction<float> action){}
public static SteamVR_Events.Event<TeleportMarkerBase> Player = new SteamVR_Events.Event<TeleportMakerBase>(); public static SteamVR_Events.Action<TeleportMakerBase> PlayerAction(UnityAction<TeleportMarkerBase> action){}
public static SteamVR_Events.Event<TeleportMarkerBase> PlayerPre = new SteamVR_Events.Event<TeleportMakerBase>(); public static SteamVR_Events.Action<TeleportMarkerBase> PlayerPreAction(UnityAction<TeleportMarkerBase> action){}
private static Teleport _instance; public static Teleport instance{}
void Awake(){} void Start(){} void OnEnable(){} void OnDisable(){}
private void CheckForSpawnPoint(){} public void HideTeleportPointer(){}
void Update(){}
private void UpdatePointer(){}
void FixedUpdate(){}
private void OnChaperoneInfoInitialized(){}
private void HidePointer(){} private void ShowPointer(Hand newPointerHand, Hand oldPointerHand){}
private void UpdateTeleportColors(){}
private void PlayAudioClip(AudioSource source, AudioClip clip){ source.clip = clip; source.Play(); }
private void PlayPointerHaptic(bool validLocation){} private void TryTeleportPlayer(){} private void InitiateTeleportFade(){} private void TeleportPlayer(){} private void HighlightSelected(TeleportMarkerBase hitTeleportMarker){}
public void ShowTeleportHint(){} public void CancelTeleportHint(){}
private IEnumerator TeleportHintCoroutine(){}
public bool IsEligibleForTeleport(Hand hand){}
private bool ShouldOverrideHoverLock(){} private bool WasTeleportButtonReleased(Hand hand){} private bool IsTeleportButtonDown(Hand hand){} private bool WasTeleportButtonPressed(Hand hand){} private Transform GetPointerStartTransform(Hand hand){}
} //立钻哥哥:public class Teleport:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportPoint.cs
//Purpose: Single location that the player can teleport to.(立钻哥哥:用途:单一的位置,玩家可以传送到.)
using UnityEngine; using UnityEngine.UI; #if UNITY_EDITOR using UnityEditor; #endif
namespace Valve.VR.InteractionSystem{ public class TeleportPoint : TeleportMarkerBase{ public enum TeleportPointType{ MoveToLocation, SwitchToNewScene };
//Public variables public TeleportPointType teleportType = TeleportPointType.MoveToLocation; public string title; public string switchToScene;
//Private data private bool gotReleventComponents = false; private MeshRenderer markerMesh; private MeshRenderer switchSceneIcon; private MeshRenderer moveLocationIcon;
//Constants private const string switchSceneAnimation = “switch_scenes_idle”; private const string moveLocationAnimation = “move_location_idle”; private const string lockedAnimation = “locked_idle”;
public override bool showReticle{}
void Awake(){} void Start(){} void Update(){}
public override bool ShouldActivate(Vector3 playerPosition){} public override bool ShouldMovePlayer(){} public override void Highlight(bool highlight){} public override void UpdateVisuals(){} public override void SetAlpha(float tintAlpha, float alphaPercent){}
public void SetMeshMaterials(Material material, Color textColor){} public void TeleportToScene(){} public void GetRelevantComponents(){} public void ReleaseRelevantComponents(){} public void UpdateVisualsInEditor(){}
} //立钻哥哥:public class TeleportPoint:TeleportMarkerBase{}
#if UNITY_EDITOR [CustomEditor(typeof(TeleportPoint))] public class TeleportPointEditor : Editor{ void OnEnable(){} public override void OnInspectorGUI(){} } //立钻哥哥:public class TeleportPointEditor:Editor{} #endif
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportArea.cs
//Purpose: An area that the player can teleport to.(立钻哥哥:用途:玩家可以传送到的区域.)
using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif
namespce Valve.VR.InteractionSystem{ public class TeleportArea : TeleportMarkerBase{ //Public properties public Bounds meshBounds{}
//Private data private MeshRenderer areaMesh; private int tintColorId = 0; private Color visibleTintColor = Color.clear; private Color highlightedTintColor = Color.clear; private Color lockedTintColor = Color.clear; private bool highlighted = false;
public void Awake(){} public void Start(){}
public override bool ShouldActivate(Vector3 playerPosition){} public override bool ShouldMovePlayer(){} public override void Highlight(bool highlight){} public override void SetAlpha(float tintAlpha, float alphaPercent){} public override void UpdateVisuals(){}
public void UpdateVisualsInEditor(){} private bool CalculateBounds(){}
} //立钻哥哥:public class TeleportArea:TeleportMarkerBase{}
#if UNITY_EDITOR [CustomEditor(typeof(TeleportArea))] public class TeleportAreaEditor : Editor{ void OnEnable(){} public override void OnInspectorGUI(){} } //立钻哥哥:public class TeleportAreaEditor:Editor{} #endif
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++Sample Scene(示例场景)
++++立钻哥哥:The sample scene Interactions_Example in the “Samples/Scenes” folder includes all of the major components and is a good place to familiarize yourself with the system. The scene contains the following elements:(立钻哥哥:“Samples/Scenes”文件夹中的示例场景 Interactions_Example包含所有主要组件,是熟悉系统的好地方。场景包含以下元素:)
++++[Player]: The Player prefab is at the core of the entire system. Most of the other components depend on the player to be present in the scene.(立钻哥哥:【玩家】:玩家预置是整个系统的核心。其他大部分组件都依赖于玩家出现在场景中.)
++++[Teleporting]: The Teleporting prefab handles all the teleporting logic for the system.(立钻哥哥:【传送】:传送预置处理系统的所有传送逻辑)
++++[Interactable Example]: This shows a very simple interactable that shows the basic aspects of receiving message from the hands and reacting to them.(立钻哥哥:【交互示例】:这显示了一个非常简单的Interactable,它显示了从手接收消息并对其作出反应的基本方面。)
++++[Throwables]: These show how to use the interaction system to create a variety of different types of throwable objects. Read the descriptions next to each table for more information.(立钻哥哥:[Throwables]:展示如何使用交互系统创建各种不同类型的可投掷对象。阅读每个表旁边的描述以获得更多信息。)
++++[Skeleton]: There’s a few different examples of hand models along with options for what extents the skeleton goes to.(立钻哥哥:[骨骼]:有几个不同的手模型的例子,以及选择什么程度的骨骼模型;)
++++[Proximity Button]: A common task is needing to hit a button. Physical buttons are more satisfying to use than flat interface but physical interaction systems can get complex fast. Without going too deep into that we’ve including a button that can be depressed just by being close to a controller.(立钻哥哥:[接近按钮]:一个常见的任务是需要点击一个按钮。使用物理按钮比使用平面界面更令人满意,但物理交互系统可能很快变得复杂。在不太深入的情况下,我们已经包含了一个按钮,只要靠近控制器就可以被按下。)
++++[Interesting Interactables]: These are slightly more complex examples of using the “Skeleton Poser” system along with Throwables. With the grenades you get two different poses depending on how you pick them up. The Happy Ball moves in your hand with a squeeze and the Squeezable, well, squeezes.(立钻哥哥:【有趣的交互性】:这些是使用“骨架Poser”系统和可投掷物的稍微复杂的例子。用手榴弹,你可以得到两个不同的姿势,这取决于你如何拿起它们。快乐球在你的手中移动,挤压,可挤压的,摁,挤压。)
++++[UI & Hints]: This shows how hints are handled in the interaction system and how it can be used to interact with Unity UI widgets like buttons.(立钻哥哥:[UI & hint]:这显示了如何在交互系统中处理提示,以及如何使用它与Unity UI小部件(如按钮)交互。)
++++[LinearDrive]: This is a slightly more complex interactable that combines a few different pieces to create an animated object that can be controlled by simple interactions.(立钻哥哥:线性驱动器:这是一个稍微复杂的交互性表,它结合了几个不同的部分来创建一个动画对象,可以通过简单的交互进行控制。)
++++[CircularDrive]: This shows how interactions can be constrained and mapped differently to cause more complex motions.(立钻哥哥:[循环驱动]:这展示了如何对交互进行约束并以不同的方式映射,从而导致更复杂的运动。)
++++[Longbow]: This was the actual Longbow used in The Lab. It’s now been updated with the “Input System” and “Skeleton Poser”. It is one of the more complex objects that we’ve created using this system and shows how simple pieces can be combined to create an entire game mechanic. Going over the different objects in this sample scene should give you a good idea of the breadth of the interaction system and how to combine its different parts to create complex game objects.(立钻哥哥:【长弓】:这是实验室实际使用的长弓,现在已经更新为“输入系统”和“骨架姿态”。它是我们使用该系统创建的较为复杂的对象之一,并展示了如何将简单的部件组合起来创建完整的游戏机制。在这个示例场景中浏览不同的对象可以让您很好地了解交互系统的宽度,以及如何将其不同部分组合起来创建复杂的游戏对象。)
++Documentation(技术资料)
++++立钻哥哥:Now we’ll go a little more in depth into some of the basic components included in the interaction system. The system is broken up into a few different part: (立钻哥哥:现在我们将更深入地讨论交互系统中包含的一些基本组件。该系统分为几个不同的部分:)
++++[Core]: A the core of the interaction system are the “Player”, “Hand” and “Interactable classes”. The provided Player prefab sets up the player object and the “SteamVR” camera for the scene.(立钻哥哥:【Core】:交互系统的核心是“Player”、“Hand”和“Interactable classes”。所提供的Player预置设置了Player对象和场景的“SteamVR”摄像机。)
----The interaction system works by sending messages to any object that the hands interact with. These objects then react to the message and can attach themselves to the hands if wanted.(立钻哥哥:交互系统的工作原理是将消息发送到与手交互的任何对象。然后,这些对象对消息作出反应,如果需要,可以将自己附加到手上.)
----To make any object receive message from the hands just add the Interactable component to that object. This object will then be considered when the hand does its hovering checks.(立钻哥哥:要使任何对象从手接收消息,只需将Interactable组件添加到该对象。当手进行悬停检查时,将考虑该对象。)
----We have also included a few commonly used interactables such as the “Throwable” or the “LinearDrive”.(立钻哥哥:我们还包括了一些常用的交互,如“Throwable”或“LinearDrive”.)
----The “Player” prefab also creates an “InputModule” which allows the hands to mimic mouse events to easily work with “Unity UI widgets”.(立钻哥哥:“Player”预置还创建了一个“InputModule”,允许双手模拟鼠标事件,以便轻松地使用“Unity UI widgets”。)
----The interaction system also includes a fallback mode which allows for typical first-person camera controls using the keyboard and mouse. This also allows the mouse to act like one of the player’s hands. This mode is particularly useful when not everyone on the team has access to “VR” headset.(立钻哥哥:交互系统还包括一个后退模式,允许使用键盘和鼠标进行典型的第一人称相机控制。这也允许鼠标像玩家的一只手一样工作。当团队中并非所有人都能使用“VR”头盔时,这种模式尤其有用。)
++[Player]
++++立钻哥哥:The Player class acts like a singleton which means there should only be one Player object in the scene.(立钻哥哥:Player类就像一个单例对象,这意味着场景中应该只有一个Player对象。)
++++The player itself doesn’t do much except for keep track of the hands and the hmd.(立钻哥哥:除了跟踪手和hmd,Player本身并没有做什么.)
++++It can be accessed globally throughout the project and many aspects of the interaction system assume that the “Player” object always exists in the scene.(立钻哥哥:它可以在整个项目中全局访问,交互系统的许多方面都假设“Player”对象始终存在于场景中。)
++++It also keeps track of whether you are in VR mode or 2D fallback mode.(立钻哥哥:它还可以跟踪你是在VR模式还是2D后退模式)
++++Using the accessors through the “Player” class allows the other components to function similarly without knowing if the VR headset or mouse/keyboard is being used.(立钻哥哥:通过“Player”类使用访问器可以让其他组件在不知道是否使用VR头盔或鼠标/键盘的情况下进行类似的操作.)
++++The 2D fallback mode is useful but has its limitations. We mainly used this mode for testing out very simple interactions that only required 1 hand and the trigger button. It was mainly useful during development when not everyone on the team had a VR headset on controllers with them at all times.(立钻哥哥:2D回退模式很有用,但也有其局限性。我们主要使用这种模式来测试非常简单的交互,只需要一只手和触发按钮。这在开发过程中非常有用,因为团队中并不是每个人都随身携带VR头盔.)
++++The Player also includes a few useful properties:(立钻哥哥:玩家还包括一些有用的属性:)
----[hmdTransform]: This will always return the transform of the current camera. This could be the VR headset or the 2D fallback camera.(立钻哥哥:hmdTransform:它总是返回当前相机的变换。这可能是VR头盔或2D后置摄像头.)
----[feetPositionGuess]: This guesses the position of the player’s feet based on the where the hmd is. Since we don’t actually know the position of their feet, this can be pretty inaccurate depending on how the player is standing.(立钻哥哥:feetPositionGuess:根据hmd的位置猜测玩家的脚的位置。因为我们实际上并不知道他们的脚的位置,这可能是非常不准确的,这取决于球员是如何站着的)
----[bodyDirectionGuess]: This is similar to the “feetPositionGuess” in that it can be inaccurate depending on how the player is standing.(立钻哥哥:bodyDirectionGuess:这类似于“feetPositionGuess”,因为它可能是不准确的,这取决于玩家是如何站着的。)
++++Note: The player class is set up to use icons to show the feet and hands in the editor scene view but due to the way Unity works these icons have to be located in a specific folder to work. These icons are provided under “Core/Icons”. Move them to a folder named “Gizoms” in the root of your projects “Asset” tree and they should work.(立钻哥哥:注意:player类设置为使用图标在编辑器场景视图中显示手脚,但由于Unity的工作方式,这些图标必须位于特定的文件夹中才能工作。这些图标在“Core/ icons”下提供。将它们移到项目“资产”树的根目录中名为“Gizoms”的文件夹中,它们应该可以工作。)
++++The 2D fallback mode can be useful during testing but it’s probably not something that you want to ship with your finished game. There are 2 ways to disable it:(立钻哥哥:2D回退模式在测试过程中非常有用,但它可能并不是你想要在完成游戏后发行的东西。有两种方法可以禁用它:)
----Uncheck the “Allow Toggle To 2D” bool on the player object in your scene before making your build.(立钻哥哥:在生成之前,取消场景中Player对象上的“允许切换到2D”选项)
----Add “HIDE_DEBUG_UI” to the list of “Scripting Define Symbols” in your project’s “PlayerSettings”. This will only disable the 2D debug view in builds of your game while allowing you to keep using it in the editor.(立钻哥哥:将“HIDE_DEBUG_UI”添加到项目“PlayerSettings”中的“脚本定义符号”列表中。这只会禁用游戏构建中的2D调试视图,同时允许您在编辑器中继续使用它.)
++Hand
++++立钻哥哥:The “Hand” class does most of the heavy lifting for the “interaction system”.(“Hand”类为“交互系统”做了大部分繁重的工作。)
++++The Hand checks for objects(Interactables) that it is hovering over and sends them messages based on the current hover state.(立钻哥哥:Hand检查它所悬停的对象(Interactables),并根据当前悬停状态向它们发送消息.)
++++The hand can only hover on 1 object at a time and only 1 hand can hover on an object at the same time.(立钻哥哥:一只手一次只能悬停在一个物体上,同时也只能悬停在一个物体上.)
++++Objects can be attached to and detached from the Hand. Only one object can be the object in focus of the hand but multiple objects can be attached to the hand at the same time.(立钻哥哥:物体可以附着在手上,也可以从手上分离出来。只有一个对象可以是手的焦点对象,但同时可以将多个对象附加到手.)
++++Once an object is detached from the hand then the previous object attached to the hand(if it is still attached) becomes the object in focus on the hand.(立钻哥哥:一旦一个对象与手分离,那么与手相连的前一个对象(如果它仍然与手相连)就成为手的焦点对象.)
++++When nothing is attached to the hand it will always show the controller.(立钻哥哥:当没有任何东西附着在手上时,它总是会显示控制器.)
++++The attached object can set AttachmentFlags that determine the behaviour of the hand and the object once it has been attached.(立钻哥哥:所附加的对象可以设置AttachmentFlags,该标记确定手和对象在被附加后的行为.)
++++The hand can be locked form hovering over other objects or any object depending on the situation.(立钻哥哥:根据不同的情况,可以将手锁定在悬停在其他物体或任何物体上.)
++++These are the message the hand sends to objects that it is interacting with: (立钻哥哥:这些是手发送给它正在与之交互的对象的消息:)
----[OnHandHoverBegin]: Sent when the hand first starts hovering over the object.(立钻哥哥:OnHandHoverBegin:当手第一次开始悬停在对象上时发送)
----[HandHoverUpdate]: Send every frame that the hand is hovering over the object.(立钻哥哥:HandHoverUpdate:发送手悬停在对象上的每一帧)
----[OnHandHoverEnd]: Sent when the hand stops hovering over the object.(立钻哥哥:OnHandHoverEnd:当手离开悬停在物体上时发送)
----[OnAttachedToHand]: Sent when the object gets attached to the hand.(立钻哥哥:OnAttachedToHand:当对象附加到hand时发送)
----[HandAttachedUpdate]: Sent every frame while the object is attached to the hand.(立钻哥哥:HandAttachedUpdate:当对象附在手上时,发送每一帧.)
----[OnDetachedFromHand]: Sent when the object gets detached from the hand.(立钻哥哥:OnDetachedFromHand:当对象脱离手时发送)
----[OnHandFocusLost]: Sent when an attached object loses focus because something else has been attached to the hand.(立钻哥哥:OnHandFocusLost:当一个附加对象因为其他对象被附加到手上而失去焦点时发送.)
----[OnHandFocusAcquired]: Send when an attached object gains focus because the previous focus object has been detached from the hand.(立钻哥哥:OnHandFocusAcquired:当一个附加对象获得焦点时发送,因为之前的焦点对象已经与手分离)
++++These are the message that the hand sends to its child objects:(立钻哥哥:这是手发送给它的子对象的消息:)
----[OnHandInitialized]: Sent when the hand first gets initialized by associating itself with the device ID of a “SteamVR” tracked controller.(立钻哥哥:OnHandInitialized:通过将自己与“SteamVR”跟踪控制器的设备ID相关联,首次初始化手时发送.)
----[OnParentHandHoverBegin]: Sent when the hand starts hovering over something.(立钻哥哥:OnParentHandHoverBegin:当手开始悬停在某物上时发送)
----[OnParentHandHoverEnd]: Sent when the hand stops hovering over something.(立钻哥哥:OnParentHandHoverEnd:当手离开悬停在某物上时发送)
----[OnParentHandInputFocusAcquired]: Sent when the game window gains input focus.(立钻哥哥:OnParentHandInputFocusAcquired:当游戏窗口获得输入焦点时发送)
----[OnParentHandInputFocusLost]: Send when the game window loses input focus.(立钻哥哥:OnParentHandInputFocusLost:当游戏窗口失去输入焦点时发送)
++++These members deal with attaching and detaching:(立钻哥哥:这些成员处理连接和分离:)
----[AttachObject]: Attaches the object from the hand using the passed in AttachmentFlags.(立钻哥哥:AttachObject:使用传递的AttachmentFlags从手上附加对象.)
----[DetachObject]: Detaches the object from the hand and optionally restores it to its original parent.(立钻哥哥:DetachObject:从手中分离对象,并可选地将其还原到其原始父对象)
----[currentAttachedObject]: This returns the in-focus attached object on the hand, if any.(立钻哥哥:currentAttachedObject:这将返回手上的in-focus附加对象(如果有的话).)
++++The Hand also has a few useful properties and functions that can be used to customize its behaviour:(立钻哥哥:手也有一些有用的属性和功能,可以用来定制其行为:)
----[OtherHand]: This is the other hand on the player. This can be useful for objects that need to interact with both hands such as the longbow.(立钻哥哥:另一只手:这是Player上的另一只手。这对于需要双手交互的对象(如长弓)非常有用)
----[HoverSphereTransform and Radius]: This can be used to customize the hover range of the hand.(立钻哥哥:HoverSphereTransform和Radius:可用于自定义手的悬停范围.)
----[HoverLayerMask]: This can be changed so that the hand only hovers over objects in certain layers.(立钻哥哥:HoverLayerMask:这可以改变,使手只悬停在某些层的对象上.)
----[HoverUpdateInterval]: The hovering check can be done more or less frequently depending on the requirements of your game.(立钻哥哥:HoverUpdateInterval:可以根据游戏的需求或多或少频繁地执行悬停检查.)
----[HoverLock/Unlock]: This is used to make the hand only hover over a certain object. Passing in null will make the hand not hover over anything while it is hover locked. This technique is used to make the hand not hover over objects while the teleport arc is active.(立钻哥哥:HoverLock/Unlock:这是用来让手只悬停在一个特定的物体上。传递null将使手在悬停锁定时不悬停在任何东西上。此技术用于使手在传送弧处于活动状态时不悬停在物体上.)
----[GetGrabStarting/GetGrabEnding]: These are used to determine if the boolean grab actions are being triggered at that time. There are two types of grabs-grip grab and pinch grab. These are generally associated with grip buttons and trigger buttons but serve special functions on the Knuckles controllers.(立钻哥哥:GetGrabStarting /GetGrabEnding:这些用于确定布尔抓取操作是否在那个时候被触发。抓握有两种类型-抓取和捏抓。这些通常与手柄按钮和触发器按钮相关联,但在Knuckles控制器上具有特殊功能)
----[GetAttachmentTransform]: Objects can use “attachment transforms” on the hand to figure out how to snap on to the hand. These are just named children of the “Hand” object. The “Player” prefab contains “Attach_ControllerTip” as an example.(立钻哥哥:GetAttachmentTransform:对象可以在手上使用“附件转换”来确定如何快速地抓住手。这些只是“Hand”对象的命名子对象。例如,“Player”预置包含“Attach_ControllerTip”.)
++Interactable(可交互的)
++++立钻哥哥:The Interactable class is more of an identifier. It identifies to the “Hand” that this object is interactable.(Interactable类更像是一个标识符。它向“手”标识该对象是可交互的。)
++++Any object with this component will receive the relevant message from the “Hand”.(立钻哥哥:任何具有此组件的对象都将从“Hand”接收相关消息.)
++++Using just these 3 components you should be able to create many different and complex interactive objects.(立钻哥哥:仅使用这3个组件,您就应该能够创建许多不同的、复杂的交互对象.)
++++A few commonly used “interactable system” components that show how the system can combine these basic mechanics to create more complicated objects have been provided.(立钻哥哥:提供了一些常用的“可交互系统”组件,它们展示了系统如何结合这些基本机制来创建更复杂的对象)
//立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Interactable.cs //Purpose: This object will get hover events and can be attached to the hands.(立钻哥哥:用途:此对象将获得悬停事件,并可以附加到手上.) using UnityEngine; using UnityEngine.Events; using System.Collections; using System.Collections.Generic;
namespace Valve.VR.InteractionSystem{ public class Interactable : MonoBehaviour{ public delegate void OnAttachedToHandDelegate(Hand hand); public delegate void OnDetachedFromHandDelegate(Hand hand);
public event OnAttachedToHandDelegate onAttachedToHand; public event OnDetachedFromHandDelegate onDetachedFromHand;
private void Awake(){ skeletonPoser = GetComponent<SteamVR_Skeleton_Poser>(); }
protected virtual void Start(){ highlightMat = (Material)Resources.Load(“SteamVR_HoverHighlight”, typeof(Material)); }
protected virtual bool ShouldIgnoreHighlight(Component component){} protected virtual bool ShouldIgnore(GameObject check){} protected virtual void CreateHighlightRenderers(){} protected virtual void UpdateHighlightRenderers(){}
//Called when a Hand starts hovering over this object.(立钻哥哥:当一只手开始悬停在该对象上时调用.) protected virtual void OnHandHoverBegin(Hand hand){}
//Called when a Hand stops hovering over this object.(立钻哥哥:当一只手离开悬停在该对象上时调用) private void OnHandHoverEnd(Hand hand){}
protected virtual void Update(){}
protected virtual void OnAttachedToHand(Hand hand){} protected virtual void OnDetachedFromHand(Hand hand){}
protected virtual void OnDestroy(){} protected virtual void OnDisable(){}
} //立钻哥哥:public class Interactable:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++Throwable(可抛出)
++++立钻哥哥:This is one of the most basic interactive objects.(这是最基本的交互对象之一)
++++The player can pick up this object when a hand hovers over it and presses one of the grab buttons(usually trigger or grip).(立钻哥哥:当一只手悬停在这个物体上并按下其中一个抓取按钮(通常是扳机或手柄)时,玩家可以拿起这个物体.)
++++The object gets attached to the hand and is held there while the button is pressed.(立钻哥哥:当按下按钮时,该对象被附在手上并保持在那里.)
++++When the button is released then any velocity that was in the hand is given to thrown object.(立钻哥哥:当按钮被释放时,手中的任何速度都被赋予抛出的物体.)
++++This lets you create basic objects that can be picked up and thrown.(立钻哥哥:这让您可以创建可以拾取和抛出的基本对象.)
//立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Throwable.cs //Purpose: Basic throwable object.(立钻哥哥:用途:基本抛掷物) using UnityEngine; using UnityEngine.Events; using System.Collections;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] [RequireComponent(typeof(Rigidbody))] [RequireComponent(typeof(VelocityEstimator))] public class Throwable : MonoBehaviour{ public UnityEvent onPickUp; public UnityEvent onDetachFromHand; public UnityEvent<Hand> onHeldUpdate;
[HideInInspector] public Interactable interactable;
protected virtual void Awake(){ velocityEstimator = GetComponent<VelocityEstimator>(); interactable = GetComponent<Interactable>();
rigidbody = GetComponent<Rigidbody>(); rigidbody.maxAngularVelocity = 50.0f; }
protected virtual void OnHandHoverBegin(Hand hand){} protected virtual void OnHandHoverEnd(Hand hand){} protected virtual void HandHoverUpdate(Hand hand){} protected virtual void OnAttachedToHand(Hand hand){} protected virtual void OnDetachedFromHand(Hand hand){}
public virtual void GetReleaseVelocities(Hand hand, out Vector3 velocity, out Vector3 angularVelocity){}
protected virtual void HandAttachedUpdate(Hand hand){} protected virtual IEnumerator LateDetach(Hand hand){} protected virtual void OnHandFocusAcquired(Hand hand){} protected virtual void OnHandFocusLost(Hand hand){}
} //立钻哥哥:public class Throwable:MonoBehaviour{}
public enum ReleaseStyle{ NoChange, GetFromHand, ShortEstimation, AdvancedEstimation, } //立钻哥哥:public enum ReleaseStyle{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++LinearDrive(线性驱动)
++++立钻哥哥:This allows an object to be moved by the hand between a starting and ending position.(这允许用手在起始和结束位置之间移动对象)
++++The object’s current position is used to set a LinearMapping.(立钻哥哥:对象的当前位置用于设置线性映射.)
//立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\LinearMapping.cs //Purpose: A linear mapping value that is used by other components.(立钻哥哥:用途:用于其它组件的线性映射值.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class LinearMapping : MonoBehaviour{ public float value; } //立钻哥哥:public class LinearMapping:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\LinearDrive.cs
//Purpose: Drives a linear mapping based on position between 2 positions.(立钻哥哥:用途:驱动基于两个位置之间位置的线性映射.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] public class LinearDrive : MonoBehaviour{ public Transform startPosition; public Transform endPosition; public LinearMapping linearMapping; public bool repositionGameObject = true; public bool maintainMomemntum = true; public float momentumDampenRate = 5.0f;
protected Interactable interactable;
protected virtual void Awake(){ mappingChangeSamples = new float[numMappingChangeSamples]; interactable = GetComponent<Interactable>(); }
protected virtual void Start(){}
protected virtual void HandHoverUpdate(Hand hand){ GrabTypes startingGrapType = hand.GetGrabStarting(); }
protected virtual void HandAttachedUpdate(){ UpdateLinearMapping(hand.transform){} }
protected virtual void OnDetachedFromHand(Hand hand){ CalculateMappingChangeRate(); }
protected void CalculateMappingChangeRate(){} protected void UpdateLinearMapping(Transform updateTransform){} protected float CalculateLinearMapping(Transform updateTransform){}
protected virtual void Update(){}
} //立钻哥哥:public class LinearDrive:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++CircularDirve(循环驱动)
++++立钻哥哥:This allows an object to be moved by the hand in a circular motion.(这允许手以圆周运动的方式移动物体。)
++++The object’s current position is used to set a LinearMapping.(立钻哥哥:对象的当前位置用于设置线性映射.)
//立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\CircularDrive.cs //Purpose: Interactable that can be used to move in a circular motion.(立钻哥哥:用途:可互动,可用于圆周运动) using UnityEngine; using UnityEngine.Events; using System.Collections;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] public class CircularDrive : MonoBehaviour{ public enum Axis_t{ XAxis, YAxis, ZAxis }
private Quaternion start; private Interactable interactable;
private void Freeze(Hand hand){} private void UnFreeze(){}
private void Awake(){ interactable = this.GetComponent<Interactable>(); }
private void Start(){} void OnDisable(){}
private IEnumerator HapticPulses(Hand hand, float flMagnitude, int nCount){}
private void OnHandHoverBegin(Hand hand){ hand.ShowGrabHint(); }
private void OnHandHoverEnd(Hand hand){ hand.HideGrabHint(); }
private GrabTypes grabbedWithType; private void HandHoverUpdate(Hand hand){ GrabTypes startingGrabType = hand.GetGrabStarting(); bool isGrabEnding = hand.IsGrabbingWithType(grabbedWithType)==false; }
private Vector3 ComputeToTransformProjected(Transform xForm){} private void DrawDebugPath(Transform xForm, Vector3 toTransformProjected){}
//Updates the LinearMapping value from the angle.(立钻哥哥:从该角度更新线性映射值) private void UpdateLinearMapping(){} private void UpdateGameObject(){}
//Updates the Debug TextMesh with the linear mapping value and the angle.(立钻哥哥:使用线性映射值和角度更新Debug TextMesh.) private void UpdateDebugText(){} private void UpdateAll(){}
//Computes the angle to rotate the game object based on the change in the transform.(立钻哥哥:根据变换中的变化计算旋转游戏对象的角度) private void ComputeAngle(Hand hand){}
} //立钻哥哥:public class CircularDrive:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++LinearMapping(线性映射)
++++立钻哥哥:This is a number that is set by a LinearDrive or CircularDrive.(这是一个由线性驱动器或循环驱动器设置的数字。)
++++The mapping can be used to map simple hand interactions into more complex behaviors.(立钻哥哥:该映射可用于将简单的手交互映射为更复杂的行为.)
----An example of this is string in the Longbow which uses a “LinearMapping” to map the pulling of the bow string to the longbow pull-back animation.(立钻哥哥:长弓中的弦就是一个例子,它使用“线性映射”将弓弦的拉伸映射到长弓的回拉动画.)
++++The mapping is used by several other classes to interpolate their properties.(立钻哥哥:其他几个类使用映射来插值它们的属性.)
----LinearAnimation(线性动画)
----LinearAnimator(线性动画师)
----LinearBlendShape(线性混合形状)
----LinearDisplacement(线位移)
----HapticRack(触觉架)
//立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\LinearMapping.cs //Purpose: A linear mapping value that is used by other components.(立钻哥哥:用途:用于其它组件的线性映射值.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class LinearMapping : MonoBehaviour{ public float value; } //立钻哥哥:public class LinearMapping:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\LinearAnimation.cs
//Purpose: Animation that moves based on a linear mapping.(立钻哥哥:用途:基于线性映射移动的动画.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class LinearAnimation : MonoBehaviour{ public LinearMapping linearMapping; public new Animation animation;
private AnimationState animState; private float animLength; private float lastValue;
void Awake(){ animation = GetComponent<Animation>(); linearMapping = GetComponent<LinearMapping>();
//We’re assuming the animation has a single clip, and that’s the one we’re going to scrub with the linear mapping.(立钻哥哥:我们假设动画只有一个剪辑,这就是我们要用线性映射去除的那个) animation.playAutomatically = true; animState = animation[animation.clip.name];
//If the anim state’s (i.e. clip’s) wrap mode is Once(the default) or ClampForever, Unity will automatically stop playing the anim, regardless of subsequent changes to animState.time. Thus, we set the wrap mode to PingPong.(立钻哥哥:如果anim状态(即clip的)换行模式为Once(默认)或ClampForever, Unity将自动停止播放anim,而不管随后对animState.time的更改。因此,我们将wrap模式设置为乒乓球.) animState.wrapMode = WrapMode.PingPong; animState.speed = 0; animLength = animState.length; }
void Update(){ float value = linearMapping.value;
//No need to set the anim if our value hasn’t changed.(立钻哥哥:如果我们的值没有改变,就不需要设置anim.) if(value != lastValue){ animState.time = value * animLength; } lastValue = value; }
} //立钻哥哥:public class LinearAnimation:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\LinearAnimator.cs
//Purpose: Animator whose speed is set based on a linear mapping.(立钻哥哥:用途:动画师,其速度是基于线性映射设置的.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class LinearAnimator : MonoBehaviour{ public LinearMapping linearMapping; public Animator animator;
void Awake(){} void Update(){} } //立钻哥哥:public class LinearAnimator:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\LinearBlendshape.cs
//Purpose: Set the blend shape weight based on a linear mapping.(立钻哥哥:目的:根据线性映射设置混合形状权重.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class LinearBlendshape : MonoBehaviour{ public LinearMapping linearMapping; public SkinnedMeshRenderer skinnedMesh;
void Awake(){} void Update(){} } //立钻哥哥:public class LinearBlendshape:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\LinearDisplacement.cs
//Purpose: Move the position of this object based on a linear mapping.(立钻哥哥:目的:基于线性映射移动该对象的位置.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class LinearDisplacement : MonoBehaviour{ public Vector3 displacement; public LinearMappling linearMapping;
void Start(){} void Update(){} } //立钻哥哥:public class LinearDisplacement:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\HapticRack.cs
//Purpose: Triggers haptic pulses based on a linear mapping.(立钻哥哥:用途:基于线性映射触发触觉脉冲.) using UnityEngine; using UnityEngine.Events; using System.Collections;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] public class HapticRack : MonoBehaviour{ public LinearMapping linearMapping;
public UnityEvent onPulse;
private Hand hand;
void Awake(){}
private void OnHandHoverBegin(Hand hand){ this.hand = hand; }
private void OnHandHoverEnd(){ this.hand = null; }
void Update(){} private void Pulse(){} } //立钻哥哥:public class HapticRack:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++VelocityEstimator(速度预测器)
++++立钻哥哥:This class is useful for estimating the velocity and acceleration of an object based on a change in its position.(这个类用于根据物体位置的变化估计物体的速度和加速度.)
++++In most cases you would get more accurate results if you get the velocity and acceleration from the actual controller but sometimes that isn’t possible such as when using the 2D fallback hand.(立钻哥哥:在大多数情况下,如果你从实际控制器得到速度和加速度,你会得到更准确的结果,但有时这是不可能的,例如当使用2D反手.)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\VelocityEstimator.cs
//Purpose: Estimates the velocity of an object based on change in position.(立钻哥哥:目的:根据物体位置的变化来估计物体的速度.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class VelocityEstimator : MonoBehaviour{ public int velocityAverageFrames = 5; public int angularVelocityAverageFrames = 11; public bool estimateOnAwake = false;
private Coroutine routine;
public void BeginEstimatingVelocity(){ FinishEstimatingVelocity(); routine = StartCoroutine(EstimateVelocityCoroutine()); }
public void FinishEstimatingVelocity(){} public Vector3 GetVelocityEstimate(){} public Vector3 GetAngularVelocityEstimate(){} public Vector3 GetAccelerationEstimate(){}
void Awake(){ velocitySamples = new Vector3[velocityAverageFrames]; angularVelocitySamples = new Vector3[angularVelocityAverageFrames];
if(estimateOnAwake){ BeginEstimatingVelocity(); } }
private IEnumerator EstimateVelocityCoroutine(){ sampleCount = 0;
Vector3 previousPosition = transform.position; Quaternion previousRotation = transfrom.rotation;
while(true){ yield return new WaitForEndOfFrame(); } }
} //立钻哥哥:public class VelocityEstimator:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++IgnoreHovering(忽略悬停)
++++立钻哥哥:This can be added to an object or specific collider if you want it to be ignored by the hand when doing its hovering checks.(这可以添加到一个对象或特定的碰撞器,如果你想要它被忽略时的手悬停检查。)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\IgnoreHovering.cs
//Purpose: Makes this object ignore any hovering by the hands.(立钻哥哥:目的:使该对象忽略任何悬停在手上的东西) using UnityEngine;
namespace Valve.VR.InteractionSystem{ public class IgnoreHovering : MonoBehaviour{ [Tooltip(“If Hand is not null, only ignore the specified hand.(立钻哥哥:如果Hand不为空,则只忽略指定的Hand.)”)] public Hand onlyIgnoreHand = null; } //立钻哥哥:public class IgnoreHovering:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++UIElement(控件元素)
++++立钻哥哥:Adding this component to an existing “UI widget” will make it so that the hands can interact with it.(将此组件添加到现有的“UI小部件”将使其能够与手交互。)
++++This will generate mouse hover and click events based on hand interactions and send them through the “Unity event system” to work with existing “UI widgets”.(立钻哥哥:这将生成鼠标悬停和点击基于手的交互事件,并通过“Unity事件系统”发送它们来处理现有的“UI小部件”.)
++++In addition it will also generate an “OnHandClick” event which will also pass in the hand that clicked the element.(立钻哥哥:此外,它还将生成一个“OnHandClick”事件,该事件也将传递给单击该元素的手.)
++++Another big part of the “interaction system” is the concept of an “ItemPackage”.(立钻哥哥:“交互系统”的另一个重要部分是“ItemPackage”的概念.)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\UIElement.cs
//Purpose: UIElement that responds to VR hands and generates UnityEvents.(立钻哥哥:用途:响应VR手并生成UnityEvents的UIElement.) using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using System;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] public class UIElement : MonoBehaviour{ public CustomEvents.UnityEventHand onHandClick; protected Hand currentHand;
protected virtual void Awake(){ Button button = GetComponent<Button>(); button.onClick.AddListener(OnButtonClick); }
protected virtual void OnHandHoverBegin(Hand hand){ currentHand = hand; InputModule.instance.HoverBegin(gameObject); ControllerButtonHints.ShowButtonHint(hand, hand.uiInteractAction); }
protected virtual void OnHandHoverEnd(Hand hand){ InputModule.instance.HoverEnd(gameObject); ControllerButtonHints.HideButtonHint(hand, hand.uiInteractAction); currentHand = null; }
protected virtual void HandHoverUpdate(Hand hand){ if(hand.uiInteractAction != null && hand.uiInteractAction.GetStateDown(hand.handType)){ InputModule.instance.Submit(gameObject); ControllerButtonHints.HideButtonHint(hand, hand.uiInteractAction); } }
protected virtual void OnButtonClick(){ onHandClick.Invoke(currentHand); } } //立钻哥哥:public class UIElement:MonoBehaviour{}
#if UNITY_EDITOR [UnityEditor.CustomEditor(typeof(UIElement))] public class UIElementEditor : UnityEditor.Editor{ //Custom Inspector GUI allows us to click from within the UI.(立钻哥哥:自定义检查器GUI允许我们从UI中单击.) public override void OnInspectorGUI(){ DrawDefaultInspector();
UIElement uiElement = (UIElement)target; if(GUILayout.Button(“Click”)){ InputModule.instance.Submit(uiElement.gameObject); } } } #endif
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++ItemPackage(项目包)
++++立钻哥哥:An “ItemPackage” can be 1 or 2 handed.(一个“ItemPackage”可以是1个或者2个。)
++++An “ItemPackage” is collection of objects that are meant to temporarily override the functionality of the hand.(立钻哥哥:“ItemPackage”是一些对象的集合,这些对象旨在临时覆盖手的功能.)
----An example of this is the Longbow. While the Longbow is attached to the hand it sort of takes over the base functionality of the hand.(立钻哥哥:长弓就是一个例子。当长弓与手相连时它就接管了手的基本功能.)
++++”ItemPackages” have the concept of being able to be picked up and put back where they were picked up from.(立钻哥哥:“ItemPackages”的概念是能够被取走并放回它们被取走的地方.)
++++Once picked up they remain attached to the hand until they are put back. No button needs to be held for them to remain attached to the hand. The hand still passes along messages like normal but these objects usually disable some of the base functionality of the hand, such as hovering while they are attached.(立钻哥哥:一旦拿起来,它们就会附着在手上,直到被放回去。不需要任何按钮来保持它们附着在手上。手仍然像平常一样传递消息,但是这些对象通常禁用手的一些基本功能,比如在它们被连接时悬停.)
----Other examples of an “ItemPackage” from “The Lab” would be the ballon tool or the “Xortex” drone controller. Both these objects take over the hand’s base functionality while they are attached.(立钻哥哥:来自“实验室”的“ItemPackage”的其他例子是ballon工具或“Xortex”无人机控制器。这两个对象在附加时都接管了手的基本功能.)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\ItemPackage.cs
//Purpose: A package of items that can interact with the hands and be returned.(立钻哥哥:用途:一种可以与手交互并返回的物品包.) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class ItemPackage : MonoBehaviour{ public enum ItemPackageType{ Unrestricted, OneHand, TwoHande }
public new string name; public ItemPackageType packageType = ItemPackageType.Unrestricted;
//object to be spawned on tracked controller.(立钻哥哥:要在跟踪控制器上生成的对象) public GameObject itemPrefab;
//object to be spawned in Other Hand.(立钻哥哥:要在另一手生成的对象.) public GameObject otherHandItemPrefab;
//used to preview inputObject.(立钻哥哥:用于预览inputObject) public GameObject previewPrefab;
//used to preview insubstantial inputObject.(立钻哥哥:用于预览非实质的inputObject) public GameObject fadedPreviewPrefab;
} //立钻哥哥:public class ItemPackage:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++ItemPackageSpawner(项目包卵生器)
++++立钻哥哥:This handles the logic for when to spawn and put away the “ItemPackage” and how to attach the items to the hand once spawned.(它处理何时生成和放置“ItemPackage”的逻辑,以及生成后如何将项目附加到手上)
++++It also handles showing the preview of the item or the outline of the item when it is picked up.(立钻哥哥:它也处理显示预览的项目或项目的外轮廓,当它被拿起)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\ItemPackageSpawner.cs
//Purpose: Handles the spawning and returning of the ItemPackage.(立钻哥哥:用途:处理ItemPackage的生成和返回) using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using UnityEngine.Events; #if UNITY_EDITOR using UnityEditor; #endif
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] public class ItemPackageSpawner : MonoBehaviour{ public ItemPackage itemPackage{}
public UnityEvent pickupEvent; public UnityEvent dropEvent;
private void CreatePreviewObject(){}
void Start(){}
private void VerifyItemPackage(){} private void ItemPackageNotValid(){} private void ClearPreview(){}
void Update(){}
private void OnHandHoverBegin(Hand hand){} private void TakeBackItem(Hand hand){} private ItemPackage GetAttachedItemPackage(Hand hand){} private void HandHoverUpdate(Hand hand){} private void OnHandHoverEnd(Hand hand){} private void RemoveMatchingItemsFromHandStack(ItemPackage package, Hand hand){} private void RemoveMatchingItemTypesFromHand(ItemPackage.ItemPackageType packageType, Hand hand){} private void SpawnAndAttachObject(Hand hand, GrabTypes grabType){}
} //立钻哥哥:public class ItemPackageSpawner:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++ItemPackageReference(项目包参考)
++++立钻哥哥:This component can be added to item to include that it is a part of an item package.(可以将此组件添加到项中,以包括它是项包的一部分)
++++There are a few other helper classes included as a core part of the interaction system.(立钻哥哥:还有一些其他的helper类包含在交互系统的核心部分中)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\ItemPackageReference.cs
//Purpose: Keeps track of the ItemPackage this object is a part of.(立钻哥哥:目的:跟踪此对象所属的ItemPackage) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class ItemPackageReference : MonoBehaviour{ public ItemPackage itemPackage; } //立钻哥哥:public class ItemPackageReference:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++PlaySound(播放声音)
++++立钻哥哥:This class allows AudioClips to be played back with many more parameters.(这个类允许使用更多参数回放AudioClips)
++++It can take in many AudioClips and play back 1 at random each time.(立钻哥哥:它可以接收许多音频,每次随机回放1次)
++++It can also randomize how the clip is played back.(立钻哥哥:它还可以随机播放剪辑)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\PlaySound.cs
//Purpose: Plays one of many audio files with possible randomized parameters.(立钻哥哥:用途:播放任意随机参数的音频文件) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(AudioSource))] public class PlaySound : MonoBehaviour{ public AudioClip[] waveFile; public bool stopOnPlay; public bool disableOnEnd; public bool looping; public bool stopOnEnd; public bool playOnAwakeWithDelay;
private AudioSource audioSource; private AudioClip clip;
void Awake(){}
//Play a random clip from those available.(立钻哥哥:从那些可用的随机播放剪辑) public void Play(){}
public void PlayWithDelay(float delayTime){}
//Play random wave clip on audiosource as a one shot.(立钻哥哥:在音频源上随机播放波形剪辑作为一个镜头) public AudioClip PlayOneShotSound(){}
pubic AudioClip PlayLooping(){}
public void Disable(){} public void Stop(){}
private void SetAudioSource(){}
} //立钻哥哥:public class PlaySound:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++SoundPlayOneShot
++++立钻哥哥: This class is specifically for sounds that only play once and don’t loop or need to be paused while playing.(这个类特别适用于只播放一次且不循环或在播放时需要暂停的声音)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\SoundPlayOneshot.cs
//Purpose: Play one-shot sounds as opposed to continuos/looping ones.(立钻哥哥:目的:播放一次性的声音,而不是连续/循环的声音) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class SoundPlayOneshot : MonoBehaviour{ public AudioClip[] waveFiles; private AudioSource thisAudioSource;
public float volMin; public float volMax;
public float pitchMin; public float pitchMax;
public bool playOnAwake;
void Awake(){ thisAudioSource = GetComponent<AudioSource>(); if(playOnAwake){ Play(); } }
public void Play(){ if(thisAudioSource != null && thisAudioSource.isActiveAndEnabled && !Util.IsNullOrEmpty(waveFiles)){ thisAudioSource.volume = Random.Range(volMin, volMax); thisAudioSource.pitch = Random.Range(pitchMin, pitchMax); thisAudioSource.PlayOneShot(waveFiles[Random.Range(0, waveFiles.Length)]); } }
public void Pause(){ if(thisAudioSource != null){ thisAudioSource.Pause(); } }
public void UnPause(){ if(thisAudioSource != null){ thisAudioSource.UnPause(); } }
} //立钻哥哥:public class SoundPlayOneshot:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++Util(工具类)
++++立钻哥哥:This is a class full of small utility functions that are used throughout the interaction system.(这是一个在整个交互系统中使用的小实用函数的类)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Util.cs
//Purpose: Utility functions used in several places.(立钻哥哥:用途:多处使用的实用函数) using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq;
namespace Valve.VR.InteractionSystem{ public static class Util{ public const float FeetToMeters = 0.3048f; public const float FeetToCentimeters = 30.48f;
public static float RemapNumber(float num, float low1, float high1, float low2, float high2){} public static float RemapNumberClamped(float num, float low1, float high1, float low2, float high2){} public static float Approach(float target, float value, float speed){} public static Vector3 BezierInterpolate3(Vector3 p0, Vector3 c0, Vector3 p1, float t){} public static Vector3 BezierInterpolate4(Vector3 p0, Vector3 c0, Vector3 c1, Vector3 p1, float t){} public static Vector3 Vector3FromString(string szString){} public static Vector2 Vector2FromString(string szString){} public static float Normalize(float value, float min, float max){} public static Vector3 Vector2AsVector3(Vector2 v){} public static Vector2 Vector3AsVector2(Vector3 v){} public static float AngleOf(Vector2 v){} public static float YawOf(Vector3 v){} public static void Swap<T>(ref T lhs, ref T rhs){} public static void Shuffle<T>(T[] array){} public static void Shuffle<T>(List<T> list){} public static int RandomWithLookback(int min, int max, List<int> history, int historyCount){} public static Transform FindChild(Transform parent, string name){} public static bool IsNullOrEmpty<T>(T[] array){} public static bool IsValidIndex<T>(T[] array, int i){} public static bool IsValidIndex<T>(List<T> list, int i){} public static int FindOrAdd<T>(List<T> list, T item){} public static List<T> FindAndRemove<T>(List<T> list, System.Predicate<T> match){} public static T FindOrAddComponent<T>(GameObject gameObject) where T : Component{} public static void FastRemove<T>(List<T> list, int index){} public static void ReplaceGameObject<T, U>(T replace, U replaceWith) where T:MonoBehaviour where U:MonoBehaviour{} public static void SwitchLayerRecursively(Transform transform, int fromLayer, int toLayer){} public static void DrawCross(Vector3 origin, Color crossColor, float size){} public static void ResetTransform(Transform t, bool resetSclae=true){} public static Vector3 ClosestPointOnLine(Vector3 vA, Vector3 vB, Vector3 vPoint){} public static void AfterTimer(GameObject go, float _time, System.Action callback, bool trigger_if_destroyed_early=false){} public static void SendPhysicsMessage(Collider collider, string message, SendMessgaeOptions sendMessageOptions){} public static void SendPhysicsMessage(Collider collider, string message, object arg, SendMessageOptions sendMessageOptions){} public static void IgnoreCollisions(GameObject goA, GameObject goB){} public static IEnumerator WrapCoroutine(IEnumerator coroutine, System.Action onCoroutineFinished){} public static Color ColorWithAlpha(this Color color, float alpha){} public static void Quit(){} public static decimal FloatToDecimal(float value, int decimalPlaces=2){} public static T Median<T>(this IEnumerable<T> source){} public static void ForEach<T>(this IEnumerable<T> source, Action<T> action){} public static string FixupNewlines(string text){} public static float PathLength(UnityEngine.AI.NavMeshPath path){} public static bool HasCommandLineArgument(string argumentName){} public static int GetCommandLineArgValue(string argumentName, int nDefaultValue){} public static float GetCommandLineArgValue(string argumentName, float flDefaultValue){} public static void SetActive(GameObject gameObject, bool active){} public static string CombinePaths(params string[] paths){}
} //立钻哥哥:public static class Util{}
//Component used by the static AfterTimer function.(立钻哥哥:组件所使用的静态后定时器功能) [System.Serializable] public class AfterTimer_Component : MonoBehaviour{ private System.Action callback; private float triggerTime; private bool timerActive = false; private bool triggerOnEarlyDestroy = false;
public void Init(float _time, System.Action _callback, bool earlydestroy){} private IEnumerator Wait(){} void OnDestroy(){} } //立钻哥哥:public class AfterTimer_Component:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++InteractableHoverEvents(交互悬停事件)
++++立钻哥哥:This class generates UnityEvents when it receives messages from the hand.(这个类在接收到来自手的消息时生成UnityEvents)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\InteractableHoverEvents.cs
//Purpose: Sends UnityEvents for basic hand interactions.(立钻哥哥:用途:发送UnityEvents用于基本的手部交互) using UnityEngine; using UnityEngine.Events; using System.Collections;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] public class InteractableHoverEvents : MonoBehaviour{ public UnityEvent onHandHoverBegin; public UnityEvent onHandHoverEnd; public UnityEvent onAttachedToHand; public UnityEvent onDetachedFromHand;
private void OnHandHoverBegin(){ onHandHoverBegin.Invoke(); }
private void OnHandHoverEnd(){ onHandHoverEnd.Invoke(); }
private void OnAttachedToHand(Hand hand){ onAttachedToHand.Invoke(); }
private void OnDetachedFromHand(Hand hand){ onDetachedFromHand.Invoke(); }
} //立钻哥哥:public class InteractableHoverEvents:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++InteractableButtonEvents(交互按钮事件)
++++立钻哥哥:This class translates controller button input into UnityEvents.(该类将控制器按钮输入转换为UnityEvents)
++ComplexThrowable(复杂的可抛物)
++++立钻哥哥:This class attaches objects to the hand using a physics joint instead of simple parenting.(本类使用物理关节而不是简单的父方法将物体附着在手上)
++++This allows for more physics based interactions with the object once it is attached.(立钻哥哥:这允许在附加对象之后,与对象进行更多基于物理的交互.)
++++Note: This class is a little experimental. Since we didn’t actually use it in “The Lab” it might not be feature complete and may be buggy.(立钻哥哥:注:这个类有点实验性质。因为我们并没有在“实验室”中真正使用它,它可能不是完整的功能,而且可能有bug)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\ComplexThrowable.cs
//Purpose: Throwable that uses physics joints to attach instead of just parenting.(立钻哥哥:用途:可抛的,使用物理关节连接,而不只是父母) using UnityEngine; using System.Collections.Generic;
namespace Valve.VR.InteractionSystem{ [RequireComponent(typeof(Interactable))] public class ComplexThrowable : MonoBehaviour{ public enum AttachMode{ FixedJoint, Force, } //立钻哥哥:public enum AttachMode{}
private List<Hand> holdingHands = new List<Hand>(); private List<Rigidbody> holdingBodies = new List<Rigidbody>(); private List<Vector3> holdingPoints = new List<Vector3>();
private List<Rigidbody> rigidBodies = new List<Rigidbody>();
void Awake(){ GetComponentsInChildren<Rigidbody>(rigidBodies); }
void Update(){}
private void OnHandHoverBegin(Hand hand){} private void OnHandHoverEnd(Hand hand){} private void HandHoverUpdate(Hand hand){} private void PhysicsAttach(Hand hand, GrabTypes startingGrabType){} private bool PhysicsDetach(Hand hand){}
void FixedUpdate(){}
} //立钻哥哥:public class ComplexThrowable:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++DistanceHaptics(距离触觉)
++++立钻哥哥:Triggers haptic pulses based on a distance between 2 transforms.(根据两个变换之间的距离触发触觉脉冲)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\DistanceHaptics.cs
//Purpose: Triggers haptic pulses based on distance between 2 positions.(立钻哥哥:用途:根据两个位置之间的距离触发触觉脉冲) using UnityEngine; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class DistanceHaptics : MonoBehaviour{ public Transform firstTransform; public Transform secondTransform;
public AnimationCurve distanceIntensityCurve = AnimationCurve.Linear(0.0f, 800.0f, 1.0f, 800.0f); public AnimationCurve pulseIntervalCurve = AnimationCurve.Linear(0.0f, 0.01f, 1.0f, 0.0f);
IEnumerator Start(){ while(true){ float distance = Vector3.Distance(firstTransform.position, secondTransform.position);
Hand hand = GetComponentInParent<Hand>(); if(hand != null){ float pulse = distanceIntensityCurve.Evaluate(distance); hand.TriggerHapticPulse((ushort)pulse); //SteamVR_Controller.Input((int)trackedObject.index).TriggerHapticPulse((ushort)pulse); }
float nextPulse = pulseIntervalCurve.Evaluate(distance);
yield return new WaitForSeconds(nextPulse); } } //立钻哥哥:IEnumerator Start(){}
} //立钻哥哥:public class DistanceHaptics:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++Player(Prefab)(Player预制体)
++++立钻哥哥:This is the single piece of the interaction system that combines all its basic parts.(这是交互系统的单个部分,它组合了所有的基本部分)
++++This prefab arranges the player and hands in a way to make them all accessible easily.(立钻哥哥:这个预置安排玩家和手在一种方式,使他们都容易访问)
++++It also contains all the setup for “SteamVR” and the 2D fallback system.(立钻哥哥:它还包含了所有的设置“SteamVR”和2D备份系统)
++++Most of the other components of the interaction system depend on the player and some of them assume that the player and hands are set up in this way.(立钻哥哥:交互系统的大多数其他组件都依赖于玩家,其中一些组件假设玩家和手是这样设置的.)
++++These should only be 1 of these in a scene.(立钻哥哥:在一个场景中有且只有一个Player.)
++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Player.cs
//Purpose: Player interface used to query HMD transforms and VR hands.(立钻哥哥:用途:用于查询HMD转换和VR手的Player接口) using UnityEngine; using System.Collections; using System.Collections.Generic;
namespace Valve.VR.InteractionSystem{ //Singleton representing the local VR player/user, with methods for getting the player’s hands, head, tracking origin, and guesses for various properties.(立钻哥哥:单例表示本地VR玩家/用户,带有获取玩家的手、头、跟踪原点和可能的各种属性的方法) public class Player : MonoBehaviour{ public Transform trackingOriginTransform; public Transform[] hmdTransforms; public Hand[] hands; public Collider headCollider; public GameObject headCollider; public GameObject rigSteamVR; public GameObject rig2DFallback; public Transform audioListener;
[Tooltip(“This action lets you know when the player has placed the headset on their head.(立钻哥哥:这个动作让你知道玩家什么时候把头盔戴在头上)”)] public SteamVR_Action_Boolean headsetOnHead = SteamVR_Input.GetBooleanAction(“HeadsetOnHead”);
public bool allowToggleTo2D = true;
//Singleton instance of the Player. Only one can exist at a time.(立钻哥哥:玩家的单例实例。一次只能存在一个) private static Player _instance; public static Player instance{ get{ if(_instance == null){ _instance = FindObjectOfType<Player>(); } return _instance; } }
//Get the number of active Hands.(立钻哥哥:获取活动手的数量.) public int handCount{}
//Get the i-th active Hand.(立钻哥哥:得到第i只活动的手) public Hand GetHand(int i){}
public Hand leftHand{} public Hand rightHand{}
//Get Player scale. Assumes it is scaled equally on all axes.(立钻哥哥:得到的玩家的比例。假设它在所有坐标轴上的比例相等) public float scale{}
//Get the HMD transform. This might return the fallback camera transform if “SteamVR” is unavailable or disabled.(立钻哥哥:得到HMD变换。如果“SteamVR”不可用或禁用,则可能返回回退相机转换) public Transform hmdTransform{}
//Height of the eyes above the ground - useful for estimating player height.(立钻哥哥:眼睛高于地面的高度-用于估计玩家的高度) public float eyeHeight{}
//Guess for the world-space position of the player’s feet, directly beneath the HMD.(立钻哥哥:猜测世界空间的位置的玩家的脚,直接下面的HMD) public Vector3 feetPositionGuess{}
//Guess for the world-space direction of the player’s hips/torso. This is effectively just the gaze direction projected onto the floor plane.(立钻哥哥:猜测玩家臀部/躯干的世界空间方向。这实际上就是投射到地板平面上的凝视方向) public Vector3 bodyDirectionGuess{}
private void Awake(){ if(trackingOriginTransform == null){ trackingOriginTransform = this.transform; } }
private IEnumerator Start(){} protected virtual void Update(){}
void OnDrawGizmos{} public void Draw2DDebug(){} private void ActivateRig(GameObject rig){} public void PlayerShotSelf(){}
} //立钻哥哥:public class Player:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++BlankController(Prefab)(空白控制器预制体)
++++立钻哥哥:This is used by the Hand when it has nothing else attached.(这是用手时,它没有任何其他附着物)
++++This render model for the controller is loaded through “SteamVR” and all its parts are articulated.(立钻哥哥:控制器的这个渲染模型是通过“SteamVR”加载的,它的所有部分都是铰接的)
++++\Assets\SteamVR\Scripts\SteamVR_RenderModel.cs
//Purpose: Render model of associated tracked object.(立钻哥哥:用途:渲染相关被跟踪对象的模型) using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using Valve.VR;
namespace Valve.VR{ [ExecuteInEditMode] public class SteamVR_RenderModel : MonoBehaviour{ public SteamVR_TrackedObject.EIndex index = SteamVR_TrackedObject.EIndex.None; protected SteamVR_Input_Sources inputSource;
public string modelOverride; public Shader shader; public bool verbose = false; public bool createComponents = true; public bool updateDynamically = true;
private Dictionary<string, Transform> componentAttachPoints = new Dictionary<string, Transform>(); private List<MeshRenderer> meshRenderers = new List<MeshRenderer>();
//If someone knows how to keep these from getting cleaned up every time you exit play mode, let me know. I’ve tried making the RenderModel class below as [System.Serializable] and switching to normal public variables for mesh and material to get them to serialize properly, as well as tried making the mesh and material objects as DontUnloadUnusedAsset, but Unity was still unloading them. The hashtable is preserving its entries, but the mesh and material variables are going null.(立钻哥哥:如果有人知道如何防止这些清理从你每次退出运行模式,让我知道。我尝试将下面的RenderModel类做成[System.Serializable], 并切换到网格和材质的普通公共变量以使它们正确序列化,同时尝试将网格和材质对象作为DontUnloadUnusedAsset,但Unity仍在卸载它们。哈希表保留了它的条目,但是网格和材质变量变为null。) public class RenderModel{ public RenderModel(Mesh mesh, Material material){ this.mesh = mesh; this.material = material; }
public Mesh mesh{ get; private set; } public Material material{ get; private set; } }
public static Hashtable models = new Hashtable(); public static Hashtable materials = new Hashtable();
//Helper class to load render models interface on demand and clean up when done.(立钻哥哥:Helper类,可根据需要加载呈现模型接口,并在完成时进行清理) public sealed class RenderModelInterfaceHolder : System.IDisposable{ private bool needsShutdown, failedLoadInterface; private CVRRenderModels _instance; public CVRRenderModels instance{} public void Dispose(){} } //立钻哥哥:public sealed class RenderModelInterfaceHolder{}
private void OnModelSkinSettingsHaveChanged(VREvent_t vrEvent){}
public void SetMeshRendererState(bool state){} public void OnHideRenderModels(bool hidden){}
private void OnDeviceConnected(int i, bool connected){}
public void UpdateModel(){}
IEnumerator SetModelAsync(string newRenderModelName){}
private bool SetModel(string renderModelName){}
RenderModel LoadRenderModel(CVRRenderModels renderModels, string renderModelName, string baseName){}
IEnumerator FreeRenderModel(System.IntPtr pRenderModel){}
public Transform FindTransformByName(string componentName, Transform inTransform=null){} public Transform GetComponentTransform(string componentName){}
private void StripMesh(GameObject go){} private bool LoadComponents(RenderModelInterfaceHolder holder, string renderModelName){}
SteamVR_Events.Action deviceConnectedAction, hideRenderModelsAction, modelSkinSettingsHaveChangedAction;
SteamVR_RenderModel(){ deviceConnectedAction = SteamVR_Events.DeviceConnectedAction(OnDeviceConnected); hideRenderModelsAction = SteamVR_Events.HideRenderModelsAction(OnHideRenderModels); modelSkinSettingsHaveChangedAction = SteamVR_Events.SystemAction(EVREventType.VREvent_ModelSkinSettingsHaveChanged, OnModelSkinSettingsHaveChanged); }
void OnEnable(){} void OnDisable(){} void Update(){}
Dictionary<int, string> nameCache; public void UpdateComponents(CVRRenderModels renderModels){}
public void SetDeviceIndex(int newIndex){ this.index = (SteamVR_TrackedObject.EIndex)newIndex; }
public void SetInputSource(SteamVR_Input_Sources newInputSource){ inputSource = newInputSource; }
private static void Sleep(){ System.Threading.Thread.Sleep(1); }
//Helper function to handle the inconvenient fact that the packing for RenderModel_t is different on Linux/OSX than it is on Windows.(立钻哥哥:帮助函数处理RenderModel_t的包装在Linux/OSX上与在Windows上不同这一不方便的事实) private RenderModel_t MarshalRenderModel(System.IntPtr pRenderModel){} private RenderModel_TextureMap_t MarshalRenderModel_TextureMap(System.IntPtr pRenderModel){}
} //立钻哥哥:public class SteamVR_RenderModel:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR{} |
++Teleport(传送)
++++立钻哥哥:The teleport system from “The Lab” supports teleporting to specific teleport points or a more general teleport area.(“实验室”的传送系统支持传送到特定的传送点或更通用的传送区)
++++The important classes are Teleport, TeleportPoint and TeleportArea.(立钻哥哥:重要的类是Teleport、TeleportPoint和TeleportArea)
++++All the functionality is wrapped up in the Teleporting prefab in “Teleport/Prefabs”. This prefab included all the logic for the teleport system to function.(立钻哥哥:所有功能都封装在“传送/预置”中的传送预置中。这个预置包括了传送系统运作的所有逻辑.)
++++Add TeleportPoints or TeleportAreas to the scene to add spots where the player can teleport to.(立钻哥哥:向场景中添加传送点或传送区域,以添加玩家可以传送到的点)
++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\Teleport.cs
//Purpose: Handles all the teleport logic.(立钻哥哥:用途:处理所有的传送逻辑) using UnityEngine; using UnityEngine.Events; using System.Collections;
namespace Valve.VR.InteractionSystem{ public class Teleport : MonoBehaviour{ public SteamVR_Action_Boolean teleportAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>(“Teleport”);
private Hand pointerHand = null; private Player player = null; private TeleportArc teleportArc = null;
private static Teleport _instance; public static Teleport instance{}
void Awake(){ _instance = this; }
void Start(){ teleportMarkers = GameObject.FindObjectsOfType<TeleportMarkerBase>(); player = InteractionSystem.Player.instance; }
void OnEnable(){} void OnDisable(){}
private void CheckForSpawnPoint(){}
public void HideTeleportPointer(){}
void Update(){}
private void UpdatePointer(){}
void FixedUpdate(){}
private void OnChaperoneInfoInitialized(){} private void HidePointer(){} private void ShowPointer(Hand newPointerHand, Hand oldPointerHand){} private void UpdateTeleportColors(){} private void PlayAudioClip(AudioSource source, AudioClip clip){} private void PlayPointerHaptic(bool validLocation){} private void TryTeleportPlayer(){} private void InitiateTeleportFade(){} private void TeleportPlayer(){} private void HighlightSelected(TeleportMarkerBase hitTeleportMarker){}
public void ShowTeleportHint(){} public void CancelTeleportHint(){}
private IEnumerator TeleportHintCoroutine(){}
public bool IsEligibleForTeleport(Hand hand){}
private bool ShouldOverrideHoverLock(){} private bool WasTeleportButtonReleased(Hand hand){} private bool IsTeleportButtonDown(Hand hand){} private bool WasTeleportButtonPressed(Hand hand){} private Transform GetPointerStartTransform(Hand hand){}
} //立钻哥哥:public class Teleport:MonoBehaviour{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++Teleport(传送)
++++立钻哥哥:This class handles most of the logic of teleporting.(这个类处理传送的大部分逻辑)
++++When the touchpad is pressed, the teleport pointer shows up. If the pointer is pointing at a valid spot when the touchpad is released when the player teleports.(立钻哥哥:当触摸板被按下时,传送指针就会出现。当玩家传送touchpad时,如果指针指向一个有效的点)
----You can also press “T” on the keyboard while in 2D fallback mode to bring up the teleport pointer.(立钻哥哥:你也可以按下键盘上的“T”,在2D后退模式,以打开传送指针)
++++This class keeps track of all the teleport markers in the scene and informs them to fade in/out depending on the state of the teleport pointer.(立钻哥哥:该类跟踪场景中的所有传送端口标记,并根据传送端口指针的状态通知它们淡入/淡出)
++++In certain situations it can be useful to have a separate mesh for the floor the scene that is different from the teleport mesh. In these situations the teleport system will trace down form where it hit the teleport mesh and try to place on the floor mesh. The point of this is to try to match the visual floor in the scene with the physical floor in the player’s play area.(立钻哥哥:在某些情况下,在地板上使用不同于传送网格的网格是很有用的。在这种情况下,传送系统将追踪它击中传送网的位置,并试图将其放置在地板网孔上。这样做的目的是尝试将场景中的视觉地板与玩家游戏区域中的物理地板匹配起来.)
++++There are a few properties that will probably need to be tweaked:(立钻哥哥:有一些属性可能需要调整:)
----[tracerLayerMask]: This is all the layers that the teleport pointer will try to hit.(立钻哥哥:[tracerLayerMask]:这是传送指针将尝试命中的所有层)
----[floorFixupMask]: The layer that the floor is on.(立钻哥哥:[floorFixupMask]:地板所在的层)
----[floorFixupMaximumTraceDistance]: The maximum distance to trace to try to look for the floor.(立钻哥哥:[floorFixupMaximumTraceDistance]:查找地板的最大跟踪距离)
----[ShowPlayAreaMarker]: This toggles whether to show the rectangle of the player’s play area while teleporting. This can help in orienting the players in their physical space.(立钻哥哥:[ShowPlayAreaMarker]:这将切换是否显示传送时玩家游戏区域的矩形。这可以帮助玩家在他们的物理空间中找到方向)
----[arcDistance]: How far the teleport arc should go. Increasing this number will allow the player to teleport further in the scene. This value will probably need to be tweaked for each scene.(立钻哥哥:[arcDistance]:传送弧应该走多远。增加这个数字将允许玩家在场景中传送得更远。这个值可能需要为每个场景进行调整)
++TeleportMarkerBase(传送标记基类)
++++立钻哥哥:This is the base class for all the teleport markers.(这是所有传送标记的基类。)
++++It contains methods that the “Teleport” class expects to be present in all the teleport markers.(立钻哥哥:它包含“Teleport”类期望出现在所有Teleport标记中的方法.)
++++You can use this as your base class to create a new type of teleport marker.(立钻哥哥:你可以用这个作为你的基类来创建一种新的传送标记)
++++A teleport marker can be locked or unlocked. The player cannot teleport to locked markers.(立钻哥哥:传送标记可以锁定或解锁。玩家不能传送到锁定的标记.)
++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportMarkerBase.cs
//Purpose: Base class for all the objects that the player can teleport to.(立钻哥哥:用途:玩家可以传送到的所有对象的基类) using UnityEngine;
namespace Valve.VR.InteractionSystem{ public abstract class TeleportMarkerBase : MonoBehaviour{ public bool locked = false; public bool markerActive = true;
public virtual bool showReticle{ get{ return true; } }
public void SetLocked(bool locked){ this.locked = locked; UpdateVisuals(); }
public virtual void TeleportPlayer(Vector3 pointedAtPosition){}
public abstract void UpdateVisuals(); public abstract void Highlight(bool highlight); public abstract void SetAlpha(float tintAlpha, float alphaPercent); public abstract bool ShouldActivate(Vector3 playerPosition); public abstract bool ShouldMovePlayer(); } //立钻哥哥:public abstract class TeleportMarkerBase:MonoBehaviour{} } //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++TeleportArea(传送区域)
++++立钻哥哥:This is a teleport area that is made up of a mesh.(这是一个由网格组成的传送区)
++++When teleporting onto these, the player will teleport exactly where they are pointing(plus the floor fixup).(立钻哥哥:当传送到这些东西上时,玩家将会准确地传送到他们所指向的地方(加上地板固定))
++++Add this component to any object with a collider and a mesh renderer to allow the player to teleport on it.(立钻哥哥:将此组件添加到任何带有碰撞体和网格渲染器的对象中,以允许玩家在其上传送)
++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportArea.cs
//Purpose: An area that the Player can teleport to.(立钻哥哥:用途:玩家可以传送到的区域) using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif
namespace Valve.VR.InteractionSystem{ public class TeleportArea : TeleportMarkerBase{ public Bounds meshBounds{ get; private set; }
private MeshRenderer areaMesh; private int tintColorId = 0; private Color visibleTintColor = Color.clear; private Color highlightedTintColor = Color.clear; private Color lockedTintColor = Color.clear; private bool highlighted = false;
public void Awake(){ areaMesh = GetComponent<MeshRenderer>(); tintColorId = Shader.PropertyToID(“_TintColor”); CalculateBounds(); }
public void Start(){ visibleTintColor = Teleport.instance.areaVisibleMaterial.GetColor(tintColorId); highlightedTintColor = Teleport.instance.areaHighlightedMaterial.GetColor(tintColorId); lockedTintColor = Teleport.instance.areaLockedMaterial.GetColor(tintColorId); }
public override bool ShouldActivate(Vector3 playerPosition){} public override bool ShouldMovePlayer(){} public override void Highlight(bool highlight){} public override void SetAlpha(float tintAlpha, float alphaPercent){} public override void UpdateVisuals(){} public void UpdateVisualsInEditor(){}
private bool CalculateBounds(){} private Color GetTintColor(){}
#if UNITY_EDITOR [CustomEditor(typeof(TeleportArea))] public class TeleportAreaEditor : Editor{ void OnEnable(){} public override void OnInspectorGUI(){} } //立钻哥哥:public class TeleportAreaEditor:Editor{} #endif
} //立钻哥哥:public class TeleportArea:TeleportMarkerBase{}
} //立钻哥哥:namespace Valve.VR.InteractionSystem{} |
++++SteamVR2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/86618187
++++SteamVR2.2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++SteamVR2.2.0交互系统:https://blog.csdn.net/VRunSoftYanlz/article/details/89199778
++立钻哥哥推荐的热门分类:
++++SteamVR:https://blog.csdn.net/vrunsoftyanlz/article/category/8582642
++++XR技术企业内训:https://blog.csdn.net/vrunsoftyanlz/article/category/8037810
++++5G+云计算+雾计算:https://blog.csdn.net/vrunsoftyanlz/article/category/8741272
++++框架编程:https://blog.csdn.net/vrunsoftyanlz/article/category/7570175
【XR游戏开发QQ群:784477094】
++立钻哥哥推荐的拓展学习链接(Link_Url):
立钻哥哥推荐的拓展学习链接(Link_Url) |
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++++HTC_VIVE开发基础:https://blog.csdn.net/VRunSoftYanlz/article/details/81989970
++++Oculus杂谈:https://blog.csdn.net/VRunSoftYanlz/article/details/82469850
++++Oculus安装使用:https://blog.csdn.net/VRunSoftYanlz/article/details/82718982
++++Unity+SteamVR=>VR:https://blog.csdn.net/VRunSoftYanlz/article/details/88809370
++++SteamVR简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86484254
++++SteamVR脚本功能分析:https://blog.csdn.net/VRunSoftYanlz/article/details/86531480
++++SteamVR2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/86618187
++++SteamVR2.2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++SteamVR/Extras:https://blog.csdn.net/VRunSoftYanlz/article/details/86584108
++++SteamVR/Input:https://blog.csdn.net/VRunSoftYanlz/article/details/86601950
++++OpenXR简介:https://blog.csdn.net/VRunSoftYanlz/article/details/85726365
++++VRTK杂谈:https://blog.csdn.net/VRunSoftYanlz/article/details/82562993
++++VRTK快速入门(杂谈):https://blog.csdn.net/VRunSoftYanlz/article/details/82955267
++++VRTK官方示例(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82955410
++++VRTK代码结构(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82780085
++++VRTK(SceneResources):https://blog.csdn.net/VRunSoftYanlz/article/details/82795400
++++VRTK_ControllerEvents:https://blog.csdn.net/VRunSoftYanlz/article/details/83099512
++++VRTK_InteractTouch:https://blog.csdn.net/VRunSoftYanlz/article/details/83120220
++++虚拟现实行业应用:https://blog.csdn.net/VRunSoftYanlz/article/details/88360157
++++VR实验:以太网帧的构成:https://blog.csdn.net/VRunSoftYanlz/article/details/82598140
++++实验四:存储器扩展实验:https://blog.csdn.net/VRunSoftYanlz/article/details/87834434
++++FrameVR示例V0913:https://blog.csdn.net/VRunSoftYanlz/article/details/82808498
++++FrameVR示例V1003:https://blog.csdn.net/VRunSoftYanlz/article/details/83066516
++++SwitchMachineV1022:https://blog.csdn.net/VRunSoftYanlz/article/details/83280886
++++PlaySceneManagerV1022:https://blog.csdn.net/VRunSoftYanlz/article/details/83280886
++++Unity5.x用户手册:https://blog.csdn.net/VRunSoftYanlz/article/details/81712741
++++Unity面试题ABC:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++Unity面试题D:https://blog.csdn.net/VRunSoftYanlz/article/details/78630838
++++Unity面试题E:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity面试题F:https://blog.csdn.net/VRunSoftYanlz/article/details/78630945
++++Cocos2dx面试题:https://blog.csdn.net/VRunSoftYanlz/article/details/78630967
++++禅道[zentao]:https://blog.csdn.net/VRunSoftYanlz/article/details/83964057
++++Lua快速入门篇(Xlua拓展):https://blog.csdn.net/VRunSoftYanlz/article/details/81173818
++++Lua快速入门篇(XLua教程):https://blog.csdn.net/VRunSoftYanlz/article/details/81141502
++++Lua快速入门篇(基础概述):https://blog.csdn.net/VRunSoftYanlz/article/details/81041359
++++框架知识点:https://blog.csdn.net/VRunSoftYanlz/article/details/80862879
++++游戏框架(UI框架夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80781140
++++游戏框架(初探篇):https://blog.csdn.net/VRunSoftYanlz/article/details/80630325
++++.Net框架设计:https://blog.csdn.net/VRunSoftYanlz/article/details/87401225
++++从零开始学架构:https://blog.csdn.net/VRunSoftYanlz/article/details/88095895
++++设计模式简单整理:https://blog.csdn.net/vrunsoftyanlz/article/details/79839641
++++专题:设计模式(精华篇):https://blog.csdn.net/VRunSoftYanlz/article/details/81322678
++++U3D小项目参考:https://blog.csdn.net/vrunsoftyanlz/article/details/80141811
++++Unity小游戏算法分析:https://blog.csdn.net/VRunSoftYanlz/article/details/87908365
++++Unity案例(Vehicle):https://blog.csdn.net/VRunSoftYanlz/article/details/82355876
++++UML类图:https://blog.csdn.net/vrunsoftyanlz/article/details/80289461
++++PowerDesigner简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86500084
++++Unity知识点0001:https://blog.csdn.net/vrunsoftyanlz/article/details/80302012
++++Unity知识点0008:https://blog.csdn.net/VRunSoftYanlz/article/details/81153606
++++U3D_Shader编程(第一篇:快速入门篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372071
++++U3D_Shader编程(第二篇:基础夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372628
++++Unity引擎基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78881685
++++Unity面向组件开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78881752
++++Unity物理系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78881879
++++Unity2D平台开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78882034
++++UGUI基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78884693
++++UGUI进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78884882
++++UGUI综合:https://blog.csdn.net/vrunsoftyanlz/article/details/78885013
++++Unity动画系统基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78886068
++++Unity动画系统进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78886198
++++Navigation导航系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78886281
++++Unity特效渲染:https://blog.csdn.net/vrunsoftyanlz/article/details/78886403
++++Unity数据存储:https://blog.csdn.net/vrunsoftyanlz/article/details/79251273
++++Unity中Sqlite数据库:https://blog.csdn.net/vrunsoftyanlz/article/details/79254162
++++WWW类和协程:https://blog.csdn.net/vrunsoftyanlz/article/details/79254559
++++Unity网络:https://blog.csdn.net/vrunsoftyanlz/article/details/79254902
++++Unity资源加密:https://blog.csdn.net/VRunSoftYanlz/article/details/87644514
++++PhotonServer简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86652770
++++编写Photon游戏服务器:https://blog.csdn.net/VRunSoftYanlz/article/details/86682935
++++C#事件:https://blog.csdn.net/vrunsoftyanlz/article/details/78631267
++++C#委托:https://blog.csdn.net/vrunsoftyanlz/article/details/78631183
++++C#集合:https://blog.csdn.net/vrunsoftyanlz/article/details/78631175
++++C#泛型:https://blog.csdn.net/vrunsoftyanlz/article/details/78631141
++++C#接口:https://blog.csdn.net/vrunsoftyanlz/article/details/78631122
++++C#静态类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630945
++++C#数据类型:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity3D默认的快捷键:https://blog.csdn.net/vrunsoftyanlz/article/details/78630838
++++游戏相关缩写:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++UnityAPI.Rigidbody刚体:https://blog.csdn.net/VRunSoftYanlz/article/details/81784053
++++UnityAPI.Material材质:https://blog.csdn.net/VRunSoftYanlz/article/details/81814303
++++UnityAPI.Android安卓:https://blog.csdn.net/VRunSoftYanlz/article/details/81843193
++++UnityAPI.AndroidJNI安卓JNI:https://blog.csdn.net/VRunSoftYanlz/article/details/81879345
++++UnityAPI.Transform变换:https://blog.csdn.net/VRunSoftYanlz/article/details/81916293
++++UnityAPI.WheelCollider轮碰撞器:https://blog.csdn.net/VRunSoftYanlz/article/details/82356217
++++UnityAPI.Resources资源:https://blog.csdn.net/VRunSoftYanlz/article/details/83155518
++++JSON数据结构:https://blog.csdn.net/VRunSoftYanlz/article/details/82026644
++++CocosStudio快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/82356839
++++Unity企业内训(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82634668
++++Unity企业内训(第1讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82634733
++++Unity企业内训(第2讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82861180
++++Unity企业内训(第3讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82927699
++++Unity企业内训(第4讲):https://blog.csdn.net/VRunSoftYanlz/article/details/83479776
++++Unity企业内训(第5讲):https://blog.csdn.net/VRunSoftYanlz/article/details/83963811
++++Unity企业内训(第6讲):https://blog.csdn.net/VRunSoftYanlz/article/details/84207696
++++钻哥带您了解产品原型:https://blog.csdn.net/VRunSoftYanlz/article/details/87303828
++++插件
++++计算机组成原理(教材篇):https://blog.csdn.net/VRunSoftYanlz/article/details/82719129
++++5G接入:云计算和雾计算:https://blog.csdn.net/VRunSoftYanlz/article/details/88372718
++++云计算通俗讲义:https://blog.csdn.net/VRunSoftYanlz/article/details/88652803
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
--_--VRunSoft:lovezuanzuan--_--ww4ww--_--