カスタムモデル付きブロックの追加(1.7.10)

1.7.10の開発講座を修正中です。このページには誤りや古い情報が含まれる可能性があります。

特殊な形のブロックを追加する。
今回は、アルミ製の金床を追加する。
(……としたいのだが、金床のGUIに関しては、実装していない。悪しからず。)

この内容はとても難解なものを含んでいるうえ、汎用性に乏しい。
そのため、更に汎用性の高いものを作る場合は、net.minecraft.client.rendererのRenderBlocksを参照。

ソースコード

package aluminiummod.common;
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;

/**
*
* @author Akasata Nahama & Tom Kate & YOU!!
*
*/
@Mod(modid = "AluminiumMod", name = "Aluminium Mod")
public class AluminiumMod {

	//追加するブロックの定義
	/*public static Block * ;*/
	public static Block AnvilAluminium;

	//レンダーIDの取得
	public static int RenderID;

	@EventHandler
	public void perInit(FMLPreInitializationEvent event) {

		/*ブロックの実装。詳細割愛。*/
		AnvilAluminium = new AnvilAluminium();

		AnvilAluminium.setCreativeTab(CreativeTabs.tabBlock);

		AnvilAluminium.setBlockName("blockAluminium");

		AnvilAluminium.setBlockTextureName("aluminiummod:aluminium_anvil");

		GameRegistry.registerBlock(AnvilAluminium, "AnvilAluminium");


	}

