鳩の溜まり場

猫か鳩になりたい

ランタイム中にAnimatorのRuntimeAnimatorControllerを変更すると一瞬だけT-Poseになる【Unity】

症状

AnimatorのRuntimeAnimatorControllerをランタイム中に変更すると一瞬T-Poseになってから変更後のアニメーションが再生される。

↓↓ 利用させていただいたアセットはこちら ↓↓

再現用のコードです。
以下のコードでは、元のRuntimeAnimatorControllerを別のRuntimeAnimatorControllerで差し替えてますが、AnimatorOverrideControllerに差し替えても同様の現象が起きます。

public class Sample : MonoBehaviour
{
    [SerializeField] private Animator animator;
    [SerializeField] private RuntimeAnimatorController runtimeAnimatorController;

    private void Start()
    {
        Application.targetFrameRate = 10;
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            animator.runtimeAnimatorController = runtimeAnimatorController;
            animator.Play("Default", 0, 0f);
        }
    }
}

解決方法

調べてみたら同じ現象に陥ったフォーラムがありました。
RuntimeAnimatorControllerを変更したタイミングでAnimator.Update()を呼び出せば良いとのこと。

forum.unity.com

Animator.Play()のあとに呼び出してるAnimator.Update()です。

public class Sample : MonoBehaviour
{
    [SerializeField] private Animator animator;
    [SerializeField] private RuntimeAnimatorController runtimeAnimatorController;

    private void Start()
    {
        Application.targetFrameRate = 10;
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            animator.runtimeAnimatorController = runtimeAnimatorController;
            animator.Play("Default", 0, 0f);
            
            // この行を追加
            animator.Update(0.0f);
        }
    }
}

おまけ

あくまで憶測ではありますが、RuntimeAnimatorControllerの差し変えによってAnimator内部での更新、あるいは描画周りの更新タイミングが嚙み合わず1フレームだけT-Poseになってるのかな?と思います。
具体的な部分までは調べてないですが、必要になったらまた調べるということで・・・。

また、Animator.Update(float deltaTime)の挙動の説明が少しわかりにくかったのでコードを見ようと思ったのですが、公開されてない部分でした。
C++で実装されてる箇所とC#で実装されてる箇所の違いはなんなんだろうか。

github.com