Mod制作日記 - ブロック
前回の続き。
追加するだけで終わっていたブロックに関しても、今回カスタムしていきます!
目次 (折りたたみ可)
カスタムブロック Lv.1
まずは「BlockRegister」クラスでの追加です。
package com.masuec.my_mod.registers;
import com.masuec.my_mod.MyMod;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class BlockRegister {
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MyMod.MODID);
public static final DeferredRegister<Item> BLOCKITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MyMod.MODID);
public static final RegistryObject<Block> TEST_BLOCK = BLOCKS
.register("test_block", () -> new Block(BlockBehaviour.Properties.copy(Blocks.STONE)));
public static final RegistryObject<Item> TEST_BLOCK_ITEM = BLOCKITEMS
.register("test_block", () -> new BlockItem(TEST_BLOCK.get(), new Item.Properties()));
public static final RegistryObject<Block> TEST_BLOCK2 = BLOCKS
.register(
"test_block2", () -> new Block(
BlockBehaviour.Properties.copy(Blocks.STONE)
.friction(0.9F)
.jumpFactor(2F)
.lightLevel(state -> 15)
.sound(SoundType.AMETHYST)
)
);
public static final RegistryObject<Item> TEST_BLOCK2_ITEM = BLOCKITEMS
.register("test_block2", () -> new BlockItem(TEST_BLOCK2.get(), new Item.Properties()));
public static void register(IEventBus evBus) {
BLOCKS.register(evBus);
BLOCKITEMS.register(evBus);
}
}
ブロックでは、BlockBehaviour.Properties.of()に必要なメソッドを連ねて、性質の設定を追加します。 BlockBehaviour.Properties.copy(Blocks.〇〇)につなげる場合は、指定したバニラのブロックの性質のコピーに付け加える/変更する形になります。
メソッド | 概要 | 例 |
---|---|---|
destroyTime | 採掘にかかる時間 | .destroyTime(10F) |
explosionResistance | 爆発耐性 | .explosionResistance(10F) |
forceSolidOn | 立方体のブロックの上にしか置けない | .forceSolidOn() |
friction | 摩擦 | .friction(.9F) |
ignitedByLava | 近くのマグマで着火する | .ignitedByLava() |
instabreak | 草のように一瞬で破壊できる | .instabreak() |
instrument | 音ブロックの音 | .instrument(NoteBlockInstrument.BANJO) |
isRedstoneConductor | レッドストーン導体かどうか | .isRedstoneConductor((state, blockGetter, pos) -> true) |
isSuffocating | 窒息するかどうか | .isSuffocating((state, blockGetter, pos) -> false) |
isValidSpawn | entityTypeのエンティティがこのブロックの上にスポーンできるかどうか | .isValidSpawn((state, blockGetter, pos, entityType) -> false) |
isViewBlocking | 視点が埋まった時に視界をふさぐかどうか | .isViewBlocking((state, blockGetter, pos) -> false) |
jumpFactor | ジャンプの強度(例:ハチミツブロック) | .jumpFactor(2F) |
lightLevel | 光源レベル | .lightLevel(state -> 15) |
mapColor | 地図上での色 | .mapColor(DyeColor.BLACK) |
noCollission | 当たり判定なし | .noCollission() |
noLootTable | 何もドロップしない | .noLootTable() |
noOcclusion | オクルージョン無効(光を遮らないブロックについている) | .noOcclusion() |
noParticlesOnBreak | 壊したときにパーティクルを出さない | .noParticlesOnBreak() |
pushReaction | ピストンで押したとき | .pushReaction(PushReaction.PUSH_ONLY) |
randomTicks | 植物の成長などのランダムティックをする | .randomTicks() |
replaceable | 草のように、上書きするようにして他のブロックを置ける | .replaceable() |
requiresCorrectToolForDrops | 適性ツールで掘らないとドロップしない | .requiresCorrectToolForDrops() |
sound | サウンド設定 | .sound(SoundType.AMETHYST) |
speedFactor | 移動速度(例:ソウルサンド) | .speedFactor(1.2F) |
カスタムブロック Lv.2
次は具体的な例をもとにしたいので、「ONの時間が短いボタン」を作ってみます。
VSCodeのエクスプローラの下から「JAVA PROJECTS > Referenced Libraries > forge-1.20.1... > net.minecraft.world.level.block.Blocks」を開きます。 Blocksクラスのファイルの中で「button」をCtrl + Fで検索すると、stoneButtonまたはwoodenButtonメソッドが見つかると思うので、そのメソッドを「右クリック > 定義へ移動」します。 すると、return文からButtonBlockクラスが使われていることがわかります。
さらに定義へ飛ぶとわかりますが、このクラスのコンストラクタで押された状態の時間を設定できるようです。つまり、
public static final RegistryObject<Block> TEST_BUTTON = BLOCKS.register(
"fast_button",
() -> new ButtonBlock(
BlockBehaviour.Properties.of()
.noCollission()
.strength(0.5F)
.pushReaction(PushReaction.DESTROY)
.sound(SoundType.COPPER),
BlockSetType.IRON,
8, // 押された状態の時間(tick)
false
)
);
public static final RegistryObject<Item> TEST_BUTTON_ITEM = BLOCKITEMS.register(
"fast_button",
() -> new BlockItem(TEST_BUTTON.get(), new Item.Properties())
);
このようにBlockRegisterクラスに書けばいいということですね。
カスタムブロック Lv.3
今度は「押された状態が短い感圧板」を作りましょう。重量感圧板だと踏んだだけでは15動力出ませんからね。
ボタンのときと同じようにバニラのコードを確認するとどうやらコンストラクタからは調節できないようです。 新しいクラスを作るしかありません。
「com.(作者名).(ModのID).block.FastPressurePlate」クラスをつくります。
package com.masuec.my_mod.blocks;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.PressurePlateBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.BlockSetType;
import net.minecraft.world.level.material.PushReaction;
public class FastPressurePlate extends PressurePlateBlock {
public FastPressurePlate() {
super(
PressurePlateBlock.Sensitivity.MOBS,
BlockBehaviour.Properties.copy(Blocks.COPPER_BLOCK)
.forceSolidOn()
.requiresCorrectToolForDrops()
.noCollission()
.pushReaction(PushReaction.DESTROY),
BlockSetType.STONE
);
}
@Override
protected int getPressedTime() {
return 8; // 押された状態の時間(tick)
}
}
getPressedTimeメソッドに関しては「右クリック > ソースアクション > Override/imprement Methods」を選択して、このメソッドにチェックが付いた状態でOKを押すとひな形を書いてくれます。
あとはBlockRegisterクラスでこれを使って新しくブロックを作ればいいというわけですね。
public static final RegistryObject<Block> FAST_PRESSURE_PLATE = BLOCKS
.register("fast_pressure_plate", () -> new FastPressurePlate());
public static final RegistryObject<Item> FAST_PRESSURE_PLATE_ITEM = BLOCKITEMS
.register("fast_pressure_plate", () -> new BlockItem(FAST_PRESSURE_PLATE.get(), new Item.Properties()));