	@EventHandler
	public void init (FMLInitializationEvent event) {
		/*FMLCommonHandler.instance().getSide() で、クライアントサイドでのみの動作としている。*/
		if(FMLCommonHandler.instance().getSide() == Side.CLIENT)
		{
			/*レンダーIDの設定。
			 * RenderingRegistry.getNextAvailableRenderId() で、未使用のレンダーIDを取得する。*/
			this.RenderID = RenderingRegistry.getNextAvailableRenderId();

			/*ブロックのレンダラ―を設定する。
			 *RenderingRegistry.registerBlockHandler(ISimpleBlockRenderingHandler); */
			RenderingRegistry.registerBlockHandler(new RenderAnvilAluminium());

		}
	}
package aluminiummod.common;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class AnvilAluminium extends Block{

	public AnvilAluminium() {
		super(Material.rock);
	}

		/**レンダーIDを返す。**/
		@Override
		public int getRenderType()
		{
			return AluminiumMod.RenderID;
		}

		/**ブロックが透けるか否かを返す。**/
	    @SideOnly(Side.CLIENT)
	    public boolean shouldSideBeRendered(IBlockAccess p_149646_1_, int p_149646_2_, int p_149646_3_, int p_149646_4_, int p_149646_5_)
	    {
	        return true;
	    }

	    /**通常のブロックでないかを返す。*/
	    public boolean renderAsNormalBlock()
	    {
	        return false;
	    }

	    /**ブロックが透明か否かを返す。*/
	    public boolean isOpaqueCube()
	    {
	        return false;
	    }
}
package aluminiummod.common;

import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.world.IBlockAccess;

import org.lwjgl.opengl.GL11;

import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;

public class RenderAnvilAluminium implements ISimpleBlockRenderingHandler
{
	/**インベントリ内でブロックをレンダリングするメソッド。もしshouldRender3DInInventoryがfalseなら空でもいいかも。**/
	@Override
	public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer)
	{
		if (modelId == this.getRenderId())
		{
			float f = 0;
			f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.75F, 0.25F, 0.75F ,false);
			f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.5F, 0.0625F, 0.625F ,false);
			f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.25F, 0.3125F, 0.5F ,false);
			this.renderAlumiAnvil(block, renderer, metadata, f, 0.625F, 0.375F, 1.0F ,false);



		}
	}

	/**ワールド内でブロックをレンダリングするメソッド**/
	@Override
	public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
	{
		if (modelId == this.getRenderId())
		{
			/*レンダリングする立方体のサイズを決めるメソッド。
			 * setRenderBounds(始点X, 始点Y, 始点Z, 終点X, 終点Y, 終点Z)*/
			renderer.setRenderBounds(0.1D, 0.0D, 0.1D, 0.9D, 0.2D, 0.9D);
			/*レンダリングするメソッド。
			 * renderStandardBlock(block, x, y, z);*/
			renderer.renderStandardBlock(block, x, y, z);
			renderer.setRenderBounds(0.25D, 0.2D, 0.25D, 0.75D, 0.3D, 0.75D);
			renderer.renderStandardBlock(block, x, y, z);
			renderer.setRenderBounds(0.3D, 0.3D, 0.2D, 0.7D, 0.6D, 0.8D);
			renderer.renderStandardBlock(block, x, y, z);
			renderer.setRenderBounds(0.2D, 0.6D, 0.0D, 0.8D, 1.0D, 1.0D);
			renderer.renderStandardBlock(block, x, y, z);

			return true;
		}
		return false;
	}

	@Override
	/**インベントリ内で3Dレンダリングするか否かを返すメソッド**/
	public boolean shouldRender3DInInventory(int modelId) {
		return true;
	}

	/**自身のレンダーIDを返すメソッド**/
	@Override
	public int getRenderId() {

		return AluminiumMod.RenderID;
	}

	protected float renderAlumiAnvil(Block block , RenderBlocks renderer , int metadata , float sides1 , float sides2 , float sides3  , float sides4 , boolean flg)
	{
		/**詳しい説明はカット。ここは難しいため、基本的にはshouldRender3DInInventoryをfalseにすることをお勧めする。**/
		if(flg)
		{
			float f = sides2;
			sides2 = sides4;
			sides4 =f;
		}
		sides2 /= 2.0F;
        sides4 /= 2.0F;
		renderer.setRenderBounds((double)(0.5F - sides2), (double)sides1, (double)(0.5F - sides4), (double)(0.5F + sides2), (double)(sides1 + sides3), (double)(0.5F + sides4));
          /*これより下は、ブロックを各面ごとにレンダリングしている。*/
		Tessellator tessellator = Tessellator.instance;
		GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
		tessellator.startDrawingQuads();
		tessellator.setNormal(0.0F, -1.0F, 0.0F);
		renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 0, metadata));
		tessellator.draw();
		tessellator.startDrawingQuads();
		tessellator.setNormal(0.0F, 1.0F, 0.0F);
		renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 1, metadata));
		tessellator.draw();
		tessellator.startDrawingQuads();
		tessellator.setNormal(0.0F, 0.0F, -1.0F);
		renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 2, metadata));
		tessellator.draw();
		tessellator.startDrawingQuads();
		tessellator.setNormal(0.0F, 0.0F, 1.0F);
		renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 3, metadata));
		tessellator.draw();
		tessellator.startDrawingQuads();
		tessellator.setNormal(-1.0F, 0.0F, 0.0F);
		renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 4, metadata));
		tessellator.draw();
		tessellator.startDrawingQuads();
		tessellator.setNormal(1.0F, 0.0F, 0.0F);
		renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 5, metadata));
		tessellator.draw();
		GL11.glTranslatef(0.5F, 0.5F, 0.5F);
		renderer.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
		return sides1 + sides3;
	}

}

解説

RenderAnvilAluminium

この中では、インベントリ内でのレンダリングが一番難しいはずである。
もし大変ならば、shouldRender3DInInventoryをfalseにすればインベントリにはテクスチャのみが表示されるため、作業が楽になる。

カスタムモデル付きブロックの追加(1.7.10)” への2件のフィードバック

  1. マルチで使用するとクラッシュするのですが

  2. クラッシュレポートをtomkate☆tntmodders.com (☆を@に変えてください)に送っていただけますでしょうか。
    よろしくおねがいします。

コメントはこちら。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

[最終更新日]2017/11/21 20:00