【マインクラフト（統合版）】ダミーエンティティの作り方まとめ

# はじめに

ここでは以下の環境で利用しているダミーエンティティの作り方をまとめています。

https://qiita.com/glasses_seven/items/433ac9d9fcbdb72c6d18/

モブ等のエンティティとは異なりダミーエンティティが作れるようになると、システム的に色んなコンテンツで応用できるようになります。

また、ダミーエンティティのようなアニメーションの必要がないものを作るだけであれば、特別なツールを使わなくてもJSONデータを組み立てるだけなのでお手軽です。


# 定義ファイルの内訳

カスタムエンティティを作るためにはビヘイビアパックとリソースパックの両方が必要になりますが、最低限以下の３ファイルを追加すれば実装は完了します。

:::note info
ここでは`customize:dummy_entity`というエンティティIDを使う想定でファイル名を記載しています。
:::

```terminal:ビヘイビアパック内で必要になるファイル
/<ビヘイビアパックのルート>
    /entities
        dummy_entity.json
```

```terminal:リソースパック内で必要になるファイル
/<リソースパックのルート>
    /entity
        dummy_entity.entity.json
    /models
        /entity
            dummy_entity.geo.json
```


# 定義ファイルの内容

### ビヘイビアパック

```json:entities/dummy_entity.json
{
    "format_version": "1.17.10",
    "minecraft:entity": {
        "description": {
            "identifier": "customize:dummy_entity",
            "is_spawnable": false,
            "is_summonable": true
        },
        "components": {}
    }
}
```

上記の`format_version`と`minecraft:entity`の項目は固定だとお考えください。

<br />
<dl>
    <dt>・description</dt>
    <dd>
        <dl>
            <dt>identifier</dt>
            <dd>エンティティIDを設定します。</dd>
            <dt>is_spawnable</dt>
            <dd>スポーンエッグの利用可否（true：利用可能、false：利用不可）。</dd>
            <dt>is_summonable</dt>
            <dd><code>summon</code>コマンドの利用可否（true：利用可能、false：利用不可）。</dd>
        </dl>
    </dd>
    <dt>・components</dt>
    <dd>
        このブロックでエンティティの持つさまざまな性質や機能を定義する事ができるので、見た目以外の部分でオリジナルコンテンツを作る時はこの部分の定義がメインになるでしょう。<br />
        ダミーエンティティを作るだけなら空のままで問題ありません。<br />
        定義内容についての詳細は以下の<a href="#コンポーネント定義">&gt;&gt; コンポーネント定義</a>の項目をご覧ください。
    </dd>
</dl><br />

### リソースパック

```json:entity/dummy_entity.entity.json
{
    "format_version": "1.10.0",
    "minecraft:client_entity": {
        "description": {
            "identifier": "customize:dummy_entity",
            "materials": {
                "default": "entity_alphatest"
            },
            "textures": {
                "default": "textures/entity/dummy_entity"
            },
            "geometry": {
                "default": "geometry.dummy_entity"
            },
            "render_controllers": [
                "controller.render.item_sprite"
            ]
        }
    }
}
```

上記の`format_version`と`minecraft:client_entity`の項目は固定だとお考えください。

<br />
<dl>
    <dt>・description</dt>
    <dd>
        <dl>
            <dt>identifier</dt>
            <dd>エンティティIDを設定します。</dd>
            <dt>materials</dt>
            <dd>
                ダミーエンティティの場合は<code>entity_alphatest</code>で問題ありません。<br />
                テクスチャに透明な部分がある場合に指定するものですが、テスト時はこの方が都合がいいでしょう。
            </dd>
            <dt>textures</dt>
            <dd>
                テクスチャのパスを設定します。<br />
                <code>textures/entity</code>に格納するので、今回の場合はネームスペースを省いて<code>textures/entity/dummy_entity</code>としています。<br />
                ダミーエンティティとして表示させない場合はテクスチャファイルがなくても動作しますが、テストする時の事を考慮して設定しておいた方がいいでしょう。
            </dd>
            <dt>geometry</dt>
            <dd>
                <code>models/entity</code>で定義しているジオメトリ名を設定します。<br />
                今回の場合はネームスペースを省いて<code>geometry.dummy_entity</code>としています。
            </dd>
            <dt>render_controllers</dt>
            <dd>
                テストする時の事を考慮して<code>controller.render.item_sprite</code>（スプライト制御）にしておいた方がいいでしょう。
            </dd>
        </dl>
    </dd>
</dl><br />

```json:models/entity/dummy_entity.geo.json
{
    "format_version" : "1.16.0",
    "minecraft:geometry" : [
        {
            "description" : {
                "identifier" : "geometry.dummy_entity",
                "texture_width" : 0.0,
                "texture_height" : 0.0
            }
        }
    ]
}
```

