前回に続きまして、今回もアドオン制作についての記録を記事にしていこうと思います!
今回は状態と動きに応じた演出です。アニメーションの切り替えに挑戦します。Blockbenchで作成したモデルに対して「水中で泳ぐ」「陸で跳ねる(flop)」「敵対Mobから逃げる」「逃走時の移動速度に応じてアニメーション速度を変える」といった、状態や行動に応じたアニメーション制御とAI構築に触れていきたいと思います。
アニメーションコントローラーを使わずに “scripts”:{“animate”:……} を用いた切り替え方法、さらに math.cosを活用したアニメーションの動的調整を導入します。
- 水中と陸上でアニメーションを切り替える方法
- 移動速度に応じたアニメーション制御の実装(math.cosの導入)
- Mobが陸に出たとき水へ戻るAIの設定
Mobの状態に応じてアニメーションを切り替える
水中で「泳ぐ」、陸上で「跳ねる」を切り替える
まずはこちらのリソースパックのentityファイル。赤枠の部分が今回で追加・変更した部分です。
animationsとscriptsに新たにflop(跳ねる)というアニメーションについて追加しています。Blockbenchから作成したアニメーションはこちら。
今回もキーフレーム上で動作を作っています。基本的に使っているのはローテーションの機能。モブを軽く飛び跳ねさせる挙動ではポジションの機能で若干モブを上下させています。
flopのjsonファイルの内容です。
0.3333とか変に長い数字、ちょっと気持ち悪いですね。後でキリが良い様に修正します。
モブが水中では「泳ぐ」、陸上では「跳ねる」といったアニメーションを実行するために、今回リソースパックentity.jsonファイル内の“scripts”:{“animate”:}で切り替え処理を行いました。
(animation_controllerは今回は触れません。挑戦はしたのですが、どうしてかanimation_controllerを入れるとグラフィックが透明化してしまって、未だ原因が分からないのです。なので今回は使いません。)
“scripts”:{“animate”:}でシンプルに実装
この方法ではアニメーションコントローラーを使わず、queryの条件に応じて直接アニメーションを切り替えられるため、軽量で分かりやすい実装が可能です。以下のようにentityファイルに記述することで、状態に応じたアニメーションの自動切り替えが可能です。
“scripts”: {
”animate”: [
{
”swim”: “query.is_in_water”
},
{
”flop”: “!query.is_in_water && !query.is_levitating”
}
]
}
swim 泳ぐアニメーションが格納されています。
flop 跳ねるアニメーションが格納されています。
query.is_in_water 水中に居る
!query.is_in_water && !query.is_levitating 水中に居ない and 浮遊していない
という条件を設定しています。ここでは「水中に居る時はアニメーションswimを再生」、「水中ではなくて尚且つ浮遊もしていない時はアニメーションflopを再生」という事を記述しています。
ただし、これは制御するアニメーションや条件が今回の様に単純だからこその記述だと思います。もっと複雑な処理を行うのならanimation_contorollerで制御する方が良いのでしょうね…いつかちゃんと扱えるようになりたいですね(汗
移動速度に応じてアニメーションを調整する方法
math.cosとquery.modified_distance_movedの組み合わせ
モブが移動しているときのスピードに応じてアニメーション調整。今回はmath.cosとquery.modified_distance_movedを組み合わせたアニメーション制御をしました。
math.cosなどを使う時も、基本は先にBlockbenchのアニメ編集からキーフレームで動作を作ってしまいます。それから作成したアニメーションのjsonファイルを開いて該当の箇所を書き換えていきます。

bodyの部分の記述を例に解説します。
“rotation”: [0, “math.cos(query.modified_distance_moved * 30.0) * 5.0”, 0]
rotation 回転の設定
構造は”rotation”: [X回転, Y回転, Z回転] となっています。上記の記述で当て嵌めると、X軸回転は0,Y軸回転は「移動距離に合わせて最大±5度まで左右に振る」、Z軸回転は0、となります。
math,cos コサイン波(波のようにな周期運動)
頂点まで行って、反対側の頂点に戻る。振り子の動きを想像していただければイメージしやすいかもしれません。単純な左右に振れる動作や上下運動に使いやすいです。モブで当て嵌めるなら、歩行の際の手足を振る運動などです。今回でいえば、体を左右に振る動きです。-math.cosという様に頭にマイナスがついている時は、反対側から波が開始されます。
query.modified_distance_moved 移動距離に基づく累積値
動いているほど値が進む。つまり歩いたり泳いだり、距離を進めば波が進むという事になります。
30.0 波の周期スピードを決める倍率
この数値が大きいほど、波の進みが速くなります。
5.0 回転角度の振れ幅(Y軸の数字)
最大で±5度、Y軸回転します。
まとめると
モブが止まっている時は静止。モブが動くほどに左右にスイング。移動速度に応じて振れ方が調整される。
というアニメーションの制御ができます。
水中AIの設計
上記では陸に上がってしまった時のアニメーションを追加、移動距離に応じたアニメーションの制御処理をしました。次はモブのAIに関する記述を作っていきます。
行動AIや体力や移動速度など、モブの性質などについてはビヘイビアで設定します。
まずはこちら。今回追加・変更した部分です。赤枠で囲った部分。



陸上移動用のAIを追加する
水中が本来の生活圏のモブでも、誤って陸に出てしまった場合に備えて陸上でのAIを作ります。
やりたいことは「陸上に上がった時は自発的に水中に戻る」というAIです。
陸上で動けるようにする
水中モブと陸上モブでは使用しているAIが異なります。
陸上モブには適用されるけれども、水中モブには適用されないAIもあるので、まずは陸上モブとしてのAIも機能する様にします。
そのためにfamilyに”mob“を追加しました。
“minecraft:type_family”: {
”family”: [“baspis”,”fish”,”mob”]
}
次に陸上で移動可能となるAIを組み込みます。この辺の所はウーパールーパーを参照しています。
“minecraft:movement”: {
”value”: 0.1
},
“minecraft:movement.amphibious”: {
”max_turn”: 15.0
},
“minecraft:behavior.random_stroll”: {
”priority”: 3,
”speed_multiplier”: 0.5
”interval”: 100
}
minecraft:navigation.genericのcan_walkをfalseからtrueにします。
“minecraft:navigation.generic”: {
”can_walk”:true
}
move_to_waterで水場へ戻る行動を設定する
Mobが陸に出たら、自動で水に戻る行動を取るには以下のAIを追加します。
“minecraft:behavior.move_to_water”: {
”priority”: 6,
”search_range”: 16,
”search_height”: 5,
”search_count”: 1,
”goal_radius”: 0.1
}
このAIは周囲の水ブロックを探し、そこに向かって歩かせます。
これらのAI設定を行えば水中モブでも陸上モブと同様に陸上での行動が可能になり、そして自ら水に戻っていくという行動をとるようになります。
敵対Mobから逃げる行動を設定する方法
behavior.avoid_mob_typeを使った回避行動
特定の敵対モブから逃げさせたい場合は、以下のようにbehavior.avoid_mob_typeを使います。
“minecraft:behavior.avoid_mob_type”: {
”priority”: 1,
”entity_types”: [
{
”filters”: {
”any_of”: [
{
”test”: “is_family”,
”subject”: “other”,
”value”: “axolotl”
}
]
},
”max_dist”: 6,
”walk_speed_multiplier”: 1.0,
”sprint_speed_multiplier”: 1.5
}
]
}
敵対モブから逃げる際に移動スピードを変更しています。リソースパックでmath.cos(query.modified_distance_movedを使ってアニメーション制御した部分が反映される箇所となります。
回避対象はis_familyを使うことで柔軟に指定できます。独自のファミリー名を割り当てることでカスタムモブにも対応可能です。
今回、対象モブはaxolotl(ウーパールーパー)だけですが、他にも回避対象モブが居れば、any_of[]の中に追記して増やせます。
ここまでで、今回追加した「モブの状態に応じたアニメーション切り替え」「移動速度に応じたアニメーション制御」「水中モブの陸上動作」などは一区切りとします。
アニメーションが反映されないときのチェックポイント
モデルとanimation.jsonのパーツ名は一致しているか?
Blockbenchで作成したモデルパーツの名前が、animation.json内で正確に一致していないと動きません。
ビヘイビア側のAIに不足や記述ミス
ビヘイビア側で行動AIに不足や間違いがあると、モブは動きません。アニメーションの制御にquery.modified_distance_movedなどを使っていると、モブが移動しない事にはアニメーションが再生されないので、ビヘイビア側の記述のチェックも大事です。
アニメ条件式の論理エラーに注意
例えば “!query.is_in_water && query.is_moving” のような複雑な条件は、スペースや記述順の違いでうまく反映されないこともあります。
マイクラアドオンで「状態と動きに応じた演出」を実装するまとめ
今回はの状態に応じてアニメーションやAIを切り替えることに挑戦しました。
- scripts.animateでアニメを状態ごとに管理
- math.cosで速度に応じた動的アニメーション
- move_to_waterやamphibiousで水中モブの地上での行動を設定
次回はスポーンルールやルートテーブルなども作ってみたいです。現在のままだとスポーンエッグからしか生まれないので、自然スポーンする様に設定して、それから折角なので倒した時のドロップアイテムなどもオリジナルで作ってみたいですね。

