複数のアニメバリエーションを一つのコントローラーで管理する方法(案)。


概要

AnimatorController(Mecanim)って場合によっては便利ですが、
2Dだとあんまり恩恵なかったり、コントローラーが量産されて煩雑になったりしますよね。

今回はUnityの2Dアニメーションに於いて、
キャラバリエーション(とか)が増えてもコントローラーは一つで済ませる方法(案)を綴ります。

※検証環境は Unity 5.0.x 及び Unity 5.2.x です。

事例

主人公キャラクターを「万里生」さんと仮定します。

万里生さんは走りアニメーション(run)を保持しており、f01~f05の5フレームで形成されています。
また、万里生さんには、標準形態のsprite_A、第二形態のsprite_B、最終形態のsprite_Cという3つのバリエーションがあります。

通常であれば、バリエーション毎にコントローラーを用意するところですが、これを一つで成立させよう、というのが今回のお話です。

サンプル

プロジェクト構成例

[Hierarchy]に任意のアニメーションオブジェクトを配置するよ。(character)
character には Animator と、下で紹介する AnimationOverride コンポーネントを付与するよ。

AnimationOverride の Renderer には、Animatorの操作対象になっている SpriteRenderer を指定するよ。(character)
AnimationOverride の Path には、万里生のバリエーションテクスチャのパスを指定するよ。(sprite_A/sprite_B/sprite_C)

上図構成で実行すると、万里生(sprite_C)が再生されるようになるよ!

AnimationOverrideクラス

前回のSpriteLoaderを使いまわします。

AnimationOverride.cs
using UnityEngine;
using System.Collections;

public class AnimationOverride : MonoBehaviour
{
    [SerializeField]
    SpriteRenderer      m_renderer  = null;     //!< コントローラーの操作対象

    [SerializeField]
    string              m_path      = "";       //!< バリエーションテクスチャのパス

    SpriteLoader        m_loader    = null;     //!< Sprite読み込むやーつ

    void Awake()
    {
        if( m_renderer == null )
            m_renderer = GetComponent<SpriteRenderer>();

        // 任意のバリエーションテクスチャを読み込む
        m_loader = new SpriteLoader();
        m_loader.Load( m_path );
    }

    /**
     * ここでSpriteを挿げ替える
     */
    void LateUpdate()
    {
        if( m_renderer == null ) return;
        if( m_renderer.sprite == null ) return;

        if( string.IsNullOrEmpty( m_path ) ) return;

        // SpriteLoaderから今AnimationClipが表示しているスプライトと同じ名前のスプライトを取得して、割り当て直す
        m_renderer.sprite = m_loader.GetSprite( m_renderer.sprite.name );
    }
}

解説

概念図

AnimationOverrideでやってること

LastUpdateの内容がミソ!

  1. m_renderer.sprite が AnimatorController(AnimationClip) から随時変更されるよね
  2. LateUpdate で、変更されたspriteの名前を取得して
  3. m_loader.GetSprite で別バリエーションの同じ名前のスプライトを拾ってくる
  4. それを m_renderer.sprite に還元する!

とっても簡単ね!

メリット

  • 同じモーションパターンならコントローラーが一つで完結する
  • モーションパターン数に変動があってもコントローラー一つを修正すればOK

デメリット

  • 全てのバリエーションに於いて「同じコマ数」、「同じスプライト名」で作る必要がある
  • 常にベースのテクスチャがオンメモリになる
  • 処理がダサい

追記

忘れてましたが、コントローラーだけじゃなくてクリップも大幅に削減できますね!