Posted at

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

More than 3 years have passed since last update.


Animator has not been initializedって?

そのままなのですが、「Animatorが初期化されてませんよ!」

というWarningです。

UnityのMechanimを利用したキャラクターを使用しようとすると、

極稀に、会う事があるようです。

しかし、Warningのため、ゲームは止まりませんし、

AnimatorのDefault Stateは動いていたりと、

よく分からない状態になります。

スクリーンショット 2015-06-15 23.12.30.png


どうして発生するの?

検索してみて分かったのですが、

一概に原因はコレ!って言える訳では無いようです。

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で移動させる事が出来ます。

スクリーンショット 2015-06-15 23.34.47.png


解決策 その3 Rebind

なんか一番それっぽいです。

Initialize出来てないなら、してしまえ!ってやつです。

API : Animator.Rebind


Sample.cs


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

// 処理


キャラクター間で同じAnimatorを使いまわしている時に発生した時は、

これが有効なようです。

GetComponentした後、Rebindしてから使用すればOK。


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

その1以外の発生条件はよく分かりませんでした。

たまたまそんな現象があるって話を聞いて、気になって調べてみたのですが…。

同じように書いてみても自分の環境では上手くいってしまったり。

余り参考にならないかもしれませんが、少しでもお力になれば幸いです。