目录
一、开发前的准备
二、基础配置
三、Pico项目配置
四、添加基础功能
五、调整功能,摇杆往前推前进
1、为了方便开发,先在Pico开发者平台里下载预览工具
Pico开发者平台https://developer-global.pico-interactive.com/sdk?deviceId=1&platformId=1&itemId=17
3、在Pico和PC端中都打开Preview Tool,显示连接成功(同一局域网或有线连接)
1、切换安卓平台
2、在Package Manager中安装XRInteractionToolkit,并导入官方提供的3个Sample
3、在Package Manager中安装XRPluginManagement
6、在XRPlug-inManagement的Android和PC中勾选PICO
(不勾选PC的Pico,Preview Tool无作用)
1、添加XR Origin
2、给双手控制器添加预设
3、打开Preview Tool测试一下
(1)实现移动功能(位移和旋转)
1、添加LocomotionSystem组件(负责运动)
2、添加TeleportationProvider组件(负责传送)
3、添加SnapTurnProvider组件(负责旋转)
(I)LeftHandSnapTurnAction勾选UseReference
(II)RightHandSnapTurnAction取消勾选UseReference
这样就是左手柄摇杆负责旋转
4、添加ContinuousMoveProvider组件(负责移动)
(I)LeftHandSnapTurnAction取消勾选UseReference
(II)RightHandSnapTurnAction勾选UseReference
这样就是右手柄摇杆负责位移
(2)允许传送的前提准备
1、给地面添加TeleportationArea组件,这样就可以可以移动了。
(3)添加射线指示器
1、新建两个Sphere作为射线指示器,并赋予给XRInteractorLineVisual的Reticle
(5)添加人物碰撞
1、添加CharacterController和CharacterControllerDriver组件
(6)实现射线抓取物品(手柄侧键)
1、给物体添加 XRGrabInteractable 组件即可(记得勾选UseDynamicAttach)
2、XRRayInteractor负责射线抓取物品,关掉就可以关闭这个功能
(7)把手柄显示出来
1、添加两个射线指示器(DirectInteractor)
2、添加预设
3、右边手柄同理(复制左手柄并修改预设)
4、把手柄预制体添加给LeftDirectInteractor和RightDirectInteractor作为子物体,就可以把手柄显示出来,我这里先用Sphere代替
———————————————————分割线————————————————————
———————————————————2023.07.18———————————————————
(1)我把之前的Sphere换成了Oculus的手部模型(手部模型带有动画)
(2)传送
1、添加传送区域(Teleportation Area)脚本,且地面要有碰撞体
2、添加传送目标点(Teleportation Anchor),它可以让玩家传送到一个指定的位置和角度。
脚本上的Teleport Anchor Transform就是传送点,Match Orientation调整方向
(3)向前推动摇杆实现传送
目前只有按下手柄的Grip按键,传送才会生效。
一般来说,我们操作VR的习惯都是往前推动摇杆触发位移
在XRI Left Hand Locomotion内Teleport Select或Teleport Mode Activate,这两个动作都绑定了Primary2DAxis,表示的是摇杆的坐标位置,推动摇杆摇杆在xy轴上的位置会发生偏移
区别在于Directions
···Teleport Select是Everything,意为摇杆推向任何方向都可以激活传送
···Teleport Mode Activate 是North,意为摇杆推向北方(前方)可以激活传送
···如果我们想通过向前推动摇杆来激活传送,那么我们就选择Teleport Mode Activate。然后我们把XRController中的Select Action和Select ActionValue都换成Teleport Mode Activate
(4)把射线直线改为曲线
(5)实现向前推摇杆才显示射线
思路:控制XRRayInteracter脚本所在游戏物体的显示和隐藏
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit;
public class TeleportationController : MonoBehaviour
{
public InputActionProperty m_teleportModeActivate;
public InputActionProperty m_teleportModeCancel;
private InputAction teleportModeActivate;
private InputAction teleportModeCancel;
public XRRayInteractor teleportInteractor;
void Start()
{
teleportModeActivate = m_teleportModeActivate.action;
teleportModeCancel = m_teleportModeCancel.action;
EnableAction();
}
private void OnDestroy()
{
DisableAction();
}
void Update()
{
if (CanEnterTeleport())
{
SetTeleportController(true);
return;
}
if (CanExitTeleport())
{
SetTeleportController(false);
return;
}
}
private void SetTeleportController(bool isEnable)
{
if (teleportInteractor != null)
{
teleportInteractor.gameObject.SetActive(isEnable);
}
}
private bool CanEnterTeleport()
{
bool isTriggerTeleport = teleportModeActivate != null && teleportModeActivate.triggered;
bool isCancelTeleport = teleportModeCancel != null && teleportModeCancel.triggered;
return isTriggerTeleport && !isCancelTeleport; //判断是否触发传送且没有按下取消传送的键
}
private bool CanExitTeleport()
{
bool isCancelTeleport = teleportModeCancel != null && teleportModeCancel.triggered;
bool isReleaseTeleport = teleportModeActivate != null && teleportModeActivate.phase == InputActionPhase.Waiting;
return isCancelTeleport || isReleaseTeleport; //判断是否按下取消传送的键或者释放了之前推动的摇杆
}
private void EnableAction()
{
if (teleportModeActivate != null && teleportModeActivate.enabled)
{
teleportModeActivate.Enable();
}
}
private void DisableAction()
{
if (teleportModeActivate != null && teleportModeActivate.enabled)
{
teleportModeActivate.Disable();
}
}
}
脚本解释:
(I)Input Action Asset 中有一个 Teleport Mode Cancel 的动作,绑定的是“按下 Grip 键”这个操作,也就是按下手柄的 Grip 键可以取消传送,我们也将这个功能加入脚本。
(II)触发传送(显示传送射线)的条件:向前推动手柄摇杆,并且没有按下 Grip 键
(III)不显示传送射线的条件:按下 Grip 键或者手柄的摇杆处于原始的位置(向前推动摇杆并且释放最终也是回到了原始位置)
(IV)EnableAction 的作用:InputAction 类的变量需要调用它的 Enable 方法后才能被激活。
(6)重新调整一下层级,给LeftHandController添加TeleportationController,并把XRRayInteractor取消激活(因为是控制游戏物体的显隐,所以LeftHandController和XRRayInteractor脚本不能挂载到同一物体上)。
同时把Teleport Interactor的XRController的Enable Input Tracking关闭,避免和父物体冲突(手部模型的父物体必须要有XRController(Action-based)脚本,并且要开启Enable Input Tracking)。
TeleportationController脚本仅仅是用于显示和隐藏射线,真正触发传送的还是Teleport Interactor物体上的XRController中的Select Action
1、先创建一些世界空间的UI,并给Canvas添加脚本Tracked Device Graphic Raycaster
2、这一步我们开始制作用于UI射线的射线。分别在LeftHand Controller 和 RightHandController 下创建 UI Ray Interactor 游戏物体。
3、可以复制Teleport Interactor,UI的射线改成直线 StraightLine
4、可以删除掉XRController(Teleport Interactor需要保留XRController是因为改了摇杆往前推瞬移,需要修改XRController,而UI射线可以沿用父物体的XRController)
5、过滤UI射线的目标。我们的UI射线只针对UI,如果不设置层级的话这条射线也会和位移射线冲突,所以需要调整到UI层级。同理位移的射线需要筛掉UI层级
6、另外,现在我们的UI射线是一直存在的。我们可以优化一下,手部如果没有指向UI,那么不显示射线,当射线照射到UI上的时候才能显示。这里实现方法很简单:只需要把未激活时候的颜色透明度改为0就好了。