资源位置

资源位置

ResourceLocation 是 Minecraft 中最重要的概念之一。它用作注册表中的键、数据或资源文件的标识符、代码中对模型的引用,以及许多其他用途。一个 ResourceLocation 由两部分组成:命名空间和路径,两者以 : 分隔。

命名空间表示该位置所属的 Mod、资源包或数据包。例如,Mod ID 为 examplemod 的 Mod 会使用 examplemod 命名空间;Minecraft 使用 minecraft 命名空间。只需创建相应的数据文件夹,就可以按需定义额外命名空间。数据包通常会使用额外命名空间,将自身逻辑与接入原版内容的部分隔离开来。

路径是在命名空间中指向目标对象的引用。例如,minecraft:cow 指向 minecraft 命名空间中名为 cow 的对象,通常用于从实体注册表获取牛实体。另一个例子是 examplemod:example_item,它可能用于从物品注册表获取 Mod 的 example_item。

ResourceLocation 只能包含小写字母、数字、下划线、点和连字符。路径还可以包含正斜杠。请注意,受 Java 模块限制,Mod ID 不能包含连字符,因此 Mod 命名空间也不能包含连字符(路径中仍可使用连字符)。

说明 ResourceLocation 本身并不表示对象的类型。例如,minecraft:dirt 可以在多个位置表示不同对象。由接收此 ResourceLocation 的代码决定它对应哪种对象。

可以调用 ResourceLocation.fromNamespaceAndPath("examplemod", "example_item") 或 ResourceLocation.parse("examplemod:example_item") 创建新的 ResourceLocation。如果使用 withDefaultNamespace,字符串会被视为路径,并以 minecraft 作为命名空间。例如,ResourceLocation.withDefaultNamespace("example_item") 会得到 minecraft:example_item。

可以分别通过 ResourceLocation#getNamespace() 和 #getPath() 获取命名空间与路径,也可以通过 ResourceLocation#toString 获取两者组成的完整字符串。

ResourceLocation 是不可变对象。它的所有工具方法(例如 withPrefix 和 withSuffix)都会返回新的 ResourceLocation。

解析 ResourceLocation

有些位置(例如注册表)会直接使用 ResourceLocation。其他位置则会按需解析它。例如:

  • ResourceLocation 可作为 GUI 背景的标识符。例如,熔炉 GUI 使用 minecraft:textures/gui/container/furnace.png。它对应磁盘上的 assets/minecraft/textures/gui/container/furnace.png 文件。注意,此处的资源位置必须包含 .png 后缀。
  • ResourceLocation 可作为方块模型的标识符。例如,泥土方块模型使用 minecraft:block/dirt。它对应磁盘上的 assets/minecraft/models/block/dirt.json 文件。注意,此处无需添加 .json 后缀,而且资源位置会自动映射到 models 子文件夹。
  • ResourceLocation 可作为配方的标识符。例如,铁块合成配方使用 minecraft:iron_block。它对应磁盘上的 data/minecraft/recipe/iron_block.json 文件。注意,此处无需添加 .json 后缀,而且资源位置会自动映射到 recipe 子文件夹。

是否需要文件后缀,以及资源位置具体解析到什么内容,取决于使用场景。

ModelResourceLocation

ModelResourceLocation 是一种特殊的资源位置,它还包含第三部分:变体。Minecraft 主要用它区分同一模型在不同显示环境下的不同变体,例如三叉戟在第一人称、第三人称和物品栏中的显示模型。

物品的变体始终是 inventory;方块状态的变体则是由逗号分隔的属性和值,例如 facing=north,waterlogged=false。没有方块状态属性的方块使用空变体。

变体会以 # 追加到普通资源位置之后。例如,钻石剑物品模型的完整名称是 minecraft:diamond_sword#inventory。不过,在大多数场景中可以省略 inventory 变体。

ModelResourceLocation 是仅限客户端使用的类。这意味着服务器如果引用此类,会因 NoClassDefFoundError 而崩溃。

ResourceKey

ResourceKey 将注册表 ID 与注册表名称组合在一起。例如,注册表 ID 为 minecraft:item、注册表名称为 minecraft:diamond_sword 的注册表键。与 ResourceLocation 不同,ResourceKey 指向唯一元素,因此可以明确标识某个元素。它最常用于多个不同注册表相互作用的场景,数据包(尤其是世界生成)是常见用途。

可以通过静态方法 ResourceKey#create(ResourceKey<? extends Registry<T>>, ResourceLocation) 创建新的 ResourceKey。第二个参数是注册表名称;第一个参数称为注册表键。注册表键是一种特殊的 ResourceKey,其注册表为根注册表(即所有其他注册表的注册表)。可以使用目标注册表的 ID,通过 ResourceKey#createRegistryKey(ResourceLocation) 创建注册表键。

创建 ResourceKey 时会进行驻留(interning)。因此,可以并且建议使用引用相等比较(==),但创建 ResourceKey 的开销相对较高。


来源: NeoForged/Documentation(1.21.1)。中文翻译依据提交 4a680cdd4d15。