提供: Minecraft Modding Wiki
2017年3月26日 (日) 23:13時点におけるKairi (トーク | 投稿記録)による版 (ソースコード)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

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

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

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

ブロックの追加

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

ソースコード

  • SampleMod.java
package com.example.examplemod;

import net.minecraft.block.Block;
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.client.model.ModelLoader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;

@Mod(modid = SampleMod.MOD_ID, 
        name = SampleMod.MOD_NAME, 
        version = SampleMod.MOD_VERSION, 
        dependencies = SampleMod.MOD_DEPENDENCIES,
        acceptedMinecraftVersions = SampleMod.MOD_ACCEPTED_MC_VERSIONS,
        useMetadata = true)
public class SampleMod {
    /** ModId文字列 */
    public static final String MOD_ID = "samplemod";
    /** MOD名称 */
    public static final String MOD_NAME = "SampleMod";
    /** MODのバージョン */
    public static final String MOD_VERSION = "0.0.1";
    /** 先に読み込まれるべき前提MODをバージョン込みで指定 */
    public static final String MOD_DEPENDENCIES = "required-after:Forge@[1.8-11.14.0.1239,)";
    /** 起動出来るMinecraft本体のバージョン。記法はMavenのVersion Range Specificationを検索すること。 */
    public static final String MOD_ACCEPTED_MC_VERSIONS = "[1.8,1.8.9]";
    /** 追加したいブロックのインスタンスを格納するための変数。レシピ等で利用。 */
    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での登録名と同じものにする。
            //ItemStackのmetadataで種類を分けて描画させたい場合。登録名を予め登録する。
            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"));
            //ModelLoader.setCustomStateMapper(sampleBlock, (new StateMap.Builder()).addPropertiesToIgnore(sampleBlock.METADATA).build());
            //上記のようにして無視させたいPropertyを指定することもできる。
            //その他にもここで設定できる項目もあるが割愛させていただく。
        }
    }
}
  • 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));
    }
}
  • SampleItemBlock.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;
    }
}
  • sampleblock.json(BlockState用)
{
    "variants": {
        "meta=0":  { "model": "samplemod:sampleblock0" },
        "meta=1":  { "model": "samplemod:sampleblock1" }
    }
}
  • 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(Block Model用)
{
    "parent": "block/cube",
    "textures": {
        "particle": "blocks/wool_colored_orange",
        "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で複数モデルを登録するなら、上のメソッドで登録した登録名を指定する。
            ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(sampleBlock), 0, new ModelResourceLocation(MOD_ID + ":" + "sampleBlock0", "inventory"));
            ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(sampleBlock), 1, new ModelResourceLocation(MOD_ID + ":" + "sampleBlock1", "inventory"));
            //ModelLoader.setCustomStateMapper(sampleBlock, (new StateMap.Builder()).addPropertiesToIgnore(sampleBlock.METADATA).build());
            //上記のようにして無視させたいPropertyを指定することもできる。
            //その他にもここで設定できる項目もあるが割愛させていただく。
        }

ブロックのテクスチャ・モデルのJSONファイルのファイル名を登録している。 ModelBakery#addVariantNameメソッドは、羊毛ブロックのような、1IDで複数種類のブロックのモデルを登録する際の登録名を予め指定しておくメソッドである。 BlockStateのPropertyを持たないブロックを追加する場合は必要ない。 ModelLoader#setCustomModelResourceLocationメソッドでテクスチャ・モデルの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
ディレクトリに配置する。(※MODIDに大文字が含まれる場合、フォルダ名称は小文字にする)

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

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

sampleblock0.json(Block Model用)

ブロックモデル用JSONファイルである。 このファイルは、
assets\<modid>\models\block
ディレクトリに配置する。(※MODIDに大文字が含まれる場合、フォルダ名称は小文字にする)

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

texture:テクスチャのファイルパスを指定。parentの指定により、キーが異なる。"cube_all"の場合は、"all"に指定。

sampleblock0.json(Item Model用)

アイテムモデル用JSONファイルである。 このファイルは、
assets\<modid>\models\item
ディレクトリに配置する。(※MODIDに大文字が含まれる場合、フォルダ名称は小文字にする)

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

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

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

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