是谁在我耳边说话: 一种事件驱动的玩家语音传播控制系统 —— PlayerVoiceSystem
引言
在社区世界的创作中,随着社区逐渐庞大和复杂,各式各样的玩家对于世界的需求也日益多样化。为了提升世界的包容性,创作者有时会希望在世界中提供一些针对特定玩家群体的功能或体验,并对世界进行相应的分区。
视觉上的分区可以通过世界视觉结构的设计来直观实现。然而,在虚拟世界中,一堵墙或一个密闭房间并不能自然地为玩家带来声音隔离。嘈杂的环境可能会让玩家难以听清彼此的声音,给交流带来不便。因此,对世界中玩家语音传播的管理和控制是不可或缺的。
玩家语音系统 (PlayerVoiceSystem) 正是为了解决这一问题而设计的组件包。它提供了一套基于事件驱动的系统,允许创作者在世界中定义不同的语音区域,并根据玩家所在的区域控制他们的语音传播。通过使用 玩家语音系统,创作者可以轻松实现语音隔离、分区和定向传播等功能,从而提升玩家在世界中的交流体验。
你真的需要这个系统吗?
社区中存在多种实现玩家语音控制的组件包。通常来说,这些用于控制玩家语音传播的组件是 互斥 的,这意味着在同一个世界中只能使用其中的一个组件包来控制玩家的语音传播,否则可能会产生冲突和不可预测的行为。下面的表格整理的他们特点,你可以根据自己的需求来选择最适合你的组件包。
| 组件包名称 | 隔音效果 | 扩音效果 | 定向传播效果 | 基于物理的效果 (头的朝向,空间遮蔽) | 复杂规则 | 事件驱动的控制 | 可扩展性 | 性能开销 |
|---|---|---|---|---|---|---|---|---|
| PlayerVoiceSystem (本组件) | 支持 | 支持 | 支持 | 不支持 | 支持 | 支持 | 强 | 低 ~ 中 (可配置) |
| TLP UdonVoiceUtils | 支持 | 支持 | 支持 | 支持 | 一定程度 | 不支持 | 中 | 高 |
| Udon防音室 SoundproofArea | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 弱 | 中 |
| 【VRChat】部屋の中にいる人の声が同じ部屋の人にしか聞こえなくなるギミック(2.0) | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 未知 | 弱 | 未知 |
| VRChat用 エリアでミュート出来たりするU#ツール(ArmoMuteArea) | 支持 (特殊) | 不支持 | 不支持 | 不支持 | 不支持 | 未知 | 弱 | 未知 |
| 【ワールドギミック】さたにあ式マイク #さたマイク | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 支持 | 弱 | 极低 |
| 【VRChat】ワールドメガホン / WorldMegaphone【UdonProps】 | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 未知 | 弱 | 未知 |
| 【無料】【VRChatワールド用ギミック】車内放送システム Train Announcement System | 不支持 | 不支持 | 支持 | 不支持 | 不支持 | 未知 | 弱 | 未知 |
安装
- 下载
Xuan25-VRC-Common-Utilities组件包,并将其导入到你的 Unity 项目中。该组件包包含UdonTelemetry组件以及一系列相关依赖组件。你可以使用 Git 将其clone到项目的 Packages 目录下,或者直接下载压缩包并将其解压到该目录中。 - 在 Unity 项目中,找到
Packages/Xuan25 Common Utilities/PlayerVoiceSystem/Examples中的场景和预制件。他们包含了 玩家语音系统 的核心组件以及一些示例组件,可以帮助你快速上手和测试 玩家语音系统 的功能。
原理概述
玩家语音系统 是一个事件驱动的系统,其核心原理是通过在世界中设置事件源来检测玩家所属的语音区域或状态。当事件发生时,例如玩家进入或离开某个区域、玩家拾取或放下物品,系统会根据预设的链式计算规则,对玩家的语音传播参数进行调整,包括传播范围、响度,以及是否应用低通滤波器。
核心组件可以分为以下几类:
- 玩家语音控制器: 一个全局组件,负责管理玩家语音的规则链,并在每个玩家状态变更时计算并更新其语音传播参数。一个世界中只能存在一个 玩家语音控制器 ,它会管理所有玩家的语音参数。
- 玩家语音缩放器: 作为链式计算规则的一环,负责管理每个玩家的一种状态,例如玩家是否处于某个特定区域,或是否拾取了某个特定物品。玩家语音缩放器 会通知 玩家语音控制器 ,并根据玩家的对应状态在规则链中调整他们的语音传播参数。这个组件由 玩家语音控制器 直接管理。
- 玩家语音事件源: 一个与 玩家语音缩放器 关联的事件源组件。当玩家执行特定行为时,它会通知 玩家语音缩放器 更新玩家状态。
在下面的章节中,这些组件的功能和使用方法将被详细介绍。通过合理配置和组合,创作者可以实现各种语音控制效果,以满足不同玩家群体的需求。
组件介绍
玩家语音控制器 (PlayerVoiceController)
玩家语音控制器 是 玩家语音系统 的核心组件,用于管理一个 玩家语音缩放器 列表,该列表被称为规则链。它还需要设置默认的语音传播范围和响度值,作为玩家语音的默认状态。若没有任何语音缩放器生效,玩家的语音传播参数将被设置为该默认值。
玩家语音缩放器 (PlayerVoiceScaler)
玩家语音缩放器 是规则链中的一个环节。当一个玩家的状态发生改变时,玩家语音控制器 会从默认值开始,依次通过规则链中的每个 玩家语音缩放器 来调整该玩家的语音传播参数,并在所有规则应用完毕后应用该玩家的最终语音参数。
通常来说,每个 玩家语音缩放器 可以根据玩家的状态,选择按一定倍率来缩放玩家的语音传播参数,或者直接将其设置为一个固定值,又或者不对其进行调整。通过合理的配置和组合,创作者可以实现各种各样的语音控制效果。
目前有三种类型的 玩家语音缩放器:玩家语音麦克风、玩家语音房间控制器 和 玩家语音触发器。接下来将会对这三种类型的 玩家语音缩放器 进行介绍。
玩家语音麦克风 (PlayerVoiceMic)
玩家语音麦克风 组件用于在一个物品被抓取时,对抓取该物品的玩家的语音进行调整。它管理一个 玩家语音麦克风拾取代理 (PlayerVoiceMicPickupProxy),用于获取玩家抓取和释放物品的事件。
该组件适合用于实现麦克风功能。例如,当玩家抓取一个麦克风物品时,他们的语音传播范围和响度会被放大;当玩家放下麦克风物品时,他们的语音传播范围和响度会恢复到默认值。
它的设置包含一组系数,用于在条件满足时调整玩家的语音传播参数。它还包含一个覆盖选项 (ScalerOverrideIfHeld),用于设置这些系数的应用方式。当覆盖选项关闭时,玩家语音麦克风会在条件满足时按系数缩放玩家的语音传播参数;当覆盖选项打开时,玩家语音麦克风会在条件满足时直接将玩家的语音传播参数设置为系数值,从而丢弃规则链中先前的调整。
此外,该组件还包含两个选项:是否本地启用 (isEnabledLocal) 和动画控制器 (animator)。前者用于控制该玩家语音麦克风是否在本地启用;后者用于将玩家语音麦克风当前的状态映射到动画控制器参数上,从而允许创作者通过动画控制器驱动视觉效果。可用的动画控制器参数类型包括两个布尔值:HeldSelf 和 HeldOther,分别表示玩家自己和其他玩家是否满足被抓取的条件。
玩家语音房间控制器 (PlayerVoiceRoomController)
玩家语音房间控制器 组件用于管理一个或多个房间区域,最多支持 32 个房间,并在玩家进入或离开这些区域时,对玩家的语音进行调整。它管理一个 玩家语音房间 (PlayerVoiceRoom) 列表。当两个玩家处于不同房间区域时,条件满足。
该组件适合用于实现房间功能。例如,当玩家进入同一个房间区域时,他们的语音传播参数不会受到影响;当玩家进入不同的房间区域时,他们的语音传播范围和响度会被衰减。
它的设置与 玩家语音麦克风 类似,包含一组系数,用于在条件满足时调整玩家的语音传播参数。它还包含一个覆盖选项 (ScalerOverrideIfIsolated),用于设置这些系数的应用方式。当覆盖选项关闭时,玩家语音房间控制器 会在条件满足时按系数缩放玩家的语音传播参数;当覆盖选项打开时,玩家语音房间控制器 会在条件满足时直接将玩家的语音传播参数设置为系数值,从而丢弃规则链中先前的调整。
在房间区域的设置上,同一个 玩家语音房间控制器 下的多个房间区域可以重叠。换句话说,一个玩家也可以同时处于多个房间区域中。当玩家处于多个房间区域中时,只要玩家之间存在任意一个共同的房间区域,隔离条件就不会满足,即他们不会被隔离。
这种行为允许创作者通过房间重叠来设置过渡区域,从而实现更自然的过渡效果。例如,在一个房间和一个楼道的场景下,楼道和房间的区域可以在门口处重叠。在这种设置下,多名玩家先后从楼道进入房间时,他们会先后进入重叠区域,并先后离开重叠区域进入房间区域。在进入和离开重叠区域的过程中,他们始终不会被完全隔离,因此不会产生突兀的语音变化。
玩家语音触发器 (PlayerVoiceTrigger)
玩家语音触发器组件用于在玩家触发碰撞触发器时,对该玩家的语音进行调整。它本身即可捕获由碰撞触发器引发的事件,因此不需要额外的玩家语音事件源组件来提供事件。
该组件适合用于实现讲台功能。例如,当玩家进入讲台区域时,他们的语音传播参数会被增强。
玩家语音事件源 (PlayerVoiceEventSource)
玩家语音事件源 是一个与 玩家语音缩放器 关联的组件,当玩家实施特定行为时通知 玩家语音缩放器 更新玩家的状态。目前有两种 玩家语音事件源: 玩家 语音麦克风拾取代理 和 玩家语音房间 。接下来将会对这两种 玩家语音事件源 进行介绍。
玩家语音麦克风拾取代理 (PlayerVoiceMicPickupProxy)
玩家 语音麦克风拾取代理 组件用于检测玩家的抓取行为,并将其与一个 玩家语音麦克风 组件关联。其需要被添加到一个可抓取物品上,并被玩家语音麦克风组件所引用。当玩家抓取或放下该物品时,玩家 语音麦克风拾取代理 会通知玩家语音麦克风组件来更新玩家的状态。
玩家语音房间 (PlayerVoiceRoom)
玩家语音房间 组件用于检测玩家的进入和离开行为,并将其与一个 玩家语音房间控制器 组件关联。它需要被添加到一个包含碰撞触发器的对象上,并被玩家语音房间控制器组件引用。当玩家进入或离开该区域时,玩家语音房间 会通知玩家语音房间控制器组件更新玩家状态。
该组件还包含一个用于启用主动更新的选项 (ActiveUpdate)。当主动更新关闭时,玩家语音房间 仅监听玩家进入和离开碰撞触发器的事件。然而,受限于 VRChat 的物理系统实现,这些事件并不能保证可靠触发。为了弥补这一不足,当主动更新启用时,玩家语音房间 会主动探测玩家是否处于该区域中。
这一选项可以大幅提升玩家 语音房间控制器 的可靠性,但也会带来一定的性能开销,因此需要根据实际情况进行权衡。
定制化语音传播
虽然房间或触发区域在概念上通常被理解为静态的,或是符合视觉直觉的区域,但这里的“房间”概念实际上非常灵活。创作者可以根据需要,将其定义为任何能够满足条件的区域或状态。
由于 玩家语音系统 是在每个玩家客户端上独立运行的,不参与任何网络同步,因此每个玩家都可以拥有完全不同的房间设置,从而实现高度定制化的语音传播效果。
下面是一些定制化房间设置的示例,可供参考:
- 在一个社交世界中,房间可以是动态的,并允许玩家自行开关,从而实现玩家自定义的隔音效果。
- 在一个集会世界中,触发区域可以跟随特定玩家移动(可通过 PlayerConditionalObject 实现;文档待补充),从而制造出一种基于特定玩家的定向语音传播效果。
- 在一个角色扮演世界中,游戏的管理员或工作人员可以拥有特殊的房间设置(可通过 PlayerWhitelistedObject 实现;文档待补充),用于覆盖默认房间行为,从而能够听到所有玩家的声音;而普通玩家则只能听到同一房间内其他玩家的声音。
错误的使用案例:
-
在一个集会世界中,有一个只有管理员可见的麦克风物品,用于广播。由于 玩家语音系统 是在每个玩家客户端上独立运行的,当管理员抓取该麦克风物品时,普通玩家的客户端并不会检测到这一行为,因此无法触发玩家语音麦克风组件来调整管理员的语音传播参数,也就无法实现广播效果。
在设计定制化的语音传播效果时,需要站在听者客户端的角度考虑,确保 玩家语音系统 能够在听者客户端上正确检测到触发条件。
调试
PlayerVoiceSystem 组件包还提供了一些调试组件,可以帮助创作者在运行时直观地观察 玩家语音系统 的内部状态。这些组件可以在 Packages/Xuan25 Common Utilities/PlayerVoiceSystem/Debug 目录下找到。
如何扩展组件功能
PlayerVoiceSystem 的组件设计具有高度的可扩展性。创作者可以通过继承 PlayerVoiceScaler 类来创建新的 玩家语音缩放器 类型,或者通过继承 PlayerVoiceEventSource 类来创建新的 玩家语音事件源 类型,从而实现更多的自定义功能。
- 扩展案例
应用案例
在这一部分中,将介绍一些基于 PlayerVoiceSystem 的应用案例。这些案例可作为参考,帮助创作者更好地理解和使用该系统。
带多个隔音区域的会场 + 演讲台
这个案例包含一个会场区域和一个演讲台区域。当玩家进入会场内的不同区域时,他们的语音会被彼此隔离;当玩家进入演讲台区域时,他们的语音会被放大,并覆盖其他规则,从而不受所在区域的影响。
这个案例也可以理解为一个带多个子会场的远程会议系统。每个子会场都是一个隔音区域,允许玩家在其中进行私密交流;而演讲台则对应主会场的电视直播,每个子会场都可以不受阻碍地听到演讲台的声音。
带麦克风的卡拉 OK 亭 + 广播麦克风
这个案例包含三个可隔音的卡拉 OK 亭,每个亭子中都有一个麦克风物品。当玩家进入亭子时,他们的语音会被彼此隔离;当玩家抓取麦克风物品时,他们的语音会被放大。除此之外,还有一个广播麦克风物品。当玩家抓取该物品时,他们的语音会被放大,并覆盖其他规则,从而不受所在区域的影响。
带多个隔音区域的会场 + 演讲台 + 提问麦克风 + 导播室
这个案例是在第一个案例的基础上增加了一个提问麦克风物品。当玩家抓取该物品时,他们的语音会被放大,并覆盖其他规则,从而使其他玩家能够听到他们的声音,而不受所在区域的影响。
此外,该案例还增加了一个导播室区域。当玩家进入导播室区域时,他们的语音会与会场子区域保持隔离,但可以与演讲台区域直接交流。
其中,玩家语音房间_导播室_演讲台 是一个特殊的房间区域,同时覆盖导播室和演讲台区域。

No comments to display
No comments to display