声音

声音

Minecraft 使用声音事件、类别和声音文件来组织与播放音效。本页介绍声音定义和不同播放方法的行为。

示例声音事件 mymod:epic_music 对应 assets/mymod/sounds.json 的 epic_music 键,文件标识 mymod:music/epic_music 对应 sounds/music/epic_music.ogg。

原创说明图,依据 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

  1. playSound(Player, BlockPos, SoundEvent, SoundSource, volume, pitch):将给定 BlockPos 的每个坐标加 0.5,转发给下一个重载。
  2. playSound(Player, double x, double y, double z, SoundEvent, SoundSource, volume, pitch):
    • 客户端:如果传入的玩家就是该客户端玩家,则向其播放声音。
    • 服务端:向附近除传入玩家之外的所有人播放,玩家可以为 null。
    • 用途:两种行为相互配合,适用于玩家发起、同时在两个逻辑端运行的代码:客户端为用户播放,服务端让其他人听到,而不向原用户重复播放。也可以在逻辑服务端传入 null,在任意位置向所有人播放声音。
  3. 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。