上記の`format_version`と`minecraft:geometry`の項目は固定だとお考えください。

<br />
<dl>
    <dt>・description</dt>
    <dd>
        <dl>
            <dt>identifier</dt>
            <dd>
                ジオメトリ名を設定します。<br />
                今回の場合はネームスペースを省いて<code>geometry.dummy_entity</code>としています。
            </dd>
            <dt>texture_width</dt>
            <dd>
                モデルの横サイズを指定します。<br />
                表示する予定のないダミーエンティティであればゼロで問題ありません（スプライト表示の時は必要としないパラメータです）。
            </dd>
            <dt>texture_height</dt>
            <dd>
                モデルの縦サイズを指定します。<br />
                表示する予定のないダミーエンティティであればゼロで問題ありません（スプライト表示の時は必要としないパラメータです）。
            </dd>
        </dl>
    </dd>
</dl><br />


# テストしてみる

ここまで定義できればダミーエンティティとしての最低限の実装は完了です。
この時点で正しく召喚できるのかテストしておいた方がいいでしょう。

但し今のままでは召喚できたとしても透明のままなので目視で確認する事ができません。
そこで以下の手順に従ってテストを進めてください。

### ①ダミー画像を設置

リソースパック内の`textures/entity`の場所にダミー画像を格納してください。

基本的にデザインやサイズは何でも構いませんが、バニラのリソースパック内にある`textures/items/ender_pearl.png`（エンダーパール）あたりを使っておけば、わざわざ作る必要がないので手間が省けるでしょう。

`entity/dummy_entity.entity.json`内の`textures`の項目で設定した`dummy_entity`という名前がファイル名になるので`dummy_entity.png`という名前にしておきます。

### ②スプライト表示にする

バニラデータにはスプライト表示をサポートするJSONデータがあらかじめ用意されていますので、今回はこれを利用します。

先ほど作ったリソースパック内の`entity/dummy_entity.entity.json`というファイルの内容を以下の`geometry`ブロックの部分と同じになるように修正します。

```json:entity/dummy_entity.entity.json
{
    "format_version": "1.10.0",
    "minecraft:client_entity": {
        "description": {
            "identifier": "customize:dummy_entity",
            "materials": {
                "default": "entity_alphatest"
            },
            "textures": {
                "default": "textures/entity/dummy_entity"
            },
            "geometry": {
                // "default": "geometry.dummy_entity"
                "default": "geometry.item_sprite"
            },
            "render_controllers": [
                "controller.render.item_sprite"
            ]
        }
    }
}
```

この修正によってダミーエンティティがスプライト表示されるようになります。
ちなみにバニラのエンダーパールの表示もスプライト制御で実装されています。

:::note info
コメントの書き方は以下のページでも掲載しましたが`//`（スラッシュ２つ）を入力する事でコメント扱いにできます。
:::

https://qiita.com/glasses_seven/items/c05d198c78ddad8b9029/

### ③コマンドで召喚する

コマンド行で`summon customize`というところまで入力すると、入力補助の機能が働いて以下の赤枠部分のように選択できるエンティティIDが表示されるはずです。

