物品属性
物品属性将物品的“属性”暴露给模型系统。例如弓最重要的属性是拉开的程度;系统利用它选择模型,形成拉弓动画。
原创说明图,依据 Forge 1.21.x 官方文档 绘制。
物品属性为注册该属性的每个 ItemStack 指定一个 float 值。原版物品模型定义可以用这些值定义“覆盖”:物品默认使用某个模型,但匹配覆盖条件时改用另一个模型。其主要优势在于值是连续的。例如弓的拉弓动画由浮点数谓词决定,数值不受限制,但通常在 0.0F 到 1.0F 之间。这让资源包可以在该范围内添加任意数量的动画模型,而不局限于四个模型“槽位”。指南针和时钟也是如此。
为物品添加属性
ItemProperties#register 为特定物品添加属性。Item 参数是目标物品(如 ExampleItems#APPLE);ResourceLocation 是属性名称(如 new ResourceLocation("pull"))。ItemPropertyFunction 是函数式接口,接收 ItemStack、所在 ClientLevel(可为 null)、持有它的 LivingEntity(可为 null)和持有实体 ID 的 int(可为 0),返回属性的 float 值。
Mod 属性建议使用 Mod ID 作为命名空间,例如 examplemod:property,而非仅写 property,后者实际表示 minecraft:property。应在 FMLClientSetupEvent 中执行。另有 ItemProperties#registerGeneric,用于给所有物品添加属性,不接收 Item 参数。
重要:使用
FMLClientSetupEvent#enqueueWork执行任务,因为ItemProperties中的数据结构不是线程安全的。
注意:Mojang 已弃用
ItemPropertyFunction,推荐其子接口ClampedItemPropertyFunction,它将结果限制在0到1之间。
使用覆盖
覆盖格式见 Minecraft Wiki,model/item/bow.json 也是一个好例子。以下假设物品具有 examplemod:power 属性。没有匹配值时默认使用当前模型;如果多个覆盖项匹配,选择列表中最后一个。
重要:谓词匹配所有大于或等于指定值的值。
带注释和省略号的示例用于说明结构;实际 JSON 文件需移除注释并补全内容。
{
"parent": "item/generated",
"textures": {
// 默认
"layer0": "examplemod:items/example_partial"
},
"overrides": [
{
// power >= .75
"predicate": { "examplemod:power": 0.75 },
"model": "examplemod:item/example_powered"
}
]
}
下面是假设的配套代码片段。与低于 1.16.x 的旧版本不同,这必须仅在客户端执行,因为服务端不存在 ItemProperties。
private void setup(final FMLClientSetupEvent event) {
event.enqueueWork(() -> {
ItemProperties.register(ExampleItems.APPLE,
ResourceLocation.fromNamespaceAndPath(ExampleMod.MODID, "pulling"), (stack, level, living, id) -> {
return living != null && living.isUsingItem() && living.getUseItem() == stack ? 1.0F : 0.0F;
});
});
}
译注:原文模型使用
examplemod:power,示例代码却注册pulling;若两者需要配合,须使用同一个属性名称。
原文:Item Properties。