参考https://academy.vrtk.io/
https://github.com/ExtendRealityLtd/VRTK.Prefabs#getting-started
https://github.com/ExtendRealityLtd/Tilia.SDK.OculusIntegration.Unity/blob/master/Documentation/HowToGuides/Installation/README.md
一,基本绑定
1.导入Oculus Integration
packages中导入oculus desktop
2.将vrtk和OculusIntegration.Unity导入到packages
选中Packages——>右键show in explorer-->在manifest.json添加下面的代码将自动导入
{
"scopedRegistries": [
{
"name": "npmjs",
"url": "https://registry.npmjs.org/",
"scopes": [
"io.extendreality"
]
}
],
"dependencies": {
"io.extendreality.vrtk.prefabs": "X.Y.Z", //vrtk对应的版本号
"io.extendreality.tilia.sdk.oculusintegration.unity": "X.Y.Z" //OculusIntegration.Unity 对应版本号
...
}
}
3.Player从Project Settings窗口的左侧菜单中选择。
在Player设置面板中,展开XR Settings。
在XR Settings确保Virtual Reality Supported选项被选中。
4.将OVRCameraRig拖入场景中并添加LinkedAliasAssociationCollection脚本,并将对应组件进行绑定,
5.将TrackedAliasFacade(中介)拖入场景并将OVRCameraRig添加到Elements下面,并在LeftControllerAlias添加正方形(0..1,0.1,0.3)作为手臂,接入设备运行就可以左右手柄变成方块跟随手移动
二,动作
-
导入控制器预制件(UnityXR.OpenVR.RightController或UnityXR.Oculus.RightController)
2.选择控制器上的一个按钮绑定事件,按钮按下时隐藏地面,按钮松开后显示地面
该Unity Button Action组件具有4个可以关联的事件:
激活状态已更改:当操作的激活状态从上一个状态更改时,发出此消息。
已激活:按下按钮时发射。
值已更改:当按钮值的状态发生更改时发出,例如从按下变为释放。
禁用:释放按钮且不再按下时发射。
3.自定义的Unity Button Action
创建一个空物体,添加Unity Button Action脚本,同上绑定事件,然后指点一个按钮激活
运行项目按下右手柄的A键地面消失,松开地面显示。
4.添加Unity轴动作
有两种Unity轴动作:
Unity 1D Axis(Unity 1D轴):侦听单个轴上的更改,并为该轴更改发出一个float值。
Unity 2D轴:侦听两个轴上的更改,并发出将两个轴更改组合在一起的Vector2值。
在Unity Axis 1D Action和Unity Axis 2D Action组件具有可以挂到4个事件:
激活状态已更改:当操作的激活状态从上一个状态更改时,发出此消息。
已激活:当轴值不再是默认值时发出。
值更改:轴值更改时发出。
禁用:当轴值返回到设置的默认值时发射。
创建一个名为的新轴VRTK_Axis10_RightTrigger,该轴将使我们能够在正确的控制器的触发点上拾取轴的变化。
Material在Unity Project中创建一个新项,并将其保留在Standard着色器上,但将更Rendering Mode改为Transparent。
在组件的Axis Name参数中Unity 1D Axis Action,输入VRTK_Axis10_RightTrigger作为值。这是我们与Unity Input Manager定义的右控制器触发轴关联的预定义名称。
场景脚本改变材质的透明度
using UnityEngine;
public class OpacityChanger : MonoBehaviour
{
public Material target;
public void UpdateOpacity(float alphaValue)
{
Color color = target.color;
color.a = alphaValue;
target.color = color;
}
}
在Value Changed事件发出时执行
运行项目扣动右手柄的扳机键可以看到小球透明度改变。
5.创建代理操作和链接操作
我们将把动作功能移动到代理动作,然后将按钮按下动作和键盘动作链接到这个新创建的代理动作。这会将我们的输出功能移到一个位置,并允许我们从许多不同的动作中调用它。
创建空物体添加Boolean Action脚本,然后绑定按下和松开的事件
展开Sources参数,然后在Size参数字段中输入所需的其他操作数进行监视。在这个例子中,我们想观看其他两个动作(菜单键Unity Button Action和空格键Unity Button Action),所以进入2到Sizes参数字段。
之前两个按钮绑定的事件可以删除了
运行项目,右手柄A键和空格键可以执行刚才的动作。
三,指针和位移
1.直指针
笔直指针预制件从起点到最大指定长度投射一条直线,或者直到指针光束与有效目标碰撞为止。
将ObjectPointer.Straight预制件拖入场景
跟踪的目标
该Follow Source参数确定指针应在场景中跟踪哪个GameObject,TrackedAlias -> Aliases -> RightControllerAlias到组件的Follow Source参数中
触发的按键
将UnityXR.OpenVR.RightController -> Trackpad -> Touch[17]GameObject 拖放到组件Activation Action
2.弯曲的指针
弯曲指针(也称为贝塞尔曲线或抛物线形指针)从原点开始向前弯曲一定距离,然后向下投射一条直线,直到它与对撞机碰撞为止。用贝塞尔曲线表示该向前然后向下的投影,该曲线基本上画出了光束原点和最终目标点之间的曲线。
同直指针添加跟随的目标和触发的按键
3.移动
传送有两种主要类型:
即时-用户指定目的地位置(例如,用控制器指针标记),然后通常通过相机淡入淡出立即出现在目的地,以减少晕动病。
破折号-用户指定目标位置,并且用户会随着时间的推移以线性运动逐渐移动,直到他们到达其目标位置。
将Teleporter.Instant拖入场景
Target所述参数Teleporter Facade组件确定哪些游戏物体实际的瞬间移动方法移动。通常,“摄影机装备”是我们要移动的GameObject,因为它包含我们的虚拟玩家。
Offset参数确定另一个GameObject,该对象可用来描述在移动时要考虑Target的偏移量,在这种情况下,偏移量是用户的耳机位置相对于其游戏区域的差。
要执行此相机闪烁,传送器需要了解场景中要应用淡入淡出的相机。该Camera Validityon参数TeleporterFacade组件允许我们指定链接这件事的简单方法
现在,我们在场景中有一个可以正常使用的传送器,我们只需要一种方法就可以告诉传送器移动到所需的目标位置。
运行场景点击右手柄的遥感键就可以实现移动了。
4.添加箭头
查找 arrow prefab并添加到对应位置,设置坐标如下图
创建两个新的空GameObject ,并将OVRInputAxis2DAction 脚本附加到每个脚本。
将两个OVRInputAxis2DAction 脚本的touch属性值设置为Primary Thumbstick 。将控制器属性值分别设置为L Touch 和R Touch
再在他下面添加两个空物体并挂上Vector2ToFloat 和FloatAction
将AxisRotator 预制件拖入并添加相应组件如下图
将 TeleporterFacade中 Offset Usage 设置为Offset Always With Destination Rotation.
然后运行项目,现在可以用触控按钮控制视角的方向了。
5.对玩家可以传送的地方增加限制
新建新层命名为Teleportable
将地面层改为Teleportable
创建一个空物体(TeleportRule)添加 AnyLayerRule脚本,并把layer mask设置为 Teleportable
将TeleportRule拖到TeleporterFacade和PointerFacade中TargetValidity选择中
运行项目,现在只有点击地板才会显示可移动,其他地方显示红色不可移动
6.探索如何添加“传送目标”,从而允许播放器将其传送光线捕捉到固定位置。
新建空物体名TeleportTarget,添加两个脚本ActionDispatcher,TransformDataProxyEmitter
并将指定如下图的脚本
搜索DestinationPoint Variant预制件,添加多个到想要传送的位置,将他们层级改为Teleportable,并指定脚本如下图
并在PointerFacade添加如下图的方法
现在运行项目,就可以传送到目标点了
7.右键隐形传送
创建空物体命名为TeleporterActivation.R,添加TeleporterActivation 脚本,并将Controller 字段设置为R Touch。
创建空物体命名为TeleporterSelection.R,添加TeleporterSelection 脚本,并将Controller 字段设置为R Touch。
在TeleporterSelection 脚本游戏对象下创建两个新的空GameObject,将FloatAction 脚本附加到每个对象。
将这两个物体拖到TeleporterSelection 中如下图
将AxisRotatorFacade 脚本中的“ 横轴” 和“ 纵轴” 字段重新分配给两个新的FloatAction 脚本游戏对象。
禁用OVRInputTouch,OVRInputButtonAction和OVRIInputAxis2DAction 脚本游戏对象的右手。
将右侧PointerFacade 脚本中的“ 激活操作” 和“ 选择操作” 字段分别重新分配给TeleporterActivation 和TeleporterSelection 脚本游戏对象。
运行项目,现在要按下右扳机键射线才出现
8.左键控制转向
禁用场景中的左手ObjectPointerCurved 预制件,并禁用左手的OVRInputTouch,OVRInputButtonAction 脚本游戏对象。
在项目窗口中,找到AxesToVector3 预制并将其拖到场景中。
在附加到预制对象的AxesToVector3Facade 脚本中,将“ 轴使用类型” 字段下拉列表设置为“ Directional”。
将“ Lateral Axis” 字段设置为位于左侧OVRIInputAxis2DAction 脚本游戏对象下的X轴值FloatAction 脚本游戏对象。
将“ Lateral Speed Multiplier” 字段值设置为45,将“ Longitudinal Speed Multiplier” 字段值设置为0。
添加Vector3Cache 脚本,将他拖到 Processed 下面调用CachedData方法
再添加CameraColorOverlay 脚本,在Vector3Cache 脚本中添加CameraColorOverlay / Blink。
在CameraColorOverlay 脚本中,将SceneCameras 场景对象分配给“ Camera Validity” 字段。
在项目中找到TeleportFade 材质,并将其分配给CameraColorOverlay 脚本中的“ Overlay Material ” 字段,然后将“ Remove Duration” 字段的值更改为0.5。
具体如下图
创建一个新的空GameObject,命名为SnapRotator,添加Vector3ToVector2 脚本和Vector2ToVector3 脚本,TransformEulerRotationMutator
并做如下操作
9.阻止玩家浏览对象内部(屏幕变黑)
在场景中禁用Teleporter.Instant预制对象下的SnapToFloor 对象。
在项目中找到CollisionFader 预制件,并将其拖动到HeadsetAlias 场景对象下的场景中。
在CollisionFader 预制件附带的CameraColorOverlay 脚本中,将CameraValidity 字段设置为SceneCameras 场景对象。
创建两个名为FadeCamera 和FadeOut的新图层。将CollisionFader 预制对象放在FadeCamera层上。
将橱柜场景对象放在FadeOut 层上。
打开顶部栏中的“ 编辑” 菜单,然后选择“ 项目设置”。导航到“ 物理” 选项卡。
切换碰撞矩阵,以便FadeCamera 层仅与FadeOut 层碰撞。
将OVRCameraRig 场景游戏对象下“ 摄影机” 脚本上的“ ClearFlags” 字段值更改为“ 纯色”,然后将颜色设置为黑色。
四,交互(unity oculus教程)
1.添加手和手柄模型
添加手
在项目中找到CustomHandLeft 和CustomHandRight 预制件,并将它们添加到场景中相应的LeftControllerAlias 和RightControllerAlias 预制件下面。
在CustomHandLeft 和CustomHandRight 场景对象上禁用OVRGrabber 脚本。
在LeftControllerAlias 和RightControllerAlias 层次结构中,禁用Cube 对象的MeshRenderer 组件。
将CustomHandLeft 和CustomHandRight 场景对象的层设置 为“ 忽略射线广播” 。
戴上HMD 并比较真实手和虚拟手的位置。
添加手柄
在项目视图中的Oculus / VR / Meshes / OculusTouchForQuestAndRiftS 文件夹中找到OculusTouchForQuestAndRiftS_Left 和OculusTouchForQuestAndRiftS_Right 模型 ,并将它们分别添加到LeftControllerAlias 和RightControllerAlias 场景对象层次结构中。
2.添加交互器
在项目中找到Interactor 预制件,然后在场景中的LeftControllerAlias 和RightControllerAlias 预制件下面添加一个。
在每个Interactor 对象层次结构中的ExampleAvatar对象上禁用MeshRenderer 。
在场景中创建两个新的空GameObject ,然后使用检查器中的“添加组件” 按钮将OVRInputAxis1DAction 和FloatToBoolean 脚本添加 到每个对象。
在FloatToBoolean 脚本中,将“ Positive Bounds” 字段设置为0.75与1之间。
在每个OVRInputAxis1DAction 脚本中,将Controller 字段设置为相应的L Touch 和R Touch 值,并将Axis 字段设置为Primary Hand Trigger 。
使用检查器中的“添加组件” 按钮将BooleanAction 脚本添加到每个对象。
在OVRInputAxis1DAction 脚本中,在ValueChanged 单操作列表下添加一个新的单操作对象。添加父GameObject 并将下拉列表设置为FloatToBoolean / DoTransform 。
在FloatToBoolean 脚本中,在“ 转换后的布尔动作”列表下添加一个新的布尔动作对象。添加父GameObject 并将下拉列表设置为BooleanAction / Receive 。
在场景中Interactor 预制件上的InteractorFacade 脚本中,将“ 抓取动作” 字段设置为相应的BooleanAction 脚本游戏对象。
具体如下图
3,添加交互物体
将Interactable.Primary_Grab.Secondary_Swap 预制件拖入场景,并将他的参数设置和想要互动的物体参数一致,然后把
禁用DefaultMesh 对象,将想要物体拖入他里面,位置归零代替DefaultMesh
4.添加OVR速度跟踪器(丢物体出去物体可以获得你的速度和角度)
将OVRAnchorVelocityEstimator 脚本添加到LeftHandAnchor,RightHandAnchor 和CenterEyeAnchor 场景对象。
在每个OVRAnchorVelocityEstimator 脚本中,将Tracked GameObject 字段设置为父游戏对象,并将Relative To 字段设置为TrackingSpace(OVRCameraRig也可以) 场景对象。
在附加到OVRCameraRig 场景对象的LinkedAliasAssociationCollection 脚本中,将Headset Velocity Tracker 字段设置为CenterEyeAnchor 场景对象,将Left Controller Velocity Tracker 字段设置为LeftHandAnchor 场景对象,并将Right Controller Velocity Tracker 字段设置为RightHandAnchor 场景对象。
对于每个Interactor 预制件,将InteractorFacade 脚本的Velocity Tracker 字段设置为相应的LeftControllerAlias 和RightControllerAlias。
5.抓取时隐藏手臂
对于每个Interactor 预制件,在InteractorFacade 脚本中,在Grabbed 和Ungrabbed InteractableFacade操作列表下创建一个新的InteractableFacade 操作对象,并分配相应的CustomHandLeft 和CustomHandRight 场景对象。
将下拉功能值设置为GameObject / SetActive,然后将“未抓取” 列表中的操作切换为true。
6.拉取抽屉
将DirectionalJointDrive 预制件放入场景,复制一个抽屉模型替换为Meshes 对象
注意如何限制抽屉进入后的位置,可以把Target value设置为1,如何运行看抽屉到哪里然后移动DirectionalJointDrive直到完全进入记录他的位置之后赋值给他
7.位置摆放提示
InteractableSnapZone 拖入要放置的位置,将要放置的钥匙替换DefaultHighlightMesh,然后更换发光材质
添加新层keylayer,将原来的钥匙层改为keylayer,创建空物体添加脚本AnyLayerRule 脚本。将“ Layer Mask” 字段下拉列表的值设置为KeyLayer,拖入到InteractableSnapZone中Snap Validity属性。
并指定钥匙插入后的触发事件
四,交互(vrtk教程可以忽略)
Touch -交互器与有效的可交互对象发生物理碰撞的位置的概念。
Grab -交互器可在何处动作以通知有效的触摸式可交互对象该交互器要启动可交互对象的抓取功能的概念。
1.添加交互器
将之前cube换成Interactor,指定他的触发条件和跟随物体
2.添加互动(对象)
Interactable.Primary_Grab.Secondary_Swap预制件
现在运行场景扣动右手柄的扳机键就可以将物体拿起来。但是你丢物体出去,物体获取不到你的丢的力度
3.OVR速度跟踪器(丢物体出去物体可以获得你的速度和角度)
https://github.com/ExtendRealityLtd/Tilia.SDK.OculusIntegration.Unity
修改package文件
{
"scopedRegistries": [
{
"name": "npmjs",
"url": "https://registry.npmjs.org/",
"scopes": [
"io.extendreality"
]
}
],
"dependencies": {
"io.extendreality.tilia.sdk.oculusintegration.unity": "X.Y.Z",
...
}
}
将OVRAnchorVelocityEstimator拖入OVRCameraRig中如下图操作
现在运行项目,丢物体,物体将获得速度和角速度
五,UI交互
1.切换场景
创建一个新的空游戏对象,并附加PauseMenuLogic 脚本。
将Teleporter_Instant 场景对象分配给Teleporter 字段,将PlayAreaAlias 对象分配给PlayArea 字段,并将Headset Alias 对象分配给HeadOrientation 字段。
在“ 暂停区域” 场景对象层次结构中找到“ 传送目标” 对象,并将其分配给PauseMenuLogic 脚本的“ 暂停位置” 字段,并将父游戏对象设置为“ 游戏位置” 字段。
创建一个新的空游戏对象,并附加OVRInputButtonAction 脚本。将“ 控制器” 和“ 按钮” 字段分别设置为L touch 和“ 开始” 。
在OVRInputButtonAction 脚本的Activated boolean action列表中 添加一个新的布尔动作,并分配PauseMenuLogic 脚本对象。
将下拉菜单设置为PauseMenuLogic / SwitchRooms。
2.UI响应
将UIHelpers 拖入场景中,
创建UI更改为World Space,调整大小和位置,删除GraphicsRaycaster 组件并添加OVRRaycaster 脚本。
禁用UIHelperLaserPointer,在PauseMenuLogic添加属性
注意采用textmeshPro显示效果更好,要勾选Extra Padding
3.物理UI交互
在LeftControllerAlias和