4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Forge】1.13.2での自作したEntityとEntityRenderの登録方法

Last updated at Posted at 2019-06-29

開発環境

OS IDE Forge JDK Lang
Windows10 1809 17763.593 IntelliJ IDEA 2019 1.13.2-25.0.74 1.8.0_202 Java

はじめに

1.13.2でのEntity登録について日本語の資料が少ないと思いましたので、参考になればと思います。
ソースコードは自作ModのTorchBowModを元に説明してきます。

私が気づいた1.12からの変更点

  • Modの初期化処理が並列的に読み込まれるようになった
  • クライアントとサーバ別の処理がしやすくなった。
  • SidedProxyを使わずにクライアントの初期化処理をできるようになった。
  • 一応SidedProxyのような処理方法も残されている。
  • ブロック、アイテム、Entityなどの登録方法が変わった
  • Entityの追加方法が変わった。
  • META-INFフォルダの中にModの情報ファイル「mods.toml」を造る必要がある。
  • recipeのフォルダがassetsからdataになった
  • 言語ファイルがlangからjsonになった。
  • pack.mcmetaが必要になった。
  • データパック用らしい

今回は中でも私がつまずいたEntityの追加についてまとめてみました。
太字部分はEntityの追加に関係してくる変更点です。

Modの初期化処理が並列的に読み込まれるようになった

preInit
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
}

従来ではpreInitやpostInitなどの処理は、上記のようにアノテーションを付加していましたが、今回の変更で@Modアノテーションのあるクラスのコンストラクタで、初期化処理のリスナを登録するように変更されました。
例えば、@Modアノテーションの付いているクラスファイルの名前がTorchBowModの場合、コンストラクタは下記のようになります。

TorchBowMod.java
public class TorchBowMod {
    public TorchBowMod() {
        final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
        modEventBus.addListener(this::preInit);// ここで初期化処理イベントを受け取るリスナを登録
        MinecraftForge.EVENT_BUS.register(this);
    }

    // 仮引数がFMLCommonSetupEventなのでpreInitに相当する
    // FMLLoadCompleteEventだとpostInitに相当する
    // 他にもいろいろなイベントが用意されているが今回は省略
    private void preInit(final FMLCommonSetupEvent event) {
        // preInitで行う処理~~~
    }
}

this::preInitという見慣れない記述が出てきました。
今回のアップデートでラムダ式が積極的に使われているためラムダ式の記述がよく出てきます。
ラムダ式については他の記事を参考にしてください。

SidedProxyを使わずにクライアントの初期化処理をできるようになった

1.12ではCommonProxyというインターフェース若しくはクラスを作り、継承したClientProxyとServerProxyでクライアント・サーバの処理を分岐していたと思います。
1.13.2では上記の初期化処理イベント以外にも、クライアントサイドのイベントFMLClientSetupEventが用意されています。

1.13.2
//クライアントサイドのイベントリスナ
private void initClient(final FMLClientSetupEvent event) {
    //クライアントサイド処理
}

このような感じです。イベントの登録は初期化処理イベントと同じ方法でできます。
さて、Entityのレンダですが1.12と1.13.2では、登録方法に変更はないのでClientProxyで書いていた

ClientProxy
//この場合自作のEntity→EntityTorchとそのEntityのレンダであるRenderTorchを登録している。
enderingRegistry.registerEntityRenderingHandler(EntityTorch.class, RenderTorch::new);

をそのままクライアントサイドのイベントリスナに書くと登録できます。

ブロック、アイテム、Entityなどの登録方法が変わった

1.12ではアイテムやブロックやモデルなどの登録には@SubscribeEventアノテーションを利用してたと思います。
1.13.2では同じアノテーションを利用していますが少々方法が変わりました。
まず@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)アノテーションの付いたstaticクラスを作成する必要があり、そのクラス内に@SubscribeEventアノテーションを付けたレジスターメソッドを記述するようになりました。

RegistryEvents
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents {
    // 仮引数がItemのジェネリクスなのでアイテムの登録だがBlockのジェネリクスにするとブロックの登録処理ができる。
    @SubscribeEvent
    public static void onItemsRegistry(RegistryEvent.Register<Item> event) {
        // この場合アイテムの登録
    }
}

Entityの追加方法が変わった

さてようやく本題ですが。
1.12まではEntityの登録にはEntityRegistryを使用していましたが、1.13.2で削除されたようです。
そのためEntityの登録には上記のRegistryEventを利用する必要があります。
しかしながらForgeにて定義されているジェネリクスの一覧を見てみると。

ForgeRegistries.class
public static final IForgeRegistry<Block> BLOCKS;
public static final IForgeRegistry<Item> ITEMS;
public static final IForgeRegistry<Potion> POTIONS;
public static final IForgeRegistry<Biome> BIOMES;
public static final IForgeRegistry<SoundEvent> SOUND_EVENTS;
public static final IForgeRegistry<PotionType> POTION_TYPES;
public static final IForgeRegistry<Enchantment> ENCHANTMENTS;
public static final IForgeRegistry<VillagerProfession> VILLAGER_PROFESSIONS;
public static final IForgeRegistry<EntityType<?>> ENTITIES;
public static final IForgeRegistry<TileEntityType<?>> TILE_ENTITIES;
public static final IForgeRegistry<ModDimension> MOD_DIMENSIONS;

単純に<Entity>ではな<EntityType<?>>になっています。
ということでジェネリクスには<EntityType<?>>を指定する必要があるのがわかります。
そしてEntityTypeのジェネリクスはEntityType<T extends Entity>になっているためEntityTypeのジェネリクスに指定する型はEntity型である必要があるのがわかります。

ということで早速自作したEntityのEntityTypeを作ってみます。
レンダのときにも出てきた「EntityTorch」というEntityを登録すると想定します。

public static EntityType<EntityTorch> TORCH;

まずは自作のEntityをジェネリクスしたEntityType型のグローバル変数を定義します。

RegistryEvents
@SubscribeEvent
public static void registerEntityTypes(final RegistryEvent.Register<EntityType<?>> event) {
}

そして「ブロック、アイテム、Entityなどの登録方法が変わった」で説明したときの、RegistryEventsクラスに上記のメソッドを追加します。
このメソッド内では、nullのままのTORCHにEntityのプロパティ的な物を書き込んで、その後登録するような処理になります。

registerEntityTypesメソッド内
TORCH= EntityType.Builder.create(EntityTorch.class, EntityTorch::new).tracker(60, 5, true).build(MODID + ":entitytorch");
TORCH.setRegistryName(new ResourceLocation(MODID, "entitytorch"));
event.getRegistry().register(TORCH);

EntityTypeはEntityType.Builderにて作成しますが、この際Entity側も1.13.2での書き方に書き換える必要があります。
これは既存のEntityなどを参考にすればできると思いますので調べるなりしてみてください。
tracker()はそれぞれrange、updateFrequency、sendVelocityUpdatesの順で指定します。
これは1.12でのEntityRegistry.registerModEntity()の第6引数、第7引数、第8引数と同じなので特に困らないでしょう。
レジストリネームなどはアイテムなどと同じ感覚で大丈夫です。

参考元

蛇足

ModdingもQiitaもはじめたばかりなので何か間違いなどやよろしくない点などありましたら指摘していただけると幸いです。
Q:なぜ今更1.13.2のこと書いたの?
A:Qiitaに最近登録したので3か月前ぐらいにブログで書いていた記事を投稿してみました。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?