scenario-godot-animation について
アニメーターやテクニカルアニメーター向けのGodot 4.7.2アニメーションスキルです。コードによる構築、動作の計測、ポーズシートを組み合わせ、インポートやアニメーションツリー、レイヤー、IKを検証します。
主な機能
- 01インポート済みクリップとリターゲットリグの監査
- 02ロコモーションの足速度測定
- 03コードによるアニメーションツリー構築と駆動
- 04フィルター付きレイヤーとIKの設定
- 05コンタクトシートによる指定時刻のポーズ確認
- 06カットシーンとカメラ挙動の検証
活用シーン
- 01接地した足の動きに歩行速度を合わせる
- 02ヒューマノイド骨格へのクリップのリターゲット
- 03上半身アクションと足の配置の追加
- 04カットシーンの時間軸とカメラ位置の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-godot-animationインストール後、Claude Code で/scenario-godot-animationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/gd_anim.pyscripts/agentkit/animation/anim_audit.gdanim_capture.gdanim_cutscene.gdanim_ik.gdanim_import.gdanim_motion.gdanim_rig.gdanim_setup.gdanim_tree.gdanim_tween.gdcutscene_director.gdfoot_placer.gdlocomotion_state.gdpose_persist.gd詳細
Godot アニメーション(アニメーターおよびテクニカルアニメーター)
対象:Godot 4.7.2.stable、macOS、Jolt Physics を使用する Forward+。references/procedures.md のすべての手順は、2026-10-02 に 4.7.2 上でプロシージャルに構築したヒューマノイドを使って実際に実行済みのため、ダウンロードは不要です。
基本方針
- 動きを目測せず、計測してください。 歩行には正しい接地速度があります。接地している足が滑らなくなる速度です。クリップから計測し(
anim_motion.gd:foot_speed)、その値を BlendSpace の点とコントローラーに使用します。リターゲットしたボディでは、速度はSkeleton3D.motion_scaleに応じて変化します(1.15 倍のボディは、1.2 m/s のクリップで 1.38 m/s で歩行しました)。 - コードが判断し、アニメーションレイヤーが表現します。 ゲームプレイ側が速度と状態を管理し、AnimationTree は advance 式またはパラメーターを通じてそれらを読み取るだけです。ツリーを取り外してもコントローラーは動作しなければなりません(Fair Fight、jzuvd0Lstuw 00:05:46)。
- 正確な時刻を確認してください。 固定時刻にシークまたはステップし、コンタクトシートを開きます(
gd_anim.pose_sheet)。リアルタイムのキャプチャでは、ランダムなフレームが取得されます。 - レイヤーごとに、対象となるボーンを明示してください。 部分クリップは部分状態のままではありません。glTF のエクスポートでは、すべてのクリップにアニメーション対象の全ジョイントが追加されます。また、デフォルトの決定的ブレンディングでは、フィルターのない OneShot を使用すると、リストにないすべてのボーンが RESET に戻ります。レイヤーを定義するのは、トラックの欠落ではなくフィルターです。
- 動きごとに適切な駆動方式を選んでください。 インプレースクリップを使った速度駆動のロコモーションは操作への応答性を保ちます。ルートモーションは、足を接地させたままにする必要がある単発の動き(回避、登攀、跳び越え)に適しています[追加]。通常のロコモーションセットにはツリーが適しています。非常に大規模な動作セットや多数のプロシージャルレイヤーでは、コードと SkeletonModifier3D レイヤーが適しています(専門家の間では意見が分かれています。Fair Fight はツリーに反対、xpoPfUKI9tw、RiftOfNostaria、Bitlytic、Chris は賛成)。開始値が不明な実行時値には Tween を、複数プロパティにわたる作成済みのカーブには AnimationPlayer を使用します(Queble、KUyQzjpRsU8 00:01:48)。
- ここでは、無言の失敗がよく起こります。 存在しないボーンを指定する BoneMap、advance mode が Enabled の状態での式による遷移、RESET キーの欠落は、いずれも 4.7.2 でエラーを出しませんでした。インポートのたび、ツリーを変更するたびに監査してください。ここに記載された兄弟スキルが利用可能なスキルに見当たらない場合は、ユーザーにインストールを依頼してください(
npx skills add scenario-labs/skills --skill <name>)。無人で作業を進める場合は、ツールのスキーマに基づいて続行し、不足していることを明記してください。
最初に確認すること
一度に質問した後、次の手順を実行します。
- モーションのソース:Mixamo またはその他の FBX、Blender glTF、モーションキャプチャ、Godot での手付け、プロシージャルのみ。
- リグ:ヒューマノイド(SkeletonProfileHumanoid が適合)かカスタムか、レストポーズが T ポーズか A ポーズか、実際の Root ボーンがあるかどうか。
- ロコモーションモデル:速度駆動(インプレースクリップ)かルートモーションか。設計で速度が固定されている場合は、目標速度。
- 必要なレイヤー:上半身のアクション、エイムまたはルックアット、不整地での足の IK、ヒットリアクション。
- クリップを共有するキャラクターと、その身長の範囲。
- カットシーン:長さ、カメラの数、ゲームプレイを停止する必要があるか、使用する会話システム。
- 物理演算のティック、レンダラー、対象ハードウェア(IK とモディファイアのコスト確認用)。
ゲート付きワークフロー
-
キットとプロジェクト。
gd_anim.install_animkit(P)を実行します。project.godotで、3D に Jolt が設定され、レンダラーがブリーフの指定どおりであることを確認します。ゲート:キットのジョブがokを返します。 -
インポート。 ループヒントを付けてサイクルに名前を付けます(
Walk-loop)。一度インポートしたら、.importファイルでオプションを設定し(gd_anim.set_import_options、P3)、--importを実行します。animation/import_rest_as_RESETを有効にします。ゲート:gd_anim.auditにフラグがなく、すべてのサイクルがループし、RESET が存在します。 -
リターゲット。 インポートしたボーン名から BoneMap を作成します(
anim_import.gd:make_bonemap、P4)。インポート時に:は_に置き換わります。ゲート:スケルトンが%GeneralSkeletonであり、ボーン名が変更され、サンプリングしたポーズがソースから 2 mm 以内です。 -
共有。 クリップを Animation Library としてインポートし、各ボディに固有の BoneMap を割り当て、
anim_setup.gd:share_library(P5)でアタッチします。ゲート:未解決トラックが 0 件で、トラックレイアウトが同一です。 -
速度。 サイクルごと、ボディごとに
foot_speedを設定します(P9)。ゲート:コントローラーと BlendSpace の速度が 2 パーセント以内です。 -
ツリー。 コードで構築します(
anim_tree.gd、P6):BlendTree ルート、その内側に StateMachine、同期付きの BlendSpace1D、フィルター付きの OneShot、TimeScale。ゲート:スクリプト入力でdriveを実行すると、期待される状態リストと時間が得られ、ツリー監査に問題がありません。driveテストに合格した遷移ヘルパー:static func transition(expr: String, at_end: bool, xfade: float) -> AnimationNodeStateMachineTransition: var t := AnimationNodeStateMachineTransition.new() t.xfade_time = xfade t.advance_mode = AnimationNodeStateMachineTransition.ADVANCE_MODE_AUTO # default Enabled never auto-fires if at_end: t.switch_mode = AnimationNodeStateMachineTransition.SWITCH_MODE_AT_END if expr != "": t.advance_expression = expr # read on tree.advance_expression_base_node return t # sm.add_transition(&"Ground", &"Fall", transition("not on_floor and not jump_pressed", false, 0.2))ゲームプレイからは、
tree.set("parameters/sm/Ground/blend_position", speed)と状態ノードのプロパティで操作します。アクションはtree.set("parameters/act/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE)で発火させます。 -
レイヤーと IK。 OneShot フィルター(P7)、FootPlacer と TwoBoneIK3D(P10)。ゲート:
skeleton_updatedで読み取ったとき、ステップ、穴、15 度の斜面で、足がターゲットから 2 cm 以内にあります。モディファイアは子の順に実行されるため、プレーサー(ターゲットと腰)はソルバーより先に配置します:var ik := TwoBoneIK3D.new() skeleton.add_child(ik) # after FootPlacer ik.setting_count = 2 for i in 2: var side: String = ["Left", "Right"][i] # := cannot infer from an array index ik.set_root_bone_name(i, side + "UpperLeg") ik.set_middle_bone_name(i, side + "LowerLeg") ik.set_end_bone_name(i, side + "Foot") ik.set_target_node(i, ik.get_path_to(targets[i])) ik.set_pole_node(i, ik.get_path_to(knee_poles[i])) # 0.6 m in front of the knee ik.set_pole_direction(i, SkeletonModifier3D.SECONDARY_DIRECTION_PLUS_Z) skeleton.skeleton_updated.connect(_check_feet) # final pose, after every modifier and influence走行中は
influenceを下げ、空中では 0 に設定して、作成済みのモーションが反映されるようにします(Lukky、MbaPDWfbNLo 00:09:30)。 -
カメラとカットシーン。 球形の形状を持つ SpringArm3D(P12)、1 つの AnimationPlayer タイムライン(P13)。ゲート:呼び出し順と時間、チェックポイントでのカメラ位置、
animation_finished、セクション再生。 -
確認。 ポーズシート:正面と側面の T ポーズ、8 つの歩行フェーズ、各状態、IK の地形、カットシーンのタイムライン(P14)。ゲート:すべてのシートを開いて説明します。
エキスパート向けチェックリスト(計画に明記してください)
- モディファイアの出力は毎フレーム巻き戻されます(Fair Fight XFZQNsFejwk 00:02:04。P10 はアニメーションされたポーズを1フレーム後に読み取ります)。ポストエフェクトには適していますが、モディファイアでポーズを制御する場合は、
pose_persist.gdをロール RESTORE で最初に、SNAPSHOT で最後に配置します。そうすると、増分5度のモディファイアが、5度のままではなく12フレームで60度に達しました(P16)。RESTORE はアニメーションを上書きするため、再生中のクリップに重ねて使わないでください。 - IK が解決するのは位置のみです。 TwoBoneIK3D では、15度の斜面に対して足の角度が12.1度ずれていました。その後に
CopyTransformModifier3D(回転のみ、参照タイプは Node、地面の傾きに合わせたアラインノード)を追加すると、足を動かさずにずれが0.0度になりました(P16、Lukky MbaPDWfbNLo 00:07:49)。 - 決定論的 IK は毎フレーム最初から解決します。1回の反復で動かすチェーンでは、角度制限を最大の180度にする必要があります(Lukky 00:04:46)。IterateIK3D では
deterministicのデフォルト値は false です。脚を踏み出す動きでは有効にしてください(MeroDev 17xi4vDqQJk 00:02:28)。 - ベジェトラックとプロパティトラックはブレンドできません(ドキュメント)。ツリーがブレンドするのは、値、位置、回転、スケールの各トラックです。
- Call Method トラックはエディターのプレビューでは実行されません(ドキュメント)。実行してテストしてください(P13)。
- キャプチャ更新モードは現在の値から最初のキーまでブレンドします。プロパティの値が5で、0.5秒時点のキーが10の場合、
play_with_captureでは0.25秒時点の値は7.5になります(P16)。 - スクリプトで多数のトラックをサンプリングする場合は、
find_trackをパスとインデックスのマップにキャッシュしてください。Fair Fight は大規模なリグで1.5~3倍の高速化を測定しました(XFZQNsFejwk 00:04:03~00:06:45)。GDScript の22トラックのテスト用リグでは1.2倍でした(P16)。クリップ間で同じトラック構成にする必要があるため、animation/remove_immutable_tracksを無効にしてください。 - ワンショットアニメーションは
animation_finishedとフラグで制御してください。そうしないと、次のフレームの移動処理によってヒットクリップが置き換えられます(DevWorm GMyw3eHDw7s 00:22:58)。測定では、「hurt」が0.4秒間維持された後、歩行が再開しました(P16)。 - Blender のソースデータ。 エクスポート前に、Rigify の Limb Segments を1にし、Game Friendly の単一ルートを設定してください(CoderNunk 0wMONEpEXpQ 00:00:19、00:01:23)。
nodes/apply_root_scale(デフォルトは true)はインポート時のスケールをメッシュとクリップに焼き込み、ルートは1のままにします(ドキュメント)。 - BlendSpace2D は4方向スプライトに使用します。ポイントはプラスまたはマイナス1に配置し、軸の範囲はプラスまたはマイナス1.1にして、斜め入力が左右にスナップするようにします。2Dでは上方向が負の Y です(Chris WrMORzl3g1U 00:09:20、00:13:09)。
数値
| 項目 | 値 | 出典 |
|---|---|---|
| 人間の歩行・走行時の地上速度 | 歩行は約1.2~1.5 m/s、ジョギングは3~4 m/s[追加] | クリップを測定(P9) |
| スライドなしの速度測定値 | 1.2および3.5で作成したクリップで、歩行は1.200、走行は3.504 m/s | P9 |
| 足のスライド許容値 | 接地した足は0.1 m/s未満、速度差は2%以内[追加] | ベースラインG5、P9 |
| ロコモーションのクロスフェード | 0.1~0.2 s、着地は0.05 s、最後に0.15 sでLandからGroundへ | P6 |
| インポートFPS | 30(animation/fps のデフォルト) | インポーター |
Normalize Position Tracks後の motion_scale | ソースの腰の高さ(テストリグは0.97 m) | P4 |
| IKの足の誤差 | 2 cm未満が必須、測定値は0.1 mm未満 | P10 |
| FootPlacerのレイ | アニメーション上の足の0.5 m上から1.0 m下まで。腰の下降クランプは0.35 m | P10 |
| スプリングアーム | 球の半径は0.2。壁の0.2 m手前に、0.01 mのマージンを加えて停止 | P12 |
| IterateIK3Dのデフォルト | max_iterations 4、min_distance 0.001、angular_delta_limit 2 deg、deterministic false | クラスリファレンス |
| Tweenの時間差 | アイテムごとに0.05 s、Tweenごとに0.2 s | P11、aagPe4dvM2M 00:04:04 |
| モディファイアのコスト | Fair Fightでは、インクリメンタルなグローバルトランスフォームにより2 msのオーバーレイを半減 | XFZQNsFejwk 00:14:07 |
品質ゲート
references/critique.mdを使って評価してください。実施した各チェックについて「Godot 4.7.2で<日付>に実行:合格、主要な数値」の形式で記録し、未実施の項目は理由を添えて「未実施」と記載してください。
ブロッキング項目:すべてのトラックが解決されること、サイクルがループし、RESETがアニメーション対象のすべてのパスを網羅すること、速度が測定済みのスライドなしの速度と一致すること、ツリーがスクリプトによる駆動に合格すること、ポーズシートが開かれていること。その他:.importの編集で、4.7.2に存在しないoverwrite_axisなどのキーを使わないこと、新しいコードでSkeletonIK3Dを使わないこと、IKの結果を_processからではなく、skeleton_updatedまたはmodification_processedで読み取ること。
よくある間違い
-
mixamorig:名を使った BoneMap。 Godot はmixamorig_Hipsをインポートします。マップは何も一致せず、スケルトンは GeneralSkeleton にリネームされたまま、すべてのライブラリトラックの解決に失敗し、何も出力されません。インポート後の名前を使ってマップを作成してください。監査では、Hips のない GeneralSkeleton にフラグが立ちます。 -
式による遷移を Enabled のままにする。 遷移は一度も実行されません。式または条件によって駆動されるすべての遷移で、
ADVANCE_MODE_AUTO(2)を設定してください。 -
1 フレーム内で 2 つの自動遷移が true になる。
on_floorをクリアするジャンプによって Ground から Fall に遷移し、JumpUp がスキップされました。式にガードを追加する(not on_floor and not jump_pressed)か、ジャンプ遷移の優先度を 0 にしてください。 -
部分的なクリップでフィルターなしの OneShot または Add を使う。 決定論的な動作(AnimationTree のデフォルト)では、リストにないボーンが RESET に戻り、キャラクターは T ポーズになります。非決定論的な動作では、そのまま固まります。ノードにフィルターを設定してください。
-
RESET がない。 インポートしたファイルにはデフォルトで RESET がありません。そのためブレンドや保存したシーンは、レストポーズまたはゼロから始まります。
animation/import_rest_as_RESETを使うか、上流工程で RESET を作成してください(Blargis、ghYilg9cq-I 00:02:39)。 -
_processで IK の結果を読み取る。 アニメーション適用後のポーズが得られます。最終結果(影響度の適用後)はSkeleton3D.skeleton_updatedで、またはモディファイアのmodification_processed(影響度の適用前、100 パーセント)で読み取ってください。 -
Hips にルートモーションを設定する。 揺れてしまうため、実際の Root を挿入してください(FinePointCGI、fq0hR2tIsRk 00:04:35)。速度は
basis * get_root_motion_position() / deltaです。 -
リターゲットしたボディで速度の定数を使う。 背の高いボディは
motion_scaleによってストライドが長くなります。ボディごとに測定し直してください。 -
停止処理のガードがない Tween。 1 つのプロパティに対して 2 つの Tween があると、どちらも毎フレーム書き込みます(Queble、KUyQzjpRsU8 00:02:54)。参照を保持し、
kill()を呼び出してください。 -
ヘッドレス実行またはスキップされたカットシーンでメソッドトラックを使う。 デフォルトの Deferred 呼び出しはフレームを待ちます。ループが一度も yield しないと、呼び出しは最後にすべて実行されます。Immediate を使うか、フレームを yield してください。
-
実行時にツリーノードを編集する。 シーンのすべてのインスタンスで共有されるため、キャラクターごとの値は
parameters/...に設定してください。 -
レイのみのスプリングアーム。 カメラが壁面まで移動してしまうため、アームに球形シェイプを設定してください。
-
注視対象を指定せずにカメラをキー設定する。 回転キーがずれていくカットシーンカメラによって、最後の 5 秒間ヒーローが映らなくなりました。最初と最後のキーだけでなく、タイムラインシートでフレーミングを確認してください。
-
独自のクリップを持つボディにライブラリを読み込む。 2 体目のキャラクターでは Import をスキップし、共有ライブラリだけを再生するようにしてください(Quilled、nb6uSeEZFCI 00:04:36)。
引き継ぎ先
- scenario-godot-expert: プロトコルの実行、
gd_run、キャプチャおよびレビュー用ツール。まずこれを読んでください。 - scenario-godot-gameplay: CharacterBody3D コントローラーとツリーが読み取る状態、メソッドトラックによるヒットボックス。
- scenario-godot-3d-world: FootPlacer とスプリングアームの衝突レイヤー、IK テスト用ジオメトリ。
- scenario-godot-pipeline-automation: バッチインポートと大規模な
.import編集、CI 実行。 - scenario-godot-ui、scenario-godot-vfx、scenario-godot-audio: Tween の範囲を超えるメニューの動き、クリップやカットシーンにキー設定されたエフェクトとサウンド。
- scenario-godot-performance-export: 対象ハードウェアでのモディファイアとツリーのコスト。
- blender- スキル: ソース側の Root ボーン、Rigify Game Friendly エクスポート、NLA のプッシュダウン、ループのヒント。
Godot 4.7 に関する注記
- SkeletonModifier3D 上の IK ファミリーは 4.6 から利用できます:TwoBoneIK3D、FABRIK3D、CCDIK3D、JacobianIK3D、
SplineIK3D。設定はインデックスごとに行います(
set_root_bone_name(i, ...)、set_target_node(i, path)、set_pole_node、set_pole_direction)。SkeletonIK3D は非推奨です。 - カスタムモディファイアでは
_process_modification_with_delta(delta)をオーバーライドします。_process_modification()は 非推奨です。influenceは自分で適用しないでください。 retarget/rest_fixer/retarget_method(0 None、1 Overwrite Axis がデフォルト、2 Use Retarget Modifier)はoverwrite_axisキーを置き換えます。実行時のリターゲティング用に RetargetModifier3D が存在します(ここでは実行しません)。tween_await(signal).set_timeout(s)は 4.7 で追加されました。tween_subtweenは 4.4 から利用できます。- アニメーションマーカーと
play_section_with_markers(4.3 以降)。Animation.lengthは 4.7 で double です。 アニメーション名は StringName です。 - AnimationMixer は AnimationPlayer と AnimationTree の基底クラスです:
root_motion_track、deterministic(プレイヤーでは false、ツリーでは true)、callback_mode_process、callback_mode_method。 - 4.7.2(P6)で確認:
priority(値が小さい方が優先)は、travel()の経路だけでなく、 同じフレームで true になる自動トランジション間の選択も決定します。最初のadvance()より前に呼び出したtravel()は エラーなしでその状態からステートマシンを開始します。トランジションのデフォルトのadvance_modeは Enabled(travel のみ)です。 - 確認済み(P10):
modification_processedはinfluence適用前のモディファイアの結果を通知します。skeleton_updatedはブレンド後の最終ポーズを通知します。どちらの外でも、ボーンのポーズはアニメーション適用後の値として読み取られます。 - 確認済み(P3):手動編集した
.importは通常の--importで適用されます。ループヒントの接尾辞はクリップ名から削除され、loopの接頭辞は保持されます。クリップ名の.は_に変換されます。 - Skeleton3D はボーン名に
:と/を使用できません。このエラー文字列は 4.7.2 で不正な形式になります (tests/OPEN_ISSUES.mdに記録済み)。
参考資料
references/procedures.md(P1 から P16、実行結果は記載されていますが、まだ実行していません)、expert-notes.md(出典付きの主張)、critique.md(評価基準、G5 ベースラインで採点済み)、gui-paths.md(エディターでのクリック手順)、sources.md。scripts/gd_anim.py:Python ヘルパー(インストール、実行、リグ、ポーズシート、監査、 GLB 編集、.import編集、ボーンのサンプリング)。scripts/agentkit/animation/:anim_rig、anim_audit、anim_capture、anim_import、anim_setup、anim_tree、anim_motion、anim_ik、anim_tween、anim_cutscene、およびfoot_placer.gd、locomotion_state.gd、cutscene_director.gd、pose_persist.gd。- テスト:
tests/code/godot-animation/test_anim_live.py(A1 から A9、W)とtest_anim_offline.py。