アニメーション状態機械とブレンド
キャラの動きが硬い・遷移がガクつく、を根治したい人へ。状態機械・ブレンドツリー・クロスフェード・ルートモーションの内部動作を押さえれば、滑らかで応答性の高い制御を設計できます。
- アニメーション状態機械(ステートマシン)は各状態に1つのモーション(またはブレンドツリー)を割り当て、条件付き遷移をエッジで表す。遷移はクロスフェード(重み付き線形補間)で滑らかに繋ぎ、フェード中は複数状態を同時評価してブレンドする。
- ブレンドツリーは1D/2Dのパラメータ(速度・方向など)で複数クリップを連続補間し、離散状態を増やさず無段階の動きを作る。重みは正規化して合計1にし、位相同期でフットスライドを防ぐ。
- レイヤリングは上半身と下半身などを別々に重ね(加算 or 上書き+マスク)、ルートモーションはクリップに埋め込まれた root ボーンの変位を実際のキャラ移動へ変換する。すべて描画のスキニングとは独立したゲームプレイ制御層の話。
スキニングは「見た目」、状態機械は「どのポーズを今出すか」の制御
横にスクロール
キャラクターアニメーションは二つの層に分かれます。一つは、ボーン(スケルトン)の姿勢からメッシュ頂点を変形させるスキニング——リニアブレンドスキニングやデュアルクォータニオンで頂点をGPU上で動かす描画側の処理です(この描画パイプラインは /graphics/ の領域)。もう一つが本記事の主題、いつ・どのモーションを・どんな姿勢(ポーズ)として出力するかを決めるゲームプレイ制御層です。前者が「与えられたポーズをどう画面に出すか」なら、後者は「そもそもどのポーズを作るか」を担います。両者は独立しており、状態機械が最終的に出力するのは1フレーム分のローカルポーズ(各ボーンの回転・位置)で、それをスキニングが受け取って頂点を変形します。
このポーズを生成する制御構造の中核がアニメーション状態機械(アニメーションステートマシン)です。歩く・走る・ジャンプ・攻撃といった各状態に1つのモーション(アニメーションクリップ、またはブレンドツリー)を割り当て、状態間の移り変わりを条件付きの遷移(トランジション)として有向グラフで表します。
アニメーション状態機械は各フレームで概ね次を行います。(1) 現在状態のクリップの再生時刻を dt だけ進め、ローカルタイムからポーズをサンプリングする。(2) 遷移条件(速度パラメータ、接地フラグ、入力トリガなど)を評価し、成立していれば遷移を開始する。(3) 遷移中なら遷移元と遷移先の両方のポーズを評価し、フェード係数でブレンドして1つのポーズに合成する。最終出力はボーンごとのローカル変換の列であり、これが上位のスキニング(描画)へ渡される。単なる「1本のクリップ再生」ではなく、遷移期間は必ず複数クリップの同時評価が走る点が要。
クロスフェード:遷移を「重み付き補間」で滑らかにする
状態Aから状態Bへ切り替えるとき、Aを止めた瞬間にBへ差し替えると姿勢が不連続に飛び、ガクつき(ポップ)が起きます。これを防ぐのがクロスフェードです。遷移時間 T(例 0.2 秒)をかけて、フェード係数 w を 0 から 1 へ動かし、両ポーズを重み付き補間します。
遷移中フレームのブレンド(各ボーンごと):
w = clamp(elapsed / T, 0, 1) // フェードの進行度 0→1
位置: p = lerp(p_A, p_B, w) // 平行移動は線形補間
回転: q = slerp(q_A, q_B, w) // クォータニオンは球面線形補間
・elapsed は遷移開始からの経過時間、T は遷移時間
・回転を素の lerp で混ぜると角速度が不均一&非正規化になるため
slerp(または正規化付き nlerp)を使うのが原則
・w にイージング(smoothstep 等)をかけると出入りがより自然
回転を扱う際、オイラー角の線形補間はジンバルロックや軸のねじれで破綻するため、ボーンの姿勢はクォータニオンで保持し、補間は slerp(球面線形補間)か、負荷を抑えたい場合は正規化付きの nlerp を使います。位置(ルート以外はスケルトン構造上ほぼ固定)とスケールは線形補間で足ります。フェード係数 w を線形に動かすと出入りが機械的になるため、smoothstep のようなイージングを掛けて加減速を付けると自然になります。
歩行と走行のように周期の異なるループを単純にクロスフェードすると、両クリップの位相(サイクル上の位置)がずれ、遷移中に足が地面を滑る「フットスライド」が生じます。対策は、遷移先のクリップの再生開始位相を遷移元に合わせる位相同期(フェーズマッチング)や、正規化サイクル時間で足の接地タイミングを揃える手法です。加えて、遷移条件が短時間で行き来するとフェードが往復して震える(チャタリング)ため、ヒステリシスや最小滞在時間で抑えます。
ブレンドツリー:離散状態を増やさず無段階に混ぜる
「立ち/歩き/走り」を別々の状態にして遷移で繋ぐと、境界での切り替わりが目立ち、状態数も速度刻みだけ爆発します。ブレンドツリー(ブレンドスペース)は、連続パラメータ(移動速度、進行方向など)を軸に取り、その値に応じて複数クリップを連続的に補間する仕組みです。1つの状態の中で無段階の動きを生成できます。
- 1Dブレンド: 速度スカラーを軸に、
速度=0→Idle、中速→Walk、高速→Runをサンプル点として並べ、現在の速度が隣接2点のどこにあるかで2クリップを重み付き補間する。 - 2Dブレンド: 進行方向ベクトル(前後・左右)を平面に取り、前進・後退・左右ストレイフの各クリップを配置。現在の入力ベクトルを内包する三角形の頂点クリップを、重心座標(barycentric weights)で3本ブレンドする。
いずれも重要なのは重みの正規化です。各クリップの重み w_i は合計が 1 になるよう正規化し、ポーズ = Σ w_i · pose_i で合成します(回転は重み付き球面補間や、微小角なら正規化付き加算で近似)。合計が 1 でないと全体のスケールが狂い、姿勢が縮んだり伸びたりします。さらにブレンドツリーでも位相同期は不可欠で、混ぜるループクリップの足の接地タイミングを正規化サイクル時間で揃えないと、無段階補間の途中で足が滑ります。
実務ではこの二つを入れ子にします。状態機械は「Locomotion」「Jump」「Attack」といった質的に異なるモード間の離散的な切り替え(と、その間の遷移・クロスフェード)を担当し、各状態の中身をブレンドツリーにして同一モード内の連続的な変化(速度や方向)を吸収する構成が定番です。こうすると状態数を抑えつつ、モード切替は明快に、モード内は滑らかに、という双方の利点が得られます。
レイヤリングとルートモーション
レイヤリングは、複数のアニメーション出力を優先度付きで重ねる仕組みです。下半身は走行ブレンドツリー、上半身は「リロード」や「手を振る」といった別クリップ、というように体の部位ごとに独立した動きを合成できます。合成方式は主に二つあります。
| 合成方式 | 計算 | 用途 |
|---|---|---|
| 上書き(Override) | マスクで指定したボーンを上位レイヤのポーズで置換 | 上半身だけリロード動作に差し替え等 |
| 加算(Additive) | 基準ポーズとの差分を下位ポーズに足し込む | 呼吸・反動・被弾のブレ・エイムのオフセット等 |
上書きレイヤはアバターマスク(ボーンマスク)で「どのボーンに効かせるか」を指定し、指定ボーンだけを上位レイヤのポーズで置き換えます。加算レイヤは、あらかじめ基準ポーズとの差分として作ったクリップを下位のポーズに足し込むもので、呼吸やエイムの微調整、被弾の揺れなど「元の動きを保ったまま上乗せしたい」効果に向きます。加算は差分の足し算なので、ベースの動きを壊さずに重ねられるのが利点です。
ルートモーションは、キャラの移動そのものをアニメーションから駆動する手法です。通常、位置はゲームプレイのロジック(速度×dt)で動かしますが、それだとアニメーションの足運びと実移動速度が一致せず、やはりフットスライドが出ます。ルートモーションでは、クリップのルートボーンにキャラ全体の変位・回転を焼き込んでおき、毎フレームその差分(デルタ)を取り出してキャラのトランスフォームに適用します。
ルートモーションの適用(毎フレーム):
Δroot = rootPose(t) − rootPose(t − dt) // このフレームのルート変位
character.position += rotate(Δroot.pos, character.rotation)
character.rotation *= Δroot.rot // ルートの回転も反映
・移動量がアニメーション由来なので足の接地と実移動が一致
→ フットスライドが原理的に出にくい
・攻撃の踏み込みや受け身など「モーションが移動を決める」場面に最適
・一方でキャラ制御は動力学的な瞬時応答が鈍くなる(クリップの
移動カーブに縛られる)ため、機敏な操作重視ゲームでは併用/切替
ルートモーションは足の接地と移動が原理的に一致するため、踏み込む攻撃や受け身、環境インタラクションなど「動きが移動量を決める」場面で威力を発揮します。反面、移動がクリップに縛られ操作の即応性が落ちるため、素早い操作が要るゲームでは通常移動と使い分けたり、ルートの水平移動だけ無視して速度制御に回すといった調整をします。
- 遷移=ブレンド: クロスフェード中は遷移元・遷移先の両ポーズを評価し、係数
w(0→1)で位置はlerp、回転はslerp補間する。単一クリップ再生ではない。 - 回転はクォータニオン: オイラー角の線形補間は破綻するため、姿勢はクォータニオンで保持し
slerp/nlerpで混ぜる。 - 重みは正規化: ブレンドツリーの各重みは合計 1 に正規化しないと姿勢のスケールが狂う。2Dは重心座標で3クリップを混ぜるのが基本。
- 位相同期でフットスライド対策: 周期の異なるループを混ぜる/遷移するときは接地タイミングを揃える。ヒステリシスで遷移のチャタリングを抑える。
- レイヤリング: 上書き(マスク指定ボーンを置換)と加算(差分を足す)を用途で使い分ける。上半身と下半身の分離、反動・エイムの上乗せに有効。
- ルートモーション: ルートボーンのデルタ変位でキャラを動かすと足運びと移動が一致。ただし即応性とのトレードオフ。
- スキニングとは別層: 以上はすべてポーズ生成(ゲームプレイ制御)の話で、頂点変形(描画)とは独立。
まとめ
アニメーション状態機械は、各状態にモーションを割り当て、条件付き遷移を有向グラフで表すことで「今どのポーズを出すか」を制御する仕組みです。遷移はクロスフェードで滑らかに繋がれ、フェード中は遷移元と遷移先の両ポーズを重み係数で補間します——位置は線形補間、回転はクォータニオンの球面線形補間で。ブレンドツリーは速度や方向といった連続パラメータで複数クリップを無段階に混ぜ、離散状態の増殖を避けます。重みは合計1に正規化し、位相同期でフットスライドを防ぐのが要点です。レイヤリングは上書き(マスク)と加算で部位ごと・効果ごとの動きを重ね、ルートモーションはクリップに焼き込んだルートボーンの変位からキャラの実移動を駆動して足運びと移動を一致させます。これらはすべて、頂点をGPUで変形するスキニング(描画)とは独立した、ポーズ生成というゲームプレイ制御層の技術です。状態機械で質的なモード切替を、ブレンドツリーでモード内の連続変化を、レイヤリングで部位合成を、ルートモーションで移動駆動を——役割を分けて組み合わせることで、滑らかで応答性の高いキャラクター制御が設計できます。制御ロジックの実装そのものは /programming/ の一般的なステートマシン設計とも地続きです。
ゲーム開発の記事ガイド
アニメーション状態機械とブレンドを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
ゲーム開発
比較で見る軸
難易度: advanced / カテゴリ: ゲーム開発 / タグ数: 6
導入後に効く点
ブレンドツリーは1D/2Dのパラメータ(速度・方向など)で複数クリップを連続補間し、離散状態を増やさず無段階の動きを作る。重みは正規化して合計1にし、位相同期でフットスライドを防ぐ。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- ゲーム開発
- タグ数
- 6
判断チェックリスト
- 自社の用途が「ゲーム開発 / アニメーション」に近いか確認する。
- 強みである「アニメーション状態機械(ステートマシン)は各状態に1つのモーション(またはブレンドツリー)を割り当て、条件付き遷移をエッジで表す。遷移はクロスフェード(重み付き線形補間)で滑らかに繋ぎ、フェード中は複数状態を同時評価してブレンドする。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。