参考视频:
Mojang为item重写了Model加载方法
我的《在MC1.21.4中创建Item时候遇到的问题》这篇博客中提到了Mojang在
1.21.4版本中要求新建一个这个路径的文件夹,而这就是可以采用新写法的原因。
assets/<namespace>/items
这里也是以原版的望远镜为例子,它在该路径下的json文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
{
"model": {
"type": "minecraft:select",
"cases": [
{
"model": {
"type": "minecraft:model",
"model": "minecraft:item/spyglass"
},
"when": [
"gui",
"ground",
"fixed"
]
}
],
"fallback": {
"type": "minecraft:model",
"model": "minecraft:item/spyglass_in_hand"
},
"property": "minecraft:display_context"
}
}
|
不难看出,视频中要求的模型加载和在渲染场景选择的问题被转移到了这个json文件中表达,
这意味着我们可以直接使用ModModelsProvider
来进行数据生成,而无需mixin
ModModelsProvider直接生成JSON
在查阅原版代码的时候,发现了在ItemModelGenerator
类中注册望远镜模型的办法如下
1
2
3
4
5
|
public void register() {
···
this.registerWithInHandModel(Items.SPYGLASS);
···
}
|
我们又知道
ModModelsProvider
继承于FabricModelProvider
继承于ItemModelGenerator
所以我们在ModModelsProvider
的generateItemModels
方法中直接就可以使用registerWithInHandModel
方法
具体如下:
1
2
3
4
5
6
7
|
public class ModModelsProvider extends FabricModelProvider {
···
@Override
public void generateItemModels(ItemModelGenerator itemModelGenerator) {
itemModelGenerator.registerWithInHandModel(ModItems.PLATE);
}
}
|
使用这个函数进行数据生成会在generated
文件夹下生成以下内容
assets\<yourModID>\items\plate.json
assets\<yourModID>\models\item\plate.json
这看起来和使用register
方法没有区别,但实际上在 1
路径下的文件结构和上面原版的“望远镜”一样了。
为了便于区别,这里给一个普通物品的该JSON:
1
2
3
4
5
6
|
{
"model": {
"type": "minecraft:model",
"model": "minecraft:item/apple"
}
}
|
发现多的"when"
正好与视频中的if
的条件对应,也就是说只需要修改when中的值,就可以达到与视频中一样控制3D化场景的时候了
深入剖析registerWithInHandModel方法
这里先贴出原版的函数实现:
1
2
3
4
5
|
public final void registerWithInHandModel(Item item) {
ItemModel.Unbaked unbaked = ItemModels.basic(this.upload(item, Models.GENERATED));
ItemModel.Unbaked unbaked2 = ItemModels.basic(ModelIds.getItemSubModelId(item, "_in_hand"));
this.output.accept(item, createModelWithInHandVariant(unbaked, unbaked2));
}
|
可以看到有一个"_in_hand"
的字符串,这意味着我们在resources
文件夹下的
assets\<yourModID>\models\item
添加物品的3D信息JSON的时候,需要把文件名改为item名+_in_hand
的形式。
如plate_in_hand.json
继续深入看createModelWithInHandVariant方法
还是先给出函数实现:
1
2
3
4
5
6
7
|
public static ItemModel.Unbaked createModelWithInHandVariant(ItemModel.Unbaked model, ItemModel.Unbaked inHandModel) {
return ItemModels.select(
new DisplayContextProperty(),
inHandModel,
ItemModels.switchCase(List.of(ModelTransformationMode.GUI, ModelTransformationMode.GROUND, ModelTransformationMode.FIXED), model)
);
}
|
你会发现assets\<yourModID>\items\plate.json
中的when
已经被Mojang写死在这了,所以要实现像视频中那样只在GUI
中渲染为2D的话,你需要重写这个方法。
不过还有个简单的形式是你直接去修改生成的JSON文件中的when
的值
(Tip:数据生成在下次运行的时候不会修改你手动改过的文件)
这样你在1.21.4中就实现了如下效果
