【Unity】Animator has not been initialized についてメモ


Animator has not been initializedって?

そのままなのですが、「Animatorが初期化されてませんよ!」
というWarningです。
UnityのMechanimを利用したキャラクターを使用しようとすると、
極稀に、会う事があるようです。
しかし、Warningのため、ゲームは止まりませんし、
AnimatorのDefault Stateは動いていたりと、
よく分からない状態になります。

どうして発生するの?

検索してみて分かったのですが、
一概に原因はコレ!って言える訳では無いようです。
Unityの昔のバグで、今は直ってるとか、そんな話まで出てきます。
以下のような状況で出会うユーザーが多いようです。

  • Animatorを内包しているGameObjectのprefabをAttachして使用している。
  • animator.SetFloat、SetBoolなどを呼び出した瞬間に発生。
  • GetComponent()などは正常に動作。
  • 別キャラクターで同じAnimatorControllerを使い回している。

原因はユーザーの状況によって様々なので、その他にもあると思います。

解決策 その1 コードの凡ミス

間違ってこんな風に書いちゃったりすると、発生します。

Sample.cs

// OriginalCharacterは
// [RequireComponent(typeof(Animator))]って思ってください。
public List<OriginalCharacter> characters;

public void CreateCharacter(string chrId){
    OriginalCharacter chr = characters.Where(c => c.chrId == chrId).FirstOrDefault();
    if(chr != null){
        Instantiate(chr);

        chr.gameObject.transform.position = new Vector3(10.0f , 1.0f , 0.0f);
        Animator anim = chr.gameObject.GetComponent<Animator>();
        anim.SetBool("Run" , true); // !!!! Error !!!!
    }
}

はい、正解はこうです。

Sample.cs

public List<OriginalCharacter> characters;

public void CreateCharacter(string chrId){
    OriginalCharacter chrPrefab = characters.Where(c => c.chrId == chrId).FirstOrDefault();
    if(chrPrefab != null){
        // これが正しい
        OriginalCharacter chr = Instantiate(chrPrefab) as OriginalCharacter;

        chr.gameObject.transform.position = new Vector3(10.0f , 1.0f , 0.0f);
        Animator anim = chr.gameObject.GetComponent<Animator>();
        anim.SetBool("Run" , true); // Success
    }
}

Attachはしているので、nullにならず、
正常に起動出来ますが、参照先がInstance化されていないため、
not Initializedとなります。
正しくInstance化している参照先を指定してあげるだけでOKです。

解決策 その2 Componentの順番を変える

その1では無さそうだ、って時にチェックしてみてください。
AnimatorをComponentの一番下に置くとこのエラーが解消されることが
あるそうです。(自分は未確認ですが)
しかし、少し古い情報なので、昔のUnityの解決法かも?
Inspectorの各Component右上のギアから
MoveDown , MoveUpで移動させる事が出来ます。

解決策 その3 Rebind

なんか一番それっぽいです。
Initialize出来てないなら、してしまえ!ってやつです。

API : Animator.Rebind

Sample.cs

    Animator anim = obj.GetComponent<Animator>();
    anim.Rebind();

    // 処理

キャラクター間で同じAnimatorを使いまわしている時に発生した時は、
これが有効なようです。
GetComponentした後、Rebindしてから使用すればOK。

調べたり、自分で書いてみたりしたけど

その1以外の発生条件はよく分かりませんでした。
たまたまそんな現象があるって話を聞いて、気になって調べてみたのですが…。
同じように書いてみても自分の環境では上手くいってしまったり。
余り参考にならないかもしれませんが、少しでもお力になれば幸いです。