この記事は"Minecraft Forge Universal 11.14.0.xxx~"を前提MODとしています。 |
ワールド上に設置できる簡単なブロックの追加方法
目次
ブロックの追加
ソースコード
- SampleMod.java
package com.example.examplemod; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.registry.GameRegistry; @Mod(modid = "SampleMod", name = "SampleMod", version = "1.0", dependencies = "required-after:Forge@[1.8-11.14.0.1239,)", useMetadata = true) public class SampleMod { public static final String MOD_ID = "SampleMod"; @Mod.Instance("SampleMod") public static SampleMod INSTANCE; @SidedProxy(clientSide = "com.example.examplemod.ClientProxy", serverSide = "com.example.examplemod.CommonProxy") public static CommonProxy proxy; public static Block sampleBlock; public static Item sampleItem; @EventHandler public void preInit(FMLPreInitializationEvent event) { sampleBlock = new SampleBlock(); //ブロックの登録。登録文字列はMOD内で被らなければ何でも良い。 GameRegistry.registerBlock(sampleBlock, SampleItemBlock.class, "sampleblock"); } @EventHandler public void init(FMLInitializationEvent event) { //モデルJSONファイルのファイル名を登録。1IDで1つだけなら、登録名はGameRegistryでの登録名と同じものにする。 //ItemStackのmetadataで種類を分けて描画させたい場合。登録名を予め登録する。 ModelBakery.addVariantName(Item.getItemFromBlock(sampleBlock), MOD_ID + ":" + "sampleblock0", MOD_ID + ":" + "sampleblock1"); //テクスチャ・モデル指定JSONファイル名の登録。 if (event.getSide().isClient()) { //1IDで複数モデルを登録するなら、上のメソッドで登録した登録名を指定する。 Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(sampleBlock), 0, new ModelResourceLocation(MOD_ID + ":" + "sampleblock0", "inventory")); Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(sampleBlock), 1, new ModelResourceLocation(MOD_ID + ":" + "sampleblock1", "inventory")); } } }
- SampleBlock.java
package com.example.examplemod; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.properties.PropertyInteger; import net.minecraft.block.state.BlockState; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import java.util.List; public class SampleBlock extends Block { //BlockState用Property変数。今回はmetadataと同じようなPropertyIntegerを用いる。 public static final PropertyInteger METADATA = PropertyInteger.create("meta", 0, 1); public SampleBlock() { super(Material.rock); setCreativeTab(CreativeTabs.tabBlock);/*クリエイティブタブの選択*/ setUnlocalizedName("blockSample");/*システム名の設定*/ /*以下のものは消しても結構です*/ setHardness(1.5F);/*硬さ*/ setResistance(1.0F);/*爆破耐性*/ setStepSound(Block.soundTypeStone);/*ブロックの上を歩いた時の音*/ /*setBlockUnbreakable();*//*ブロックを破壊不可に設定*/ /*setTickRandomly(true);*//*ブロックのtick処理をランダムに。デフォルトfalse*/ /*disableStats();*//*ブロックの統計情報を保存しない*/ setLightOpacity(1);/*ブロックの透過係数。デフォルト0(不透過)*/ setLightLevel(1.0F);/*明るさ 1.0F = 15*/ //初期BlockStateの設定 this.setDefaultState(this.blockState.getBaseState().withProperty(METADATA, 0)); } //ItemStackのmetadataからIBlockStateを生成。設置時に呼ばれる。 @Override public IBlockState getStateFromMeta(int meta) { return this.getDefaultState().withProperty(METADATA, meta); } //IBlockStateからItemStackのmetadataを生成。ドロップ時とテクスチャ・モデル参照時に呼ばれる。 @Override public int getMetaFromState(IBlockState state) { return (Integer)state.getValue(METADATA); } //初期BlockStateの生成。 @Override protected BlockState createBlockState() { return new BlockState(this, METADATA); } //複数種類のブロックをクリエイティブタブに登録するためのメソッド @Override public void getSubBlocks(Item itemIn, CreativeTabs tab, List list) { super.getSubBlocks(itemIn, tab, list); list.add(new ItemStack(itemIn, 1, 1)); } }
- SmpleItemBlock.java
package com.example.examplemod; import net.minecraft.block.Block; import net.minecraft.item.ItemBlock; public class SampleItemBlock extends ItemBlock { public SampleItemBlock(Block block) { super(block); } //ItemStackのdamage値からmetadataの値を返す。 @Override public int getMetadata(int damage) { return damage; } }
- sampleblock0.json(BlockState用)
{ "variants": { "normal": { "model": "samplemod:sampleblock0" } } }
- sampleblock0.json(Block Model用)
{ "parent": "block/cube_all", "textures": { "all": "blocks/bedrock" } }
- sampleblock0.json(Item Model用)
{ "parent": "samplemod:block/sampleblock0", "display": { "thirdperson": { "rotation": [ 10, -45, 170 ], "translation": [ 0, 1.5, -2.75 ], "scale": [ 0.375, 0.375, 0.375 ] } } }
- sampleblock1.json(BlockState用)
{ "variants": { "normal": { "model": "samplemod:sampleblock1" } } }
- sampleblock1.json(Block Model用)
{ "parent": "block/cube", "textures": { "down": "blocks/wool_colored_black", "up": "blocks/wool_colored_white", "north": "blocks/wool_colored_yellow", "south": "blocks/wool_colored_red", "west": "blocks/wool_colored_green", "east": "blocks/wool_colored_blue" } }
- sampleblock1.json(Item Model用)
{ "parent": "samplemod:block/sampleblock1", "display": { "thirdperson": { "rotation": [ 10, -45, 170 ], "translation": [ 0, 1.5, -2.75 ], "scale": [ 0.375, 0.375, 0.375 ] } } }
解説
SampleMod.java
//テクスチャ・モデル指定JSONファイル名の登録。 if (event.getSide() == Side.CLIENT) { //ItemStackのmetadataで種類を分けて描画させたい場合。登録名を予め登録する。 ModelBakery.addVariantName(Item.getItemFromBlock(sampleBlock), MOD_ID + ":" + "sampleBlock0", MOD_ID + ":" + "sampleBlock1"); //モデルJSONファイルのファイル名を登録。1IDで1つだけなら、登録名はGameRegistryでの登録名と同じものにする。 //1IDで複数モデルを登録するなら、上のメソッドで登録した登録名を指定する。 Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(sampleBlock), 0, new ModelResourceLocation(MOD_ID + ":" + "sampleBlock0", "inventory")); Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(sampleBlock), 1, new ModelResourceLocation(MOD_ID + ":" + "sampleBlock1", "inventory")); }
ブロックのテクスチャ・モデルのJSONファイルのファイル名を登録している。 ModelBakery#addVariantNameメソッドは、羊毛ブロックのような、1IDで複数種類のブロックのモデルを登録する際の登録名を予め指定しておくメソッドである。 BlockStateのPropertyを持たないブロックを追加する場合は必要ない。 ItemModelMesher#registerメソッドでテクスチャ・モデルのJSONファイルを登録している。 ここで登録されるのは手持ちやドロップアイテム時の描画についてであり、設置時のモデルに関して登録は不要である。 1.7と同様の処理については1.7のブロック追加を参照のこと。
SampleBlock.java
//BlockState用Property変数。今回はmetadataと同じようなPropertyIntegerを用いる。 public static final PropertyInteger METADATA = PropertyInteger.create("meta", 0, 1);
このブロックに紐付けしたいPropertyの宣言。今回は分かりやすいように従来のmetadataライクなものを利用している。
//初期BlockStateの設定 this.setDefaultState(this.blockState.getBaseState().withProperty(METADATA, 0));
BlockStateの初期状態の指定。
//ItemStackのmetadataからIBlockStateを生成。設置時に呼ばれる。 @Override public IBlockState getStateFromMeta(int meta) { return this.getDefaultState().withProperty(METADATA, meta); } //IBlockStateからItemStackのmetadataを生成。ドロップ時とテクスチャ・モデル参照時に呼ばれる。 @Override public int getMetaFromState(IBlockState state) { return (Integer)state.getValue(METADATA); } //初期BlockStateの生成。 @Override protected BlockState createBlockState() { return new BlockState(this, METADATA); }
BlockState周りのメソッド。それぞれ注記の通りである。
SampleItemBlock.java
//ItemStackのdamage値からmetadataの値を返す。 @Override public int getMetadata(int damage) { return damage; }
Itemの該当メソッドが0を返しているため、Overrideしている。onItemUseをOverrideすれば不要。
sampleblock0.json(BlockState用)
BlockState別のモデルJSONファイルの指定を行う。
このファイルは、
assets\<modid>\blockstates
ディレクトリに配置する。
normal:BlockStateの状態指定。"meta=0,bool=false"のように書く。"normal"は状態別にしない場合。
model:モデル用JSONファイルのファイル名を指定。"<modid>:ファイル名"という形式。
sampleblock0.json(Block Model用)
ブロックモデル用JSONファイルである。
このファイルは、
assets\<modid>\models\block
ディレクトリに配置する。
parent:親のモデルJSONファイルを指定。"block/cube_all"で全面同一テクスチャの立方体モデルを指定。
texture:テクスチャのファイルパスを指定。parentの指定により、キーが異なる。"cube_all"の場合は、"all"に指定。
sampleblock0.json(Item Model用)
アイテムモデル用JSONファイルである。
このファイルは、
assets\<modid>\models\item
ディレクトリに配置する。
parent:親のモデルJSONファイルを指定。ブロックの場合は、ブロックモデルのJSONファイルを指定。
display:描画時の回転、平行移動、拡大縮小の係数を指定。コピペ安定。
thirdperson:三人称視点での指定。
他のファイルの説明は省略。