资源位置
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。