提供: Minecraft Modding Wiki
移動先: 案内検索
(ModelLoader.setCustomModelResourceLocationを利用するように変更)
(意味不明な解説になってたので)
29行目: 29行目:
 
         if (event.getSide().isClient()) {
 
         if (event.getSide().isClient()) {
 
             //モデルJSONファイルのファイル名を登録。1IDで1つだけなら、登録名はGameRegistryでの登録名と同じものにする。
 
             //モデルJSONファイルのファイル名を登録。1IDで1つだけなら、登録名はGameRegistryでの登録名と同じものにする。
            //ItemStackのmetadataで種類を分けて描画させたい場合。登録名を予め登録する。
+
             ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(sampleBlock), 0, new ModelResourceLocation(MOD_ID + ":" + "sampleblock", "inventory"));
            ModelBakery.addVariantName(Item.getItemFromBlock(sampleBlock), MOD_ID + ":" + "sampleblock0", MOD_ID + ":" + "sampleblock1");
 
            //1IDで複数モデルを登録するなら、上のメソッドで登録した登録名を指定する。
 
             ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(sampleBlock), 0, new ModelResourceLocation(MOD_ID + ":" + "sampleblock0", "inventory"));
 
            ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(sampleBlock), 1, new ModelResourceLocation(MOD_ID + ":" + "sampleblock1", "inventory"));
 
 
         }
 
         }
 
     }
 
     }
45行目: 41行目:
  
 
public class SampleBlock extends Block {
 
public class SampleBlock extends Block {
    //BlockState用Property変数。今回はmetadataと同じようなPropertyIntegerを用いる。
 
    public static final PropertyInteger METADATA = PropertyInteger.create("meta", 0, 1);
 
 
 
     public SampleBlock() {
 
     public SampleBlock() {
 
         super(Material.rock);
 
         super(Material.rock);
 
         setCreativeTab(CreativeTabs.tabBlock);/*クリエイティブタブの選択*/
 
         setCreativeTab(CreativeTabs.tabBlock);/*クリエイティブタブの選択*/
 
         setUnlocalizedName("blockSample");/*システム名の設定*/
 
         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));
 
 
     }
 
     }
  
98行目: 55行目:
  
 
     /**
 
     /**
    特に変えない
 
    */
 
    @SideOnly(Side.CLIENT)
 
    public int getBlockColor(){
 
        return 0xffffff;
 
    }
 
 
    /**
 
    BlockStateで色を変えている。 パーティクルは変えないようにする。
 
    */
 
    @SideOnly(Side.CLIENT)
 
    public int getRenderColor(IBlockState state){
 
        if(checkStackRoot()) return 0xffffff;
 
        return ItemDye.dyeColors[(Integer) state.getValue(METADATA)];
 
    }
 
 
    /**
 
    RenderPassを利用しないのでgetRenderColorと同じで良い
 
 
     RenderPassに渡される数値はJsonで指定したtintindexで、tintindexを指定しないとこのメソッドは呼ばれない。
 
     RenderPassに渡される数値はJsonで指定したtintindexで、tintindexを指定しないとこのメソッドは呼ばれない。
 
     @see #getRenderColor
 
     @see #getRenderColor
121行目: 60行目:
 
     @SideOnly(Side.CLIENT)
 
     @SideOnly(Side.CLIENT)
 
     public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass){
 
     public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass){
         return getRenderColor(worldIn.getBlockState(pos));
+
         return ItemDye.dyeColors[renderPass];
    }
 
 
 
    /**
 
    StackTraceElementを使ってパーティクル生成時にメソッドが呼ばれているかチェック
 
    */
 
    public static boolean checkStackRoot(){
 
        StackTraceElement[] es = new Exception().getStackTrace();
 
        String particle = EntityDiggingFX.class.getCanonicalName()/*"net.minecraft.client.particle.EntityDiggingFX"*/;
 
        return es[2].getClassName().equals(particle) || es[4].getClassName().equals(particle);
 
 
     }
 
     }
 
}
 
}
138行目: 68行目:
 
package等省略
 
package等省略
  
public class SampleItemBlock extends ItemColored {
+
public class SampleItemBlock extends ItemBlock{
     /**booleanとBooleanの違いか、GameRegistoryでItemColoredそのままを利用できないので第二引数を潰す*/
+
    public SampleItemBlock(Block block){
     public SampleItemBlock(Block block) {
+
        super(block);
         super(block,false);
+
    }
 +
 
 +
     /**
 +
    Layerが機能しているかの確認。
 +
    */
 +
    @SideOnly(Side.CLIENT)
 +
     public int getColorFromItemStack(ItemStack stack, int renderPass){
 +
         return block.colorMultiplier(null, null, renderPass);
 
     }
 
     }
 
}
 
}
 
 
</source>
 
</source>
 
*sampleblock.json(BlockState用)
 
*sampleblock.json(BlockState用)
150行目: 86行目:
 
