声音
Minecraft 使用声音事件、类别和声音文件来组织与播放音效。本页介绍声音定义和不同播放方法的行为。
原创说明图,依据 Forge 1.21.x 官方文档 绘制。
术语
| 术语 | 说明 |
|---|---|
| 声音事件 | 触发音效的事件,例如 minecraft:block.anvil.hit 或 botania:spreader_fire。 |
| 声音类别 | 声音所属类别,例如 player、block 或 master。声音设置界面中的滑块代表这些类别。 |
| 声音文件 | 磁盘上实际播放的 .ogg 文件。 |
sounds.json
此 JSON 定义声音事件、播放的声音文件、字幕等。声音事件通过 ResourceLocation 标识。sounds.json 应位于资源命名空间根目录 assets/<namespace>/sounds.json,定义该命名空间中的声音事件。
完整规范见 Minecraft Wiki,下面的例子展示重要部分:
{
"open_chest": {
"subtitle": "mymod.subtitle.open_chest",
"sounds": [ "mymod:open_chest_sound_file" ]
},
"epic_music": {
"sounds": [
{
"name": "mymod:music/epic_music",
"stream": true
}
]
}
}
顶层对象下每个键对应一个声音事件。无需给出命名空间,因为它取自 JSON 本身所在的命名空间。每个事件指定启用字幕时显示的本地化键,最后指定实际播放的声音文件。该值是数组:若指定多个文件,事件触发时游戏会随机选择一个播放。
两个例子展示了指定声音文件的不同方式。详见 Wiki。一般来说,背景音乐或唱片等较长文件应使用第二种形式,因为 stream 告诉 Minecraft 从磁盘流式读取,而不是将整个文件加载到内存。第二种形式还可以指定音量、音高和权重。
对于命名空间 namespace 和路径 path,声音文件位于 assets/<namespace>/sounds/<path>.ogg。因此,mymod:open_chest_sound_file 指向 assets/mymod/sounds/open_chest_sound_file.ogg;mymod:music/epic_music 指向 assets/mymod/sounds/music/epic_music.ogg。sounds.json 可以通过数据生成创建。
创建声音事件
要在服务端引用声音,必须创建包含 sounds.json 对应条目的 SoundEvent,然后将其注册。通常创建声音事件使用的位置应设为其注册表名称。
SoundEvent 作为声音引用传递以供播放。如果 Mod 提供 API,应在 API 中公开其 SoundEvent。
注意:只要声音在
sounds.json中注册,无论是否存在引用它的SoundEvent,仍可在逻辑客户端引用。
播放声音
原版提供很多播放声音的方法,有时难以判断该用哪一种。下面每种方法都接收上面注册的 SoundEvent;“服务端行为”和“客户端行为”指相应的逻辑端。
Level
playSound(Player, BlockPos, SoundEvent, SoundSource, volume, pitch):将给定BlockPos的每个坐标加 0.5,转发给下一个重载。playSound(Player, double x, double y, double z, SoundEvent, SoundSource, volume, pitch):- 客户端:如果传入的玩家就是该客户端玩家,则向其播放声音。
- 服务端:向附近除传入玩家之外的所有人播放,玩家可以为
null。 - 用途:两种行为相互配合,适用于玩家发起、同时在两个逻辑端运行的代码:客户端为用户播放,服务端让其他人听到,而不向原用户重复播放。也可以在逻辑服务端传入
null,在任意位置向所有人播放声音。
playLocalSound(double x, double y, double z, SoundEvent, SoundSource, volume, pitch, distanceDelay):- 客户端:在客户端世界播放;如果
distanceDelay为true,则根据与玩家的距离延迟播放。 - 服务端:无操作。
- 用途:仅在客户端工作,适合自定义数据包发送的声音或其他仅客户端效果声音;雷声使用此方法。
- 客户端:在客户端世界播放;如果
ClientLevel
playLocalSound(BlockPos, SoundEvent, SoundSource, volume, pitch, distanceDelay) 将 BlockPos 的每个坐标加 0.5 后转发给 Level 的第三个重载。
Entity
playSound(SoundEvent, volume, pitch) 转发给 Level 的第二个重载,玩家参数为 null。客户端无操作;服务端在实体位置向所有人播放。用于在服务端从非玩家实体发出声音。
Player
playSound(SoundEvent, volume, pitch) 重写 Entity 方法,转发给 Level 的第二个重载,并以 this 作为玩家。客户端无操作(参见 LocalPlayer 的重写);服务端向附近除该玩家之外的所有人播放。用途参见 LocalPlayer。
LocalPlayer
playSound(SoundEvent, volume, pitch) 重写 Player 方法,转发给 Level 的第二个重载,并以 this 作为玩家。客户端直接播放声音;该方法仅存在于客户端。与 Level 方法一样,玩家类的这两个重写似乎用于同时在两端运行的代码:客户端为用户播放,服务端让其他人听到,而不向原用户重复播放。
原文:Sounds。