手部菜单 Hand menu
手部菜单允许用户为经常使用的功能快速调出手边附加的UI。为了防止在与其他物体互动时出现错误激活,手部菜单提供了'Require Flat Hand(需要放平手)和'Use Gaze Activation(使用凝视激活)'等选项。建议使用这些选项来防止不必要的激活。
手部菜单示例
HandMenuExamples.unity 场景在MRTK/Examples/Demos/HandTracking/Scenes
文件夹下。当它运行时,场景将只激活当前选择的菜单类型。
你可以在 MRTK/Examples/Demos/HandTracking/Prefabs
文件夹下找到这些手部菜单预制体。
HandMenu_Small_HideOnHandDrop 和 HandMenu_Medium_HideOnHandDrop
这两个示例简单地激活和禁用MenuContent对象,以便在**OnFirstHandDetected()和OnLastHandLost()**事件上显示和隐藏菜单。
HandMenu_Large_WorldLock_On_GrabAndPull
对于需要更长的交互时间的更复杂的菜单,建议世界锁定(world-lock)菜单。在本例中,除了在**OnFirstHandDetected()*和OnLastHandLost()**事件上激活和禁用MenuContent之外,用户还可以抓取并锁定菜单。
背板的ManipulationHanlder
使它可以抓取和移动。On Manipulation Started事件,SolverHandler.UpdateSolvers 被停用以锁定菜单。此外,它显示了Close button ,以允许用户在任务完成时关闭菜单。在 On Manipulation Ended事件,它调用HandConstraintPalmUp.StartWorldLockReattachCheckCoroutine 允许用户通过举起并看着手掌将菜单拿回来。
Close 按钮重新激活SolverHandler.UpdateSolvers 和隐藏MenuContent。
HandMenu_Large_AutoWorldLock_On_HandDrop
这个例子类似于HandMenu_Large_WorldLock_On_GrabAndPull。唯一的区别是,菜单将自动锁定手动下降。这是通过不隐藏**OnLastHandLost()**事件上的MenuContent来实现的。抓取和推拉行为与HandMenu_Large_WorldLock_On_GrabAndPull的例子相同。
脚本
HandConstraint
行为提供了一个solver,该solver将跟踪的对象约束到一个安全的区域,以供手动约束的内容(比如手动UI、菜单等)使用。安全区域是指不与手相交的区域。 HandConstraint
的一个派生类称为HandConstraintPalmUp
还包括证明的常见行为激活解决面临的手掌是当用户跟踪对象。
请参阅每个HandConstraint
属性可用的工具提示以获得额外的文档。下面将更详细地定义一些属性。
Safe Zone:安全区指定在哪里约束内容。建议将内容放置在尺骨侧,避免与手重叠,提高交互质量。通过将手的方向投影到与摄像机视角正交的平面上,并对手周围的边界框进行射线投射,计算出安全区域。安全区被定义为与
IMixedRealityHand
一起工作,但也可以与其他控制器类型一起工作。建议探讨不同的控制器类型上每个安全区域代表什么。Follow Hand Until Facing Camera 激活后,solver将手动旋转,直到菜单与视线完全对齐,此时它将面对摄像头。这是通过改变HandConstraintSolver中的SolverRotationBehavior来实现的,从LookAtTrackedObject到LookAtMainCamera作为solver 变量的GazeAlignment 角度。
Activation Events:当前
HandConstraint
触发4个激活事件。这些事件可以在许多不同的组合中使用来创建独特的HandConstraint
行为,请查看MRTK/Examples/Demos/HandTracking/Scenes/
场景来获得这些行为的例子。- OnHandActivate:当一只手满足IsHandActive方法时触发。
- OnHandDeactivate:当IsHandActive方法不再满足时触发。
- OnFirstHandDetected:手跟踪状态从无手变为有手时发生。
- OnLastHandLost:手跟踪状态 从视野中至少有一只手变为视野中没有手时发生。
Solver Activation/Deactivation Logic:当前推荐的激活和取消激活
HandConstraintPalmUp
逻辑是这样做通过使用SolverHandler 的UpdateSolver的值,而不是通过禁用/启用对象。这可以在示例场景中通过基于编辑器的钩子(hooks)看到,这些钩子是在附加菜单的ManipulationHandler的"OnManipulationStarted/Ended"事件后触发的。- Stopping the hand-constraint logic:当尝试设置手动约束对象停止(以及不运行激活/停用逻辑)时,将UpdateSolver设置为False,而不是禁用HandConstraintPalmUp。 *如果您希望启用基于凝视(甚至非基于凝视)的重新连接逻辑(Reattach logic),然后调用HandConstraintPalmUp . StartWorldLockReattachCheckCorotine()函数。这将触发一个协程,继续检查是否满足"IsValidController" 标准,并将UpdateSolver设置为True(或禁用该对象)
- Starting the hand-constraint logic:当尝试设置手动约束对象以再次跟随您的手时(根据它是否满足激活条件),将SolverHandler的UpdateSolver设置为true。
Reattach Logic:当前的
HandConstraintPalmUp
能够自动重新附加目标对象到被跟踪的点,而不管SolverHandler的UpdateSolver是否为真。这是通过调用HandConstraintPalmUp的StartWorldLockReattachCheckCorotine()函数来完成的,在它被锁定之后(在本例中,它有效地将SolverHandler的UpdateSolver设置为False)。