{
 
{
 
     "variants": {
 
     "variants": {
         "meta=0":  { "model": "samplemod:sampleblock0" },
+
         "normal":  { "model": "samplemod:sampleblock" }
        "meta=1":  { "model": "samplemod:sampleblock1" }
 
 
     }
 
     }
 
}
 
}
292行目: 227行目:
 
     "textures": {
 
     "textures": {
 
         "all": "blocks/dirt",
 
         "all": "blocks/dirt",
         "overlayall": "items/potion_overlay"
+
         "overlayall": "items/snowball"
 
     }
 
     }
 
}
 
}
324行目: 259行目:
  
 
     /**
 
     /**
    特に変えない
 
    */
 
    @SideOnly(Side.CLIENT)
 
    public int getBlockColor(){
 
        return 0xffffff;
 
    }
 
 
    /**
 
    BlockStateで色を変えている。 パーティクルは変えないようにする。
 
    */
 
    @SideOnly(Side.CLIENT)
 
    public int getRenderColor(IBlockState state){
 
        if(checkStackRoot()) return 0xffffff;
 
        return ItemDye.dyeColors[(Integer) state.getValue(METADATA)];
 
    }
 
 
    /**
 
    RenderPassを利用しないのでgetRenderColorと同じで良い
 
 
     RenderPassに渡される数値はJsonで指定したtintindexで、tintindexを指定しないとこのメソッドは呼ばれない。
 
     RenderPassに渡される数値はJsonで指定したtintindexで、tintindexを指定しないとこのメソッドは呼ばれない。
 
     @see #getRenderColor
 
     @see #getRenderColor
347行目: 264行目:
 
     @SideOnly(Side.CLIENT)
 
     @SideOnly(Side.CLIENT)
 
     public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass){
 
     public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass){
         return getRenderColor(worldIn.getBlockState(pos));
+
         return ItemDye.dyeColors[renderPass];
    }
 
 
 
    /**
 
    StackTraceElementを使ってパーティクル生成時にメソッドが呼ばれているかチェック
 
    */
 
    public static boolean checkStackRoot(){
 
        StackTraceElement[] es = new Exception().getStackTrace();
 
        String particle = EntityDiggingFX.class.getCanonicalName()/*"net.minecraft.client.particle.EntityDiggingFX"*/;
 
        return es[2].getClassName().equals(particle) || es[4].getClassName().equals(particle);
 
 
     }
 
     }
 
</source>
 
</source>
 
基本的にコメントのとおりである。
 
基本的にコメントのとおりである。
 
===SampleItemBlock.java===
 
ItemColorを継承しているため、特に気にすべき点はない。
 
  
 
===sampleblock0.json(BlockState用)===
 
===sampleblock0.json(BlockState用)===

2015年9月10日 (木) 21:23時点における版

この記事は"Minecraft Forge Universal 11.14.0.xxx~"を前提MODとしています。

Wood pickaxe.png
初心者向けのチュートリアルです。
C block.png
Blockに関係のあるチュートリアルです。

ワールド上に設置できる簡単なブロックの追加方法

ブロックの追加

注意:一度入れたMODを外すと、再び入れてもテクスチャが反映されなくなります。デバッグ時にご注意を。

ソースコード

  • SampleMod.java
package等省略

@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;

    public static Block sampleBlock;

    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        sampleBlock = new SampleBlock();
        //ブロックの登録。登録文字列はMOD内で被らなければ何でも良い。

        GameRegistry.registerBlock(sampleBlock, SampleItemBlock.class, "sampleblock");

        //テクスチャ・モデル指定JSONファイル名の登録。
        if (event.getSide().isClient()) {
            //モデルJSONファイルのファイル名を登録。1IDで1つだけなら、登録名はGameRegistryでの登録名と同じものにする。
            ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(sampleBlock), 0, new ModelResourceLocation(MOD_ID + ":" + "sampleblock", "inventory"));
        }
    }
}
  • SampleBlock.java
package等省略

public class SampleBlock extends Block {
    public SampleBlock() {
        super(Material.rock);
        setCreativeTab(CreativeTabs.tabBlock);/*クリエイティブタブの選択*/
        setUnlocalizedName("blockSample");/*システム名の設定*/
    }

    /**返しているのは「切り抜き」「ミップマップされた」である。*/
    @Override
    @SideOnly(Side.CLIENT)
    public EnumWorldBlockLayer getBlockLayer(){
        return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }

    /**
     RenderPassに渡される数値はJsonで指定したtintindexで、tintindexを指定しないとこのメソッドは呼ばれない。
     @see #getRenderColor
     */
    @SideOnly(Side.CLIENT)
    public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass){
        return ItemDye.dyeColors[renderPass];
    }
}
  • SampleItemBlock.java
package等省略

public class SampleItemBlock extends ItemBlock{
    public SampleItemBlock(Block block){
        super(block);
    }

