Skip to content

创建自定义音效

准备音频文件

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

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

Audacity 中未准备好的音频文件

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

分割立体声轨

删除一个音频通道

导出或渲染音频文件时,请确认选择的是 OGG 文件格式。 有些 DAW (如 REAPER) 可能支持多种 OGG 音频层格式。 在这种情况下,选择 OGG Vorbis 即可。 根据注册表项的数量,入口点类可能很快就会变得十分杂乱。 为了避免这种情况,我们可以使用一个新的辅助类。 在这种情况下,选择 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) 条目为玩家提供了更多的关于该声音的信息。 声音字幕 (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。 查看 播放声音事件(SoundEvent) 页面,了解如何播放声音。