Unity Meta Quest 一体机开发(十三):【手势追踪】自定义交互事件 EventWrapper


此教程相关的详细教案,文档,思维导图和工程文件会分享在 Spatial XR 社区。这是一个高质量 XR 开发者社区,博主目前在内担任 XR 开发的讲师。该社区提供专人答疑、完整进阶教程、从零到一项目孵化保姆服务(包含产品上架App lab)、投资|融资对接、工程文件下载等服务。

社区链接:
SpatialXR社区:完整课程、项目下载、项目孵化宣发、答疑、投融资、专属圈子

在这里插入图片描述


📕教程说明

这篇教程将会介绍如何用 Meta XR SDK,自定义交互事件触发时执行的逻辑。最后会实现一个功能:用手指点击 UI 按钮后,在前方召唤一把剑。

环境配置可参考:https://blog.csdn.net/qq_46044366/article/details/133967343

配置一个基本的玩家物体可以参考前几期教程:https://blog.csdn.net/qq_46044366/article/details/134097455

系列教程专栏:https://blog.csdn.net/qq_46044366/category_12118293.html

配套的视频链接:
上半部分:https://www.bilibili.com/video/BV1rK4y1B7Zs
下半部分:https://www.bilibili.com/video/BV1vT4y1p7EK

​电脑操作系统:Windows 11

使用的 VR 设备:Meta Quest 3(Quest 系列都适用)

使用的 Unity 版本:2021.3.5 LTS (这里推荐使用 2021 及以上的 LTS 版本)

Meta XR SDK 版本:v57

官方文档:https://developer.oculus.com/documentation/unity/unity-gs-overview/

Event Wrapper 介绍文档:
https://developer.oculus.com/documentation/unity/unity-isdk-event-wrappers/

最终效果:

在这里插入图片描述


📕交互事件概述

交互事件是 XR 开发中经常使用的一个东西。当一个交互动作发生的时候,可能会伴随着一些事情的发生。比如点击一个 “游戏开始” 的UI按钮,就会触发 “游戏开始” 事件,从而对游戏场景里的一些东西进行初始化。这个时候 “点击UI按钮” 就是一个交互事件,对游戏场景里的东西初始化就是这个事件触发后需要执行的事。在 Meta XR SDK 中,交互事件一般会在一个交互过程中的不同状态下触发,以点击 UI 按钮为例,这个动作属于 Poke 交互,我们知道交互的发生需要有 Interactor 和 Interactable 两个对象的参与,那么 Poke 交互对应的 Interactor 在手上,对应的 Interactable 在 UI 按钮物体上。对于 UI 按钮这个 Interactable 来说,当手指靠近按钮的时候,按钮自身会进入到 Hover 状态,这个时刻就可以当作一个交互事件发生了。然后当手指点击到按钮,将按钮按到底的时候,按钮自身会进入到 Select 状态,这边需要注意的是对于一个可以被推动的按钮来说,必须要推到底,也就是推到按钮 Surface 的位置才会进入到 Select 状态,当手指刚刚触碰到按钮表面的时候是不会进入到 Select 状态的。那么进入到 Select 状态这个瞬间也可以当作一个交互事件发生了。

其实前几期教程我们已经有接触到交互事件,我这里是在场景中添加了一个 Poke 教程里配置的 UI 按钮(教程链接:Unity Meta Quest 一体机开发(十二):【手势追踪】Poke 交互 - 用手指点击由 3D 物体制作的 UI 按钮)。

在这里插入图片描述

比如按钮身上的 Interactable Color Visual 脚本,这个脚本能够实现物体在进入不同状态的时候改变物体的颜色。那么这就和交互事件的概念比较像了,进入到不同的状态相当于不同交互事件的触发,改变颜色相当于事件触发后执行的事。Meta XR SDK 会自动检测相应的交互事件什么发生,但是这个脚本把交互事件触发后执行的逻辑写死了,它只能改变物体的颜色,无法处理其他的事。而接下来我会介绍如何去自定义交互事件触发时执行的逻辑。

📕自定义交互逻辑

Meta XR SDK 提供了一个 EventWrapper 的概念,叫做事件包装器(官方文档:https://developer.oculus.com/documentation/unity/unity-isdk-event-wrappers/)。它能够处理 Interaction SDK 中的一些交互事件,并且我们能够自定义交互事件发生时执行的逻辑。如下图所示,Meta 提供了不同类型的 EventWrapper:

在这里插入图片描述

我们这期教程主要关注可交互物体,也就是 Interactable 的交互事件,那么可以使用这两种 EventWrapper:InteractableUnityEventWrapper 和 PointableUnityEventWrapper。这两个脚本有一些相同的交互事件,也有一些不同的交互事件。不过最常用的是下图中标出的 4 个共同的交互事件:

在这里插入图片描述

Hover 是悬停的状态,Interactor 靠近 Interactable 的时候触发。当交互动作完成的时候,也就是 Interactor 选中 Interactable 时,由 Hover 状态转变为 Select 状态。

我们这期教程会介绍 InteractableUnityEventWrapper 脚本的用法,它用起来会稍微简单一点。

我们需要把 InteractableUnityEventWrapper 脚本添加到 UI 按钮物体上:

在这里插入图片描述
我们可以在脚本的 Inspector 面板上看到这个脚本提供的交互事件。

⭐方法一:Inspector 面板赋值

Event Wrapper 提供交互事件,并且检测交互事件什么时候触发。但是触发交互事件后需要执行什么事情需要我们自己处理。第一种处理方式是在 Event Wrapper 脚本的 Inspector 面板上直接进行赋值。我们会实现按下 UI 按钮后在前方生成一把剑的功能,判断什么时候按下 UI 按钮会由 Event Wrapper 来处理,我们这里把按下 UI 按钮视为 Select 交互事件触发,也就是将按钮按到底的时候,触发 Select 事件,然后执行生成剑的逻辑。那么我们需要自己写个脚本实现生成物体的功能,然后让 Event Wrapper 在判断到 Select 事件触发时去调用我们脚本中生成物体的方法。

脚本如下:

using Oculus.Interaction;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemSpawner : MonoBehaviour
{
    public GameObject spawnObj;
    public Transform spawnPoint;

    public void SpawnItem()
    {
        GameObject obj = GameObject.Instantiate(spawnObj);
        obj.transform.position = spawnPoint.position;
    }
}

spawnObj 是需要生成的物体,spawnPoint 是物体生成的位置,SpawnItem 方法负责将需要生成的物体生成在需要生成的位置上。

然后将这个脚本挂载到按钮物体身上,并且在面板上进行赋值:

在这里插入图片描述

我这边将一个剑的模型制作成了 Prefab,拖到了 spawnObj 变量上。然后在按钮物体上新建了一个子物体,作为生成剑的位置。

在这里插入图片描述
我们可以在场景中调整 SpawnPoint 子物体的位置。

然后点击 InteractableUnityEventWrapper 脚本上的 WhenSelect 事件的 “+”号,进行事件触发执行逻辑的添加:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

当按钮被按到底的时候, WhenSelect 事件触发,然后调用 SpawnButton 物体上的 ItemSpawner 脚本中的 SpawnItem 方法,在设定的生成点生成剑的游戏物体。

⭐方法二:纯代码处理

我们修改 ItemSpawner 脚本:

using Oculus.Interaction;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemSpawner : MonoBehaviour
{
    public GameObject spawnObj;
    public Transform spawnPoint;

    private InteractableUnityEventWrapper eventWrapper;

    void Start()
    {
        eventWrapper = GetComponent<InteractableUnityEventWrapper>();
        eventWrapper.WhenSelect.AddListener(SpawnItem);
    }
    private void OnDestroy()
    {
        eventWrapper.WhenSelect.RemoveListener(SpawnItem);
    }

    public void SpawnItem()
    {
        GameObject obj = GameObject.Instantiate(spawnObj);
        obj.transform.position = spawnPoint.position;
    }
}

和方法一的区别是,我们在代码中获取了 InteractableUnityEventWrapper 脚本,然后用代码为 InteractableUnityEventWrapper 的 WhenSelect 事件添加了事件触发后需要执行的方法。

InteractableUnityEventWrapper 的 WhenSelect 事件的监听器(AddListener 方法)需要传入一个 UnityAction 类型的参数。UnityAction 是 Unity 中的一种委托类型,可以绑定无返回值,无参数的方法。我们写的 SpawnItem 方法正好符合条件,所以能直接传入 AddListener 方法中,相当于我们把 SpawnItem 方法的执行委托给了 Event Wrapper,当 Event Wrapper 检测到 WhenSelect 事件触发后,会执行我们委托的事情,也就是调用 SpawnItem 方法,在设定的生成点生成指定的物体。

另外需要注意的是,当我们调用了 AddListener 后,需要在合适的地方调用 RemoveListener 方法,将事件监听器移除掉。

如果我们选用纯代码的方法处理交互事件,就不用在 Unity 的 Inspector 面板中拖拽赋值了。然后 ItemSpawner 脚本需要和 InteractableUnityEventWrapper 脚本挂载到同一个游戏物体身上。

最终效果:

在这里插入图片描述

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YY-nb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值