Skip to content

创建自定义音效

准备音频文件

你的音频文件需要转化为特定格式。 OGG Vorbis 是一种用于音频等多媒体数据的开放式容器格式,Minecraft 的声音文件就使用了这种格式。 为了避免 Minecraft 处理声音传播距离的问题,你的音频必须只有单声道 (Mono)。

大部分现代 DAW (数字音频工作站) 软件都可以使用这种格式进行导入和导出。 在下面的例子中,我们将使用免费开源软件“Audacity”将音频文件转换成规定的格式,当然其他的 DAW 也可以做到。

Audacity 中未准备好的音频文件

在本例中,哨声 被作为例子导入 Audacity。 它目前被保存为.wav格式的文件,有两个音频通道 (立体声) 。 按照自己的需求编辑音频,并确保使用“音轨头”顶部的下拉元素删除其中一个音频通道。

分割立体声轨

删除一个音频通道

导出或渲染音频文件时,请确认选择的是 OGG 文件格式。 有些 DAW (如 REAPER) 可能支持多种 OGG 音频层格式。 在这种情况下,选择 OGG Vorbis 即可。

导出为 OGG 文件

另外,音频文件过大会导致模组文件也更大。 如有必要,在编辑和导出文件时适量压缩音频本身,以尽量减小导出的文件大小。

加载音频文件

要在你的模组中使用音频文件,要添加新的 resources/assets/<mod id here>/sounds 目录,并将导出的音频文件 metal_whistle.ogg 放入该目录中。

如果 resources/assets/<mod id here>/sounds.json 文件还未生成,继续创建该文件,并将你的音效添加到音效条目中。

json
{
    "metal_whistle": {
      "subtitle": "sound.fabric-docs-reference.metal_whistle",
      "sounds": [
        "fabric-docs-reference:metal_whistle"
      ]
    }
  }

声音字幕 (subtitle) 条目为玩家提供了更多的关于该声音的信息。 声音字幕翻译键会在 resources/assets/<mod id here>/lang 目录下的语言文件中用到,如果游戏内字幕设置已打开且正在播放自定义声音,则会显示该翻译键在语言文件内对应的值,如果找不到,那么会直接显示该声音字幕的翻译键。

注册自定义音效

要将自定义音效添加到模组里,请在实现了 ModInitializer 入口点的类中注册一个 SoundEvent。

java
Registry.register(Registries.SOUND_EVENT, new Identifier(MOD_ID, "metal_whistle"),
        SoundEvent.of(new Identifier(MOD_ID, "metal_whistle")));

整理工作

根据注册表项的数量,入口点类可能很快就会变得十分杂乱。 为了避免这种情况,我们可以使用一个新的辅助类。

在新创建的辅助类中添加两个新方法: 一个用于注册所有音效,一个用于初始化该类。 之后就可以根据需要,添加新的自定义 SoundEvent 常量了。

java
public class CustomSounds {
	private CustomSounds() {
		// private empty constructor to avoid accidental instantiation
	}

	// ITEM_METAL_WHISTLE is the name of the custom sound event
	// and is called in the mod to use the custom sound
	public static final SoundEvent ITEM_METAL_WHISTLE = registerSound("metal_whistle");

	// actual registration of all the custom SoundEvents
	private static SoundEvent registerSound(String id) {
		SoundEvent sound = SoundEvent.of(new Identifier(FabricDocsReferenceSounds.MOD_ID, id));
		return Registry.register(Registries.SOUND_EVENT, new Identifier(FabricDocsReferenceSounds.MOD_ID, id), sound);
	}

	// This static method starts class initialization, which then initializes
	// the static class variables (e.g. ITEM_METAL_WHISTLE).
	public static void initialize() {
		FabricDocsReferenceSounds.LOGGER.info("Registering " + FabricDocsReferenceSounds.MOD_ID + " Sounds");
		// Technically this method can stay empty, but some developers like to notify
		// the console, that certain parts of the mod have been successfully initialized
	}
}

如此,在实现了 ModInitializer 的入口点类中,只需调用一行即可注册所有的自定义 SoundEvents。

java
public class FabricDocsReferenceSounds implements ModInitializer {
	public static final String MOD_ID = FabricDocsReference.MOD_ID;
	public static final Logger LOGGER = FabricDocsReference.LOGGER;

	@Override
	public void onInitialize() {
		// This is the basic registering. Use a new class for registering sounds
		// instead, to keep the ModInitializer implementing class clean!
		Registry.register(Registries.SOUND_EVENT, new Identifier(MOD_ID, "metal_whistle"),
				SoundEvent.of(new Identifier(MOD_ID, "metal_whistle")));

		// ... the cleaner approach.
		CustomSounds.initialize(); 
		FabricDocsReferenceItems.initialize(); 
	}
}

使用自定义的 SoundEvent

使用辅助类去访问自定义的 SoundEvent。 查看 播放声音事件(SoundEvent) 页面,了解如何播放声音。