    /**
     Layerが機能しているかの確認。
     */
    @SideOnly(Side.CLIENT)
    public int getColorFromItemStack(ItemStack stack, int renderPass){
        return block.colorMultiplier(null, null, renderPass);
    }
}
  • sampleblock.json(BlockState用)
{
    "variants": {
        "normal":  { "model": "samplemod:sampleblock" }
    }
}

</source>

  • samplebase.json
{
  "elements": [
    {
      "from": [0,0,0],
      "to": [16,16,16],
      "faces": {
        "down": {
          "uv": [0,0,16,16],
          "texture": "#bottom",
          "cullface": "down"
        },
        "up": {
          "uv": [ 0,0,16,16],
          "texture": "#top",
          "cullface": "up"
        },
        "north": {
          "uv": [0,0,16,16],
          "texture": "#north",
          "cullface": "north"
        },
        "south": {
          "uv": [0,0,16,16],
          "texture": "#south",
          "cullface": "south"
        },
        "west": {
          "uv": [0,0,16,16],
          "texture": "#west",
          "cullface": "west"
        },
        "east": {
          "uv": [0,0,16,16],
          "texture": "#east",
          "cullface": "east"
        }
      }
    },
    {
      "from": [0,0,0],
      "to": [16,16,16],
      "faces": {
        "down": {
          "uv": [0,0,16,16],
          "texture": "#overlaybottom",
          "tintindex": 0,
          "cullface": "down"
        },
        "up": {
          "uv": [0,0,16,16],
          "texture": "#overlaytop",
          "tintindex": 1,
          "cullface": "up"
        },
        "north": {
          "uv": [0,0,16,16],
          "texture": "#overlaynorth",
          "tintindex": 2,
          "cullface": "north"
        },
        "south": {
          "uv": [0,0,16,16
          ],
          "texture": "#overlaysouth",
          "tintindex": 3,
          "cullface": "south"
        },
        "west": {
          "uv": [0,0,16,16],
          "texture": "#overlaywest",
          "tintindex": 4,
          "cullface": "west"
        },
        "east": {
          "uv": [0,0,16,16],
          "texture": "#overlayeast",
          "tintindex": 5,
          "cullface": "east"
        }
      }
    }
  ]
}
  • samplebase_all.json
{
  "parent": "samplemod:block/samplebase",
  "textures": {
    "particle": "#all",
    "bottom": "#all",
    "top": "#all",
    "north": "#all",
    "east": "#all",
    "south": "#all",
    "west": "#all",
    "overlaybottom": "#overlayall",
    "overlaytop": "#overlayall",
    "overlaynorth": "#overlayall",
    "overlayeast": "#overlayall",
    "overlaysouth": "#overlayall",
    "overlaywest": "#overlayall"
  }
}
  • sampleblock0.json(Block Model用)
{
    "parent": "samplemod:block/samplebase_all",
    "textures": {
        "all": "blocks/stone",
        "overlayall": "blocks/grass_side_overlay"
    }
}
  • 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(Block Model用)
{
    "parent": "samplemod:block/samplebase_all",
    "textures": {
        "all": "blocks/dirt",
        "overlayall": "items/snowball"
    }
}
  • 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

同様の処理なため1.8のブロック追加を参照のこと。

SampleBlock.java

/**返しているのは「切り抜き」「ミップマップされた」である。*/
    @Override
    @SideOnly(Side.CLIENT)
    public EnumWorldBlockLayer getBlockLayer(){
        return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }

    /**
     RenderPassに渡される数値はJsonで指定したtintindexで、tintindexを指定しないとこのメソッドは呼ばれない。
     @see #getRenderColor
     */
    @SideOnly(Side.CLIENT)
    public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass){
        return ItemDye.dyeColors[renderPass];
    }

基本的にコメントのとおりである。

sampleblock0.json(BlockState用)

BlockState別のモデルJSONファイルの指定を行う。 このファイルは、
assets\<modid>\blockstates
ディレクトリに配置する。

meta=0:BlockStateの状態指定。"meta=0,bool=false"のように書く。BlockStatesが無い場合は、"normal"とする。

model:モデル用JSONファイルのファイル名を指定。"<modid>:ファイル名"という形式。

sampleblock0.json(Block Model用)

ブロックモデル用JSONファイルである。 このファイルは、
assets\<modid>\models\block
ディレクトリに配置する。

parent:親のモデルJSONファイルを指定。"samplemod:block/samplebase_all"で全面同一テクスチャの立方体モデルを指定。

texture:テクスチャのファイルパスを指定。この場合は、"all"と"overlayall"に指定。

sampleblock0.json(Item Model用)

アイテムモデル用JSONファイルである。 このファイルは、
assets\<modid>\models\item
ディレクトリに配置する。

parent:親のモデルJSONファイルを指定。ブロックの場合は、ブロックモデルのJSONファイルを指定。

display:描画時の回転、平行移動、拡大縮小の係数を指定。コピペ安定。

thirdperson:三人称視点での指定。

他のファイルの説明は省略。