Featured image of post 1.21.4将2D物品转换为3D的新方法(无需Mixin)

1.21.4将2D物品转换为3D的新方法(无需Mixin)

FirstFabricModDev 5

参考视频:

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
所以我们在ModModelsProvidergenerateItemModels方法中直接就可以使用registerWithInHandModel方法
具体如下:

1
2
3
4
5
6
7
public class ModModelsProvider extends FabricModelProvider {
    ···
    @Override
    public void generateItemModels(ItemModelGenerator itemModelGenerator) {
        itemModelGenerator.registerWithInHandModel(ModItems.PLATE);
    }
}

使用这个函数进行数据生成会在generated文件夹下生成以下内容

  1. assets\<yourModID>\items\plate.json
  2. 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中就实现了如下效果
效果

本作品采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可(CC BY-NC-SA 4.0)
文章浏览量:Loading
Powered By MC ZBD Studio
发表了21篇文章 · 总计29.03k字
载入天数...载入时分秒...
总浏览量Loading | 访客总数Loading

主题 StackJimmy 设计
由ZephyrBD修改