アドオン詳細解説 - エンティティ(リソース)
目次 (折りたたみ可)
エンティティのリソースの仕組み
エンティティはビヘイビアもリソースもどちらも複雑です。 リソースパックでは、テクスチャを貼り付けるだけでなく、 アニメーションやジオメトリ、その他細かい要素、任意でパーティクルとサウンドを紐づける必要があります。

「entity_client」がメインとなって、エンティティとそれらの紐づける要素すべての中継となります。
略語
この記事では以下のような略語を使います。
アニコン:アニメーションコントローラの略
レンコン:レンダーコントローラの略
entity_client
ファイルの場所
リソース
┣ manifest.json
┣ pack_icon.png
┗ entity
┗ 〇〇.entity.json
ファイル名は他のファイルとの区別のため「〇〇.entity.json」にするのを強くおすすめします。 別に「〇〇.json」でも動作はします。
基本構造
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "ex:my_entity",
"materials": {
// マテリアル
},
"textures": {
// テクスチャ
},
"geometry": {
// ジオメトリ
},
"spawn_egg": {
// スポーンエッグのテクスチャ
},
"scripts": {
"animate": [
// Animキー
]
},
"animations": {
// アニメーション, アニコン
},
"render_controllers": [
// レンコン
]
}
}
}
詳細な構造
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "ex:my_entity",
"min_engine_version": "1.18.0",
"materials": {
// マテリアル
},
"textures": {
// テクスチャ
},
"geometry": {
// ジオメトリ
},
"queryable_geometry": "Str",
"spawn_egg": {
// スポーンエッグのテクスチャ
},
"particle_effects": {
// パーティクル
},
"particle_emitters": {
// パーティクル・エミッター
},
"sound_effects": {
// サウンド
},
"scripts": {
"variables": {
// Molang変数に関する設定
},
"initialize": "Molng-n",
"pre_animation": "Molang-n",
"scale": "Molang",
"scaleX": "Molang",
"scaleY": "Molang",
"scaleZ": "Molang",
"parent_setup": "Molang",
"animate": [
// Animキー
],
"should_update_bones_and_effects_offscreen": "Molang",
"should_update_effects_offscreen": "Molang"
},
"animations": {
// アニメーション, アニコン
},
"render_controllers": [
// レンコン
],
"enable_attachables": "Bool",
"hide_armor": "Bool",
"item": "Str"
}
}
}
テクスチャ・ジオメトリ・マテリアルの紐づけ
後に説明する「複雑なエンティティ」ではない場合、以下のように紐づけが簡単になります。
"materials": {
"default": "(マテリアルID)"
},
"textures": {
"default": "(テクスチャのファイルパス)"
},
"geometry": {
"default": "(ジオメトリID)"
}
また、これも後に詳しい説明をしますが、レンコンの指定も簡単になります。
"render_controllers": [
"(レンコンID)"
]
複雑なエンティティとは、複数の状態をもったエンティティのことです。たとえば、村人は様々な職業という形で「状態」をもっています。 村人のように「状態」でテクスチャ、ジオメトリ、マテリアルが変わるエンティティを作る場合には紐づけが難しくなります。
2つの状態A、Bをもつエンティティにリソースを紐づける例で説明します。
まず、entity_clientでテクスチャなどを紐づける用意をします。
"materials": {
// "state1", "state2"の部分は自由
"state1": "(マテリアルID)",
"state2": "(マテリアルID)"
},
"textures": {
// すべて連動するわけではないので、
// 状態によって変わらなければそのまま"default"1つだけでOK
"default": "(テクスチャのファイルパス)"
}
// テクスチャ、ジオメトリ、マテリアルで書き方は変わらない
そして、レンコン側で状態に応じた条件分岐を作ってこれらのキー(上記の "state1", "state2", "default"の部分) を指定して、状態でテクスチャなどが切り替わるようにします。
レンコンの作りかた/編集のしかたはレンコンの章で説明します。
スポーンエッグのテクスチャ
色を二つ指定するか、アイテムのTerrainID(とインデックス)を指定してテクスチャを決めます。
色を二つ指定する場合は、 "base_color"に下地の色、 "overlay_color"に模様の色を16進カラーコードで指定します。
"spawn_egg": {
"base_color": "#ffffff",
"overlay_color": "#0000ff"
}
テクスチャを指定する場合は、 "texture"にTerrainIDを、必要なら "texture_index"の項目を追加してインデックスを整数で指定します。
"spawn_egg": {
"texture": "my_entity_spawn_egg"
}
アニメーションの紐づけ
先に大まかな説明をすると、アニメーションはentity_clientと直接紐づけて常時そのアニメーションを実行するか、 アニコンをはさんでentity_clientと紐づけて、条件に応じてアニメーションの実行するタイミングをコントロールするといった形になります。
まず、紐づけるアニメーションまたはアニコンをentity_clientの "animations" で列挙しておきます。この際、自由にアニメーションキー名を決めます。
"animations": {
"(Animキー)": "(AnimID/AniConID)",
"(Animキー)": "(AnimID/AniConID)",
"(Animキー)": "(AnimID/AniConID)"
// ...
}
これらのうち、常に実行する/処理するもののアニメーションキーを "scripts"の "animate"に列挙します。
"scripts": {
"animate": [
"(Animキー)",
"(Animキー)",
"(Animキー)"
// ...
]
}
アニコンを挟む場合は、そのアニコン内で "scripts"の "animate"のような場所があって、そこにアニメーションキーを書きます。
レンコンの紐づけ
"render_controllers"プロパティにレンコンのIDを列挙します。 高度なことをしない限り、指定するのは1つになるはずです。
"render_controllers": [
"(レンコンID)",
"(レンコンID)"
// ...
]
また、Molang式で条件を添えることができます。
この場合、レンコンはテクスチャやジオメトリなど、直接見た目に関わるものをコントロールしているという役割上、
条件を満たさないとエンティティが透明になります。
意図的でないならば、複数紐づけていずれか一つの条件が満たされるようにしましょう。
"render_controllers": [
{ "(レンコンID)": "(条件(Molang))" },
{ "(レンコンID)": "(条件(Molang))" }
// ...
]
パーティクルとサウンド
アニメーションと同じ要領でパーティクルとサウンドもアニコンを使うことによって、条件に応じてそれらを発生させることができます。 entity_clientではこのような準備をします。
"particle_effects": {
"(パーティクルキー)": "(パーティクルID)"
// ...
},
"sound_effects": {
"(サウンドキー)": "(サウンドID)"
// ...
},
パーティクルキー、サウンドキーはアニメーションキーと同じで、名前を自由に決めます。
variable変数の定義
"scripts"内の "pre_animation"でMolangのvariable変数を定義することができます。 ここで定義した変数はアニメーションやアニコンなど様々な場所で使うことができます。
"scripts": {
"pre_animation": [
"v.foo = math.sin(q.life_time);"
]
},
また、 "initialize"プロパティでそれら変数の初期値を設定できます。
"initialize": [
"v.foo = 0.0;"
]
上級 さらに、 "variables"プロパティでvariable変数をパブリックに設定して、矢印演算子を用いて読み取れるようにします。
"variables": {
"variable.foo": "public"
}
プロパティ名は設定したい変数、値は "public"しかありません。
Attachableに関する設定
"enable_attachables"の項目を
trueに設定すると、Attachableを有効にできます。
防具を身に着けるモブなのに防具が表示されないという場合はこの項目の設定を忘れている可能性が高いです。
アニコン
ファイルの場所
リソース
┣ manifest.json
┣ pack_icon.png
┗ animation_controllers
┗ 〇〇.animation_controllers.json
ファイル名は他のファイルとの区別のため「〇〇.animation_controllers.json」(バニラ準拠)にするのをおすすめします。 別に「〇〇.json」でも動作はします。
基本構造
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.my_entity.main": {
"initial_state": "(state名)",
"states": {
"(state名)": {
"animations":[
"(Animキー)",
// または
{ "(Animキー)": "(条件(Molang式))" }
// ...
],
"transitions": [
{ "(state名)": "(条件(Molang式))" }
// ...
]
}
}
}
}
}
詳細な構造
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.my_entity.main": {
"initial_state": "(state名)",
"states": {
"(state名)": {
"animations":[
"(Animキー)",
// または
{ "(Animキー)": "(条件(Molang))" }
// ...
],
"transitions": [
{ "(state名)": "(条件(Molang))" }
// ...
],
"particle_effects": [
{
"effect": "(パーティクルキー)",
"locator": "(Str)",
"pre_effect_script": "(Molang)",
"bind_to_actor": "(Bool)"
}
// ...
],
"sound_effects": [
{ "effect": "(サウンドキー)" }
// ...
]
}
}
}
}
}
アニコンのしくみ
アニコンは複数のstateの移動と、そのための条件(transition)をもとにアニメーションをコントロールします。
たとえば「stand」「walk」という2つのstateがあって、初めは「stand」だとします。 「stand」のtransitionに「歩いているか」という条件を設定して、その条件を満たしたら「walk」に移るようにして、 「walk」では歩くアニメーションが紐づいているアニメーションキーを指定すれば、歩き始めたときに歩くアニメーションがスタートするようになります。
「walk」にもtransitionに「立ち止まっているか(=歩いていないか))」の条件を設定して、その条件を満たしたら「stand」に移るようにするのを忘れてはいけません。 でないと立ち止まってもstateが「walk」のまま「stand」に移らず、歩くアニメーションが立ち止まっても再生されたままになってしまいます。
具体的な書き方
まず基本構造のマーカー部分がIDになります。「controller.animation.〇〇」という形でないといけません。 上記の例では〇〇の部分が「(エンティティ名).(どんなアニコンか)」のようにさらにドット( . )で区切っています。
IDをプロパティ名とするオブジェクトの中にはまず、初めのstateをどれにするか指定する "initial_state"と、stateをまとめる "states"オブジェクトを書きます。
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.my_entity.main": {
"initial_state": "(state名)",
"states": {
}
}
}
}
"states"オブジェクトの中にstateを列挙していきます。 stateは名前を自由に決め、その名前をプロパティ名とするオブジェクトになります。
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.my_entity.main": {
"initial_state": "(state名)",
"states": {
"(state名)": {
}
}
}
}
}
各stateの中身には "animations"、 "transition"をプロパティ名とする配列を置きます。
"animations"にはこのstateに入ったときに再生されるアニメーションキーを列挙し、 "transition"には次はどのstateに移動するかを決める条件を以下のように列挙します。
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.my_entity.main": {
"initial_state": "(state名)",
"states": {
"(state名)": {
"animate": [
"(Animキー)",
"(Animキー)"
// ...
],
"transitions": [
{ "(state名)": "(条件(Molang))" },
{ "(state名)": "(条件(Molang))" }
// ...
]
}
}
}
}
}
パーティクルとサウンド
"animations"、 "transition"と並べて、そのstateに入ったときに発生させるパーティクルとサウンドを以下のように指定します。
"particle_effects": [
{
"effect": "(パーティクルキー)",
"pre_effect_script": "(Molang)"
}
// ...
],
"sound_effects": [
{ "effect": "(サウンドキー)" }
// ...
]
"pre_effect_script"ではそのパーティクル内で使うためのvariable変数を定義できます。
レンコン
ファイルの場所
リソース
┣ manifest.json
┣ pack_icon.png
┗ render_controllers
┗ 〇〇.render_controllers.json
ファイル名は他のファイルとの区別のため「〇〇.render_controllers.json」(バニラ準拠)にするのをおすすめします。 別に「〇〇.json」でも動作はします。
基本構造
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.my_entity": {
"arrays": {
"geometries": {
"Array.XXX": [ "Geometry.XXX", "Geometry.XXX" /* ... */ ]
},
"materials": {
"Array.XXX": [ "Material.XXX", "Material.XXX" /* ... */ ]
},
"textures": {
"Array.XXX": [ "Texture.XXX", "Texture.XXX" /* ... */ ]
}
},
"geometry": "Geometry.XXX",
"materials": [
{ "(ボーン名)": "Material.XXX" }
// ...
],
"textures": [ "Texture.XXX", "Texture.XXX" /* ... */ ]
}
}
}
詳細な構造
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.Str": {
"rebuild_animation_matrices": "Bool",
"arrays": {
"geometries": {
"Array.XXX": [ "Geometry.XXX", "Geometry.XXX" /* ... */ ]
},
"materials": {
"Array.XXX": [ "Material.XXX", "Material.XXX" /* ... */ ]
},
"textures": {
"Array.XXX": [ "Texture.XXX", "Texture.XXX" /* ... */ ]
}
},
"geometry": "Geometry.XXX",
"part_visibility": [
{ "(ボーン名)": "Molang" }
// ...
],
"materials": [
{ "(ボーン名)": "Material.XXX" }
// ...
],
"textures": [ "Texture.XXX", "Texture.XXX" /* ... */ ],
"color": {
"r": "(Molang)",
"g": "(Molang)",
"b": "(Molang)",
"a": "(Molang)"
},
"overlay_color": {
"r": "(Molang)",
"g": "(Molang)",
"b": "(Molang)",
"a": "(Molang)"
},
"on_fire_color": {
"r": "(Molang)",
"g": "(Molang)",
"b": "(Molang)",
"a": "(Molang)"
},
"is_hurt_color": {
"r": "(Molang)",
"g": "(Molang)",
"b": "(Molang)",
"a": "(Molang)"
},
"uv_anim": {
"offset": [ "(Molang)", "(Molang)" ],
"scale": [ "(Molang)", "(Molang)" ]
},
"light_color_multiplier": "(Molang)",
"ignore_lighting": "(Bool)",
"filter_lighting": "(Bool)"
}
}
}
具体的な説明
"arrays"でアレイを定義します。 複数のジオメトリ、マテリアル、テクスチャを紐づける場合でなければ定義する必要はありません。
ジオメトリのアレイは "geometries"で、マテリアルは "materials"で、テクスチャは "textures"で定義します。
たとえば、entity_clientで以下のように紐づけていたとします。
"textures": {
"state1": "(テクスチャのファイルパス1)",
"state2": "(テクスチャのファイルパス2)"
}
これでアレイを定義すると、
"textures": {
"Array.texture": [ "Texture.state1", "Texture.state2" ]
}
左の "Array.XX"のXXの部分は自由に決められます。 並べる順番も自由です。
ジオメトリやマテリアルも Texureの部分を Geometryや Materialに変えるだけであとは同様です。
次に、ジオメトリやテクスチャなど、どれを適用するかを決める部分です。 直接指定する場合は直接指定するだけですが、状態などによって条件分岐する場合は、アレイから値をMolangで選ぶ必要があります。
アレイの値は1番目から Array.XX[0]、 Array.XX[1]、 Array.XX[2]......のように指定します。 [ ]の中をMolangで記述することによって条件分岐を実現します。
先ほどのテクスチャの例で minecraft:variantコンポーネントの値によってテクスチャが変わるとすると、
"textures": [
"Array.texture[q.variant]"
]
のように指定します。このMolang式ができるだけ簡単になるようにアレイの値の順番を決めましょう。
以下、簡単に例を示します。entity_clientは以下のようになっているとします。
"materials": {
"material1": "(マテリアルID1)",
"material2": "(マテリアルID2)"
},
"textures": {
"texture1": "(テクスチャのファイルパス1)",
"texture2": "(テクスチャのファイルパス2)"
},
"geometry": {
"geo1": "(ジオメトリID1)",
"geo2": "(ジオメトリID2)"
}
直接指定
"geometry": "Geometry.geo1",
"materials": [
{ "*": "Material.material1" }
],
"textures": [ "Texture.texture1" ]
ジオメトリを切り替わるようにする
"arrays": {
"geometries": {
"Array.geos": [ "Geometry.geo1", "Geometry.geo2" ]
}
},
"geometry": "Array.geos[(Molang式)]"
ボーンごとに異なるマテリアルを適用する
"materials": [
{ "(ボーン名1)": "Material.material1" },
{ "(ボーン名2)": "Material.material2" }
]
ボーン名を指定するときに、まとめて指定する書き方があります。たとえば、 "bone_head"と "bone_body"は後半だけが違うので、 "bone_*"というようにまとめて指定できます。
複数のテクスチャを適用する
"textures": [
"Texture.texture1",
"Texture.texture2"
]
同時にテクスチャを適用するので、当然重なります。 実用するシチュエーションとして、たとえば「顔が変わるエンティティ」を実装する場合は、 顔とそれ以外のテクスチャは別々にして、顔のテクスチャの指定にだけアレイを使うといったような感じです。
ボーンの表示/非表示をコントロールする
"part_visibility"でボーン名とMolang式を指定します。
"part_visibility": [
{ "(ボーン名)": "Molang" }
// ...
]
テクスチャに関する様々な色を変更する
"overlay_color"でオーバーレイする色、 "on_fire_color"で燃えているときにオーバーレイする色、 "is_hurt_color"でダメージを受けた瞬間にオーバーレイする色を決められます。
"overlay_color": {
"r": "(Molang)",
"g": "(Molang)",
"b": "(Molang)",
"a": "(Molang)"
},
"on_fire_color": {
"r": "(Molang)",
"g": "(Molang)",
"b": "(Molang)",
"a": "(Molang)"
},
"is_hurt_color": {
"r": "(Molang)",
"g": "(Molang)",
"b": "(Molang)",
"a": "(Molang)"
}
テクスチャをアニメーションさせる
"uv_anim"で値を設定することで、テクスチャをアニメーションさせることができます。 方式として、"テクスチャのどこを切り取るか"の長方形を動かしてアニメーションする方式になるので、 ブロックのようにパラパラ漫画式でアニメーションさせたい場合は工夫が必要です。
"uv_anim": {
"offset": [ "(Molang)", "(Molang)" ],
"scale": [ "(Molang)", "(Molang)" ]
}
"offset"でuvを指定し、 "scale"はそのuvのスケールを指定します。
特殊発光
"ignore_lighting"を trueにすることで、周囲の明暗を無視する、 つまり暗さを無視して光っているようになります。
このプロパティが書いてあるレンコンで紐づけたテクスチャに適用されるので、 目だけ光らせたい場合は、このレンコンでは目だけのテクスチャを指定する必要があります。
Attachable
Attachableとは、防具や手に持っているアイテムなど、エンティティ本体とは別となるモデルではあるが、アニメーションが本体に追従するような部品のことです。 そして、ホットバーや左手スロット、または防具スロットのインベントリのアイテムと連動する必要があります。
一言で正しくするのは難しいです。基本的に「防具」と「手に持っているアイテム」のモデルであると思っても大丈夫です。
ファイルの場所
リソース
┣ manifest.json
┣ pack_icon.png
┗ attachables
┗ 〇〇.json
具体的な説明
JSONの書き方はほとんどentity_clientと同じです。 ただし、IDは対応させるアイテムのIDと一致させてください。