![入力補助の表示](https://socket-manager.github.io/document/minecraft-contents/img/custom-entity-dummy/summon-input.png?reload "入力補助の表示")

これが表示されればJSONファイルが正しく認識されています。
後は実際に`summon`コマンドを使って適当な座標に召喚すると以下のように出現します。

![エンティティの召喚](https://socket-manager.github.io/document/minecraft-contents/img/custom-entity-dummy/summon.png "エンティティの召喚")

召喚できる事が確認できたら`entity/dummy_entity.entity.json`内のコメントアウトを元に戻して`geometry.item_sprite`の方をコメントアウトして残しておくのがいいでしょう。
ダミー画像も含めて残しておくと今後のテスト時にも有効活用できます。


# コンポーネント定義

これまでの設定でベースの部分は出来上がりました。
あとは用途に応じてビヘイビアパック内にある`entities/dummy_entity.json`ファイルの`components`ブロックに都度必要な定義を追加していく事になります。

ここでは`components`ブロックのうち本環境で汎用的に使っている部分だけをピックアップしておきます。

<br />
<dl>
    <dt>・minecraft:nameable</dt>
    <dd>
        名札や<code>summon</code>コマンドによる命名が可能かどうかを設定します。<br/>
        <code>minecraft:nameable</code>ブロック自体が未定義の場合はネーミングできません。
        <dl>
            <dt>allow_name_tag_renaming（デフォルト:true）</dt>
            <dd>
                trueの場合、名札を使って名前を変更できます。<br />
            </dd>
        </dl>
        <dl>
            <dt>always_show（デフォルト:false）</dt>
            <dd>
                trueの場合、名札は常に表示されます。<br />
            </dd>
        </dl>
    </dd>
    <dt>・minecraft:health</dt>
    <dd>
        スポーン時の体力値を設定します。
        <dl>
            <dt>value</dt>
            <dd>
                デフォルトの体力値を整数、または範囲で設定します。<br />
                範囲で設定する時は以下の通り。
                <dl>
                    <dt>range_min</dt>
                    <dd>
                        デフォルト体力の最小値を設定します。
                    </dd>
                    <dt>range_max</dt>
                    <dd>
                        デフォルト体力の最大値を設定します。
                    </dd>
                </dl>
            </dd>
            <dt>max</dt>
            <dd>
                最大の体力値を整数で設定します。<br />
            </dd>
        </dl>
    </dd>
    <dt>・minecraft:breathable</dt>
    <dd>
        呼吸可否等の設定値を設定します。
        <dl>
            <dt>breathe_blocks（デフォルト:なし）</dt>
            <dd>
                呼吸できるブロックのリストを設定します。
            </dd>
            <dt>breathes_air（デフォルト:true）</dt>
            <dd>
                trueの場合、空気中で呼吸できます。
            </dd>
            <dt>breathes_lava（デフォルト:true）</dt>
            <dd>
                trueの場合、溶岩で呼吸できます。
            </dd>
            <dt>breathes_solids（デフォルト:false）</dt>
            <dd>
                trueの場合、固体ブロックで呼吸できます。
            </dd>
            <dt>breathes_water（デフォルト:false）</dt>
            <dd>
                trueの場合、水中で呼吸できます。
            </dd>
            <dt>inhale_time（デフォルト:0）</dt>
            <dd>
                呼吸ゲージを最大まで回復するまでの秒数を設定します。
            </dd>
            <dt>non_breathe_blocks（デフォルト:なし）</dt>
            <dd>
                呼吸できないブロックのリストを設定します。
            </dd>
            <dt>suffocate_time（デフォルト:-20）</dt>
            <dd>
                窒息ダメージ間の秒数を設定します（マイナスで指定する事に注意）。
            </dd>
            <dt>total_supply（デフォルト:15）</dt>
            <dd>
                息を止められる秒数を設定します。
            </dd>
        </dl>
    </dd>
    <dt>・minecraft:collision_box</dt>
    <dd>
        衝突判定の範囲をブロック単位で設定します。<br />
        ここで設定した値によって影の大きさも変化します。
        <dl>
            <dt>height（デフォルト:1.0）</dt>
            <dd>
                衝突判定の高さを設定します。
            </dd>
            <dt>width（デフォルト:1.0）</dt>
            <dd>
                衝突判定の幅を設定します。
            </dd>
        </dl>
    </dd>
    <dt>・minecraft:pushable</dt>
    <dd>
        エンティティを押し出す事ができるかどうかを設定します。
        <dl>
            <dt>is_pushable（デフォルト:true）</dt>
            <dd>
                trueの場合、他のエンティティによって押し出す事ができます。
            </dd>
            <dt>is_pushable_by_piston（デフォルト:true）</dt>
            <dd>
                trueの場合、ピストンによって押し出す事ができます。
            </dd>
        </dl>
    </dd>
    <dt>・minecraft:physics</dt>
    <dd>
        物理法則を設定します。<br />
        <code>minecraft:physics</code>ブロック自体が未定義の場合は物理法則が適用されません。
        <dl>
            <dt>has_collision（デフォルト:true）</dt>
            <dd>
                trueの場合、オブジェクトと衝突します。
            </dd>
            <dt>has_gravity（デフォルト:true）</dt>
            <dd>
                trueの場合、重力の影響を受けます。
            </dd>
            <dt>push_towards_closest_space（デフォルト:false）</dt>
            <dd>
                trueの場合、ブロックに埋まった時に最も近い空き領域に押し出されます。
            </dd>
        </dl>
    </dd>
</dl>

:::note info
一部例外はありますが、基本的に定義されていないデータブロック、および値は暗黙的にデフォルト値が適用されます。
:::


# おわりに

本環境では以下のページでご紹介させて頂いたコンテンツ内でダミーエンティティを使っています。

https://qiita.com/glasses_seven/items/d48d8716eb80daa2a518/

https://qiita.com/glasses_seven/items/53e07b2e71eee588203f/

https://qiita.com/glasses_seven/items/cd55c6bd721a9ced1f06/

https://qiita.com/glasses_seven/items/0529d05f2b833a9f9cae/

https://qiita.com/glasses_seven/items/556927227356043752a2/

https://qiita.com/glasses_seven/items/876eb47c3e38828428e4/