今回から人間ユニットの動作部分(機能部分)の製作に当たります。今後、動作部分のことをAIと呼びます。AIを作る際には entity
ディレクトリ内に ai
というディレクトリを作成し、その中に書いていきます。
1. ディレクトリ構成の確認
まず、今までに作っていたディレクトリを再度確認します。
~/takunologymod
: メインディレクトリでMod全体の名称。takunologymod/entity
: Entity に関する内容をまとめるディレクトリ。takunologymod/init
:FML (Forge Mod Loader) にてMod初期化処理を行う際のデータ登録をまとめる。今回は Enitty の登録を管理するディレクトリになっている。今後、アイテムやブロックなどを増やす場合はこの中に登録用クラスとして付け足していく。takunology/util
:追加事項のあるものを管理するディレクトリ。(今回はレンダラーのイベント初期化処理で使用している。)
ここまでが大まかなディレクトリです。ここからは takunologymod/entity
ディレクトリ内の配置についてです。
entity/ai
: Entity の機能を記述するディレクトリ。動作内容や作業(タスク) 内容の定義で使用。entity/model
Entity の形状を管理するディレクトリ。テクスチャを貼り付けるための胴体に関する定義部分。entity/render
: Entity の描画(レンダリング)を管理するディレクトリ。テクスチャを読み込んで model に貼り付けるための画像を return する。
前回までに model
と render
は定義済みですね。意外と少ないディレクトリ構成で生物は生み出せることが分かったのですが、ここから色々と付け足していく予定です。
上記のディレクトリ構成で作業を進めていきます。
2. PlayerEntityの継承
プレイヤーと同じ構造にしたいので、継承内容を変更します。entity
直下に HumanUnit
がありますが、これは基本ベースとなるクラスです。今の段階では EntityVillager
を継承したままなので、これを EntityPlayer
に変更します。
変更するとスーパークラスへ渡すコンストラクタの引数も変わるので、super
メソッドを変更しなければなりません。ということで、変更してみました。
package jp.takunology.takunologymod.entity; import com.mojang.authlib.GameProfile; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; //プレイヤーベース Entity の継承 public class HumanUnit extends EntityPlayer { public HumanUnit(World worldIn, GameProfile gameProfile) { super(worldIn, gameProfile); } @Override //スペクテイターモード public boolean isSpectator() { return false; } @Override //クリエイティブモード public boolean isCreative() { return false; } }
ここで問題なのが GameProfile
引数です。ここにはゲームプロファイルすなわち固有データを入れなければいけないかもしれません。あと、PlayerEntity
を継承すると、なぜか entity/render/RenderHumanUnit.java
の extends RenderLiving<HumanUnit>
でエラーが発生します。
The type HumanUnit is not a valid substitute for the bounded parameter <T extends EntityLiving> of the type RenderLiving<T>
RenderLiving
の型には一致しないみたいです。 EntityPlayer
が EntityLiving
から継承されていないからかもしれません。そこで、もしやと思って RenderPlayer
があるのかと思って入力してみたら、ありました。
3. RenderPlayer を継承してみる
entity/render/RenderHumanUnit.java
にて RenderPlayer
を継承してみましたが、すごく赤線(エラー)が出てしまいました。メソッドの引数に何を入れたらよいのか分からないので参照してみます。
前回までは RenderLiving
のコンストラクタに色々代入していました。こんな感じでしたね。
public RenderLiving(RenderManager rendermanagerIn, ModelBase modelbaseIn, float shadowsizeIn) { super(rendermanagerIn, modelbaseIn, shadowsizeIn); }
今回継承した RenderPlayer
はこんな感じです。
public RenderPlayer(RenderManager renderManager) { this(renderManager, false); }
どうやら RenderManager
だけを代入すれば描画してくれそうですね。とりあえず RenderHumanUnit.java
を書きかえてみます。
public class RenderHumanUnit extends RenderPlayer { public static final ResourceLocation TEXTURES = new ResourceLocation(TakunologyMod.MODID + ":textures/entity/humanunit_1.png"); public RenderHumanUnit(RenderManager manager) { super(manager); } }
そして実行しようとしたら...
今度はイベントハンドラで型が合わないといわれてしまいました。
4. 試行錯誤の結果
色々やってみて気づいたのですが、プレイヤーのテクスチャ(スキン)はマインクラフトのサーバ上にアップロードする仕組みになってから複雑になっています。サーバ上のプレイヤープロファイルとそのスキンが紐づけられており、それを適切に処理するためのレンダラークラスが書かれています。
ということで、EntityPlayer
を継承してスキンを自由に変更するのは技術的に難しいという判断をしました。おそらくレンダラー関係をいじろうとすると大量のクラス内での変更が必要かと...。
ちょっと継承する Entity を村人ベースにすべきか検討します。