AnimatorOverrideControllerとは?

AnimatorOverrideControllerは、既存のAnimator Controllerのアニメーションクリップだけを差し替えることができる特殊なコントローラーです。

通常、異なるキャラクターに異なるアニメーションを適用する場合、それぞれに別のAnimator Controllerを作成する必要があります。

しかし、ステートマシンの構造やトランジションのロジックが同じ場合、これは非効率的です。

AnimatorOverrideControllerを使用すると、ステートマシンの構造を保ったまま、アニメーションクリップだけを置き換えることができます。

AnimatorOverrideControllerを使うメリット

Animator Controllerの複製が不要

同じ動作でアニメーションが異なるキャラクターを作る際、Animator Controllerを複製する必要がありません。

これにより、以下のメリットがあります:

  • アセット管理が簡潔になる
  • ディスク容量の節約
  • プロジェクトの見通しが良くなる

メンテナンス性の向上

元のAnimator Controllerを修正すると、それを使用するすべてのAnimatorOverrideControllerに自動的に反映されます。

例えば、攻撃モーションのトランジション条件を変更した場合、すべてのキャラクターバリエーションに変更が適用されます。

実際の使用シーン

AnimatorOverrideControllerは以下のようなシーンで活用できます:

  • 敵キャラクターの色違い: 同じ動作だが見た目が異なる敵
  • 武器のバリエーション: 同じ攻撃パターンで武器が異なる場合
  • キャラクタースキン: プレイヤーキャラクターの衣装違い
  • 難易度別の演出: 同じ動作で速度やエフェクトが異なるパターン

基本的な使い方

AnimatorOverrideControllerアセットの作成

Unity EditorでAnimatorOverrideControllerを作成する手順は以下の通りです:

  1. Projectウィンドウで右クリック
  2. CreateAnimationAnimator Override Controllerを選択
  3. 作成されたアセットを選択

AnimatorOverrideControllerの場合、アイコンに+マークがつきます。

元のAnimator Controllerの指定

InspectorControllerフィールドに、ベースとなるAnimator Controllerを設定します。

設定すると、元のコントローラーで使用されているアニメーションクリップの一覧が表示されます。

アニメーションクリップの差し替え

一覧に表示された各アニメーションクリップの右側に、差し替え先のクリップを設定します。

Idleだけ変更してみましたが、未設定の場合は元のAnimatorControllerのアニメーションが使用されます。

左側が元のAnimatorController、右側がAnimatorOverrideControllerIdleのアニメーションを別のものに変更した状態です。

キャラクターへの適用

AnimatorコンポーネントのControllerフィールドに、作成したAnimatorOverrideControllerを設定します。

using UnityEngine;

public class CharacterSetup : MonoBehaviour
{
    [SerializeField] private AnimatorOverrideController _overrideController;

    private void Start()
    {
        var animator = GetComponent<Animator>();
        animator.runtimeAnimatorController = _overrideController;
    }
}

スクリプトから動的に差し替える

ランタイムでアニメーションクリップを差し替えることができます。

using UnityEngine;

public class DynamicAnimationSwitcher : MonoBehaviour
{
    [SerializeField] private Animator _animator;
    [SerializeField] private AnimationClip _newIdleClip;
    [SerializeField] private AnimationClip _newWalkClip;

    private void Start()
    {
        // AnimatorOverrideControllerを作成
        var overrideController = new AnimatorOverrideController(_animator.runtimeAnimatorController);

        // クリップを取得
        var clipOverrides = new AnimationClipOverrides(overrideController.overridesCount);
        overrideController.GetOverrides(clipOverrides);

        // クリップを差し替え(nullチェック推奨)
        if (_newIdleClip != null && clipOverrides["Idle"] != null)
            clipOverrides["Idle"] = _newIdleClip;
        if (_newWalkClip != null && clipOverrides["Walk"] != null)
            clipOverrides["Walk"] = _newWalkClip;

        // 変更を適用
        overrideController.ApplyOverrides(clipOverrides);
        _animator.runtimeAnimatorController = overrideController;
    }
}

注意点

元のAnimator Controllerとの依存関係

AnimatorOverrideControllerは元のAnimator Controllerに依存しています。

元のコントローラーを削除したり大幅に変更すると正しく動作しなくなります。

アニメーションクリップの互換性

差し替えるクリップは元のクリップと互換性が必要です:

  • 長さの違い: トランジションのタイミングに影響
  • Animation Event: 差し替え先にも同じイベントが必要
  • ルートモーション: 設定が異なると移動距離が変わる

パフォーマンスとnullチェック

  • ランタイムで作成すると若干メモリ・CPU使用。頻繁に切り替える場合は事前に作成することをおすすめします
  • クリップ差し替え時は必ずnullチェックしましょう(null設定でアニメーションが再生されなくなる)

まとめ

AnimatorOverrideControllerは、同じ動作で異なるアニメーションを使用する場合に非常に便利な機能です。

ステートマシンの構造を共有することで、メンテナンス性が大幅に向上し、アセット管理も簡潔になります。

キャラクターバリエーションの実装や、武器・衣装の切り替えなど、様々なシーンで活用できます。

ScriptableObjectと組み合わせることで、より柔軟なキャラクター管理システムを構築できます。

ぜひプロジェクトで活用してみてください!