我的世界1.20.1模组开发---3.数据生成(目前不完整,没有什么参考价值,以后理解了再慢慢补充)
介绍
我们在模组里每添加一个物品或方块后,在游戏里显示的都只是马赛克,因为我们还没有为我们的物品或方块设置对应的模型贴图。我的世界游戏里,每一个物品和方块我们所看到的样子都是一张张贴图,就是画的像素画,贴在了一个模型表面。我们想设置对应的贴图,需要写一个对应的json文件来描述这个物品,如下图所示。但是,由于是一个json文件,编译器中对json文件并没有代码提示和相应的错误提示,我们手写很容易写错,出现各种各样的bug。当然也有更高效的方式,我们可以用forge为我们提供的json文件生成器生成对应的json文件。下面就开始正式介绍。
ModelProvider类
我们的自定义类要继承ItemModelProvider类,这是forge为我们提供的自动生成json数据的类。从他的名字我们不难看出,这个类是用来生成Item对应的模型的json的文件的类,所以我们自定义的生成数据的类要继承这个类。但是ItemModelProvider类也是继承于ModelProvider类,大部分的方法都在这个最基础的父类里面,所以我们进入ModelProvider类里看看我们能用得上哪些方法。
在我们的自定义类里面,我们要重写父类的registerModels方法,这个方法就是我们最主要的方法,需要添加的物品需要生成对应的json文件要写在这个方法里。
我们给一个物品添加贴图时,首先要知道这个物品是什么,然后是贴图资源的位置,有了这两个参数我们就能成功的为一个物品添加贴图。这里我们要用到ModelProvider类里的withExistingParent方法,因为游戏里有给物品的通用材质,所以我们可以继承这个材质,把这个通用材质作为我们的父材质继承过来用。
public T withExistingParent(String name, ResourceLocation parent) {
return getBuilder(name).parent(getExistingFile(parent));
}
这个方法需要传入物品的名称和对应的父材质资源,返回一个泛型对象也就是我们的自定义类的对象,得到的对象会设置好对应的父材质,我们再调用这个对象身上的texture方法来设置我们的物品贴图即可。
代码
生成物品json文件
这么说着可能确实比较抽象,我理解的也不是太透彻,对于初学者来说,我们不需要太过于要求自己明白原理,起步阶段会用就行x.x。下面的代码写多了以后慢慢也能理解的。下面我们新建一个ModItemModelGen类来专门生成物品的json文件,这个类要继承ItemModelProvider类,并重写里面的registerModels方法,在这个方法里添加物品的json文件生成所需设置。
package com.hmy.test1mod.datagen; import com.hmy.test1mod.Test1Mod; import com.hmy.test1mod.item.ModItems; import net.minecraft.data.PackOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraftforge.client.model.generators.ItemModelProvider; import net.minecraftforge.common.data.ExistingFileHelper; import net.minecraftforge.registries.ForgeRegistries; public class ModItemModelGen extends ItemModelProvider { //通用模型,让其他物品继承使用 public static final String GENERATED="item/generated"; //构造函数 public ModItemModelGen(PackOutput output, ExistingFileHelper existingFileHelper){ //第二个参数要填自己的modid super(output, Test1Mod.MOD_ID,existingFileHelper); } //重写该方法,在这个方法里面填写要生成数据的物品 @Override protected void registerModels() { //在里面调用自定义的生成模型的方法,传入对应参数即可 itemGenerateModel(ModItems.YUANSHI.get(),resourceItem(itemName(ModItems.YUANSHI.get()))); itemGenerateModel(ModItems.JIUCHANZHIYUAN.get(),resourceItem(itemName(ModItems.JIUCHANZHIYUAN.get()))); itemGenerateModel(ModItems.REDSWORD.get(),resourceItem(itemName(ModItems.REDSWORD.get()))); itemGenerateModel(ModItems.EIGHTBALL.get(),resourceItem(itemName(ModItems.EIGHTBALL.get()))); } //自定义方法,item表明我们要生成数据的物品,texture表明生成数据的贴图资源 public void itemGenerateModel(Item item, ResourceLocation texture){ //因为要继承通用模型,调用这个方法设置父模型为通用模型,返回这个类的对象调用texture方法设置贴图 withExistingParent(itemName(item),GENERATED).texture("layer0",texture); } //获取item的所在路径 public String itemName(Item item){ return ForgeRegistries.ITEMS.getKey(item).getPath(); } //拼接路径寻找贴图资源 public ResourceLocation resourceItem(String path){ return new ResourceLocation(Test1Mod.MOD_ID,"item/"+path); } }
生成方块json文件
我们设置方块对应的配置于物品的比起来较为简单,我们首先创建一个ModBlockModelGen类,这个类要继承BlockStateProvider类,之后创建构造函数,并重写registerStatesAndModels方法,在该方法里添加对应的方块即可。
package com.hmy.test1mod.datagen;
import com.hmy.test1mod.Test1Mod;
import com.hmy.test1mod.block.ModBlocks;
import com.hmy.test1mod.block.custom.JumpBlock;
import net.minecraft.data.PackOutput;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.client.model.generators.BlockModelProvider;
import net.minecraftforge.client.model.generators.BlockStateProvider;
import net.minecraftforge.common.data.ExistingFileHelper;
public class ModBlockModelGen extends BlockStateProvider {
public ModBlockModelGen(PackOutput packOutput, ExistingFileHelper existingFileHelper) {
super(packOutput, Test1Mod.MOD_ID,existingFileHelper);
}
@Override
protected void registerStatesAndModels() {
this.registerBlockModelAndItem(ModBlocks.BLUE_BLOCK.get());
this.registerBlockModelAndItem(ModBlocks.BLUE_ORE.get());
this.registerBlockModelAndItem(ModBlocks.JUMP_BLOCK.get());
}
//在registerStatesAndModels方法里调用该函数直接添加对应的方块即可
public void registerBlockModelAndItem(Block block){
this.simpleBlockWithItem(block,this.cubeAll(block));
}
simpleBlockWithItem方法可以把方块和对应的物品一起生成json文件,cubeAll方法是设置该方块的六面都使用一个贴图,如果每个面不同贴图的方块以后再介绍。直接在重写的simpleBlockWithItem中调用registerBlockModelAndItem方法传入对应的方块即可。最后把该类添加到数据生成器中即可。
生成语言json文件
我们每一个物品都都有对应的显示的名称,这个名称由我们的json来描述,可以自己设置多种语言,分别对应不同的json文件。forge官方也为我们提高了对应的生成json文件的方法,我们新建一个ModLangGen类,这个类要继承LanguageProvider类,重写addTranslations方法,在该方法里调用add方法即可添加完成。
public void add(Item key, String name) { add(key.getDescriptionId(), name); }
这个方法要传入两个参数,第一个参数是我们添加的物品,第二个则是我们要给物品起的名字。下面上代码。
package com.hmy.test1mod.datagen; import com.hmy.test1mod.Test1Mod; import com.hmy.test1mod.block.ModBlocks; import com.hmy.test1mod.item.ModItems; import net.minecraft.data.PackOutput; import net.minecraftforge.common.data.LanguageProvider; public class ModLangGen extends LanguageProvider { public ModLangGen(PackOutput output,String locale){super(output, Test1Mod.MOD_ID,locale);} //重写这个方法,这个方法里添加对应物品的信息 @Override protected void addTranslations() { //物品 //直接调用add方法,传入物品和物品对应的名字即可 add(ModItems.YUANSHI.get(),"YusnShi"); add(ModItems.JIUCHANZHIYUAN.get(),"JiuChanZhiYuan"); } }
数据生成器
前面几个类只是相当于创建了几个工具,我们在工具里面设置了要生成的json文件,接下来我们要用一个数据生成类统一管理这些设置好的工具,并交由总线管理,让系统可以自动生成这些设置好的json文件。
我们创建一个DataGenerator类让系统生成这些json,之前创建的语言文件和物品模型文件的生成类都要添加到这个类里面。
package com.hmy.test1mod.datagen;
import com.hmy.test1mod.Test1Mod;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.PackOutput;
import net.minecraft.data.loot.LootTableProvider;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraftforge.common.data.ExistingFileHelper;
import net.minecraftforge.data.event.GatherDataEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
//这个类相当于对所有的json数据生成器的一个管理,都添加到generator身上即可
@Mod.EventBusSubscriber(modid = Test1Mod.MOD_ID,bus=Mod.EventBusSubscriber.Bus.MOD)
public class DataGenerators {
//这个注释表明这个方法要被模组事件总线所监视,这个方法是事件触发时的回调
@SubscribeEvent
public static void gatherData(GatherDataEvent event){
//创建一堆东西,照着写就行,以后有机会会介绍
DataGenerator generator=event.getGenerator();
PackOutput output=generator.getPackOutput();
CompletableFuture<HolderLookup.Provider>lookupProvider=event.getLookupProvider();
ExistingFileHelper helper=event.getExistingFileHelper();
//添加生成对应文件的生成器
//第一个参数表示在客户端还是服务端,这里我们选择客户端,第二个传进一个生成的对象,就是我们之前自己写的类
generator.addProvider(event.includeClient(),new ModItemModelGen(output,helper));
//en_us表示英文名称的文件,还可以根据需求设置多种语言
generator.addProvider(event.includeClient(),new ModLangGen(output,"en_US"));
//添加生成方块json文件的类
generator.addProvider(event.includeClient(),new ModBlockModelGen(output,helper));
}
}
完成这些配置之后,我们首先要把物品对应的贴图放到对应的位置里,这样系统才能找到贴图并渲染。目录创建在resources目录下,目录的级别和路径一定严格按照要求,如下所示,不然系统无法找到贴图。注意:贴图的名字要和一开始我们设置的物品的name属性要一致才可以。
然后我们点击一些RunData命令让系统生成这些数据,当构建成功后直接RunClient运行游戏即可。
运行游戏后打开我们的创造模式物品栏下,就可以看到我们设置好贴图的物品了。