Cubism SDK for Unityでのパラメータ操作について

最終更新: 2020年1月31日

Cubism SDK for Unityでモデルのパラメータの値を操作する場合、Unityのイベント関数のMonoBehaviour.LateUpdate()からMonoBehaviour.OnPreRender()までのタイミングで行う必要があります。

Unityのイベント関数にの実行順ついては こちら をご覧ください。

AnimationClipを再生させる処理は、Unityのイベント関数のMonoBehaviour.Update()とMonoBehaviour.LateUpdate()の間で行われます。
仮にパラメータの値をMonoBehaviour.Update()で操作した場合、直後に再生されるAnimationClipの値によって上書きされてしまいます。
そのため、パラメータの値を操作する場合はAnimationClipが値を設定した後に行います。

Cubism SDK for Unity同梱のコンポーネントはすべてMonoBehaviour.LateUpdate()からパラメータの値を操作しております。

また、各フレームでパラメータの値からモデルの頂点更新処理をCubismModel.OnRenderObject()で行っているため、これよりも後で値の操作を行うと計算されません。

※CubismModel.OnRenderObject()はSceneに配置された各Cameraがレンダリングを終えたタイミングで呼び出されるため、Sceneに複数Cameraが配置されている場合、CubismModel.OnRenderObject()がCameraの数だけ呼び出されます。 

SRPでの動作

Unityは2018.1から、レンダリングの設定や実行をC#スクリプトで制御できる仕組みである「Scriptable Render Pipeline(SRP)」が追加されました。

SRP自体の詳細につきましてはUnity公式のドキュメントをご覧ください。

このレンダーパイプラインを使用する場合、Unityの一部のイベント関数が呼びされません。

Cubism SDK for Unity において、設定されたパラメータの値からモデルの頂点を更新する処理はCubismModel.OnRenderObject()で行っている。
これは、頂点の更新処理をパラメータの値の更新を行っているLateUpdate()よりも後に呼び出すためですが、MonoBehaviour.OnRenderObject()はSRPのプロジェクトでは呼び出されません。

Cubism SDK for Unity R1以降では、プロジェクトがSRPに対応したUnity 2018.1以降の場合、頂点の更新処理を行う関数を PlayerLoop によって LateUpdate()の後に呼び出されるよう登録しています。

        private bool WasAttachedModelUpdateFunction { get; set; }

        ...

        /// <summary>
        /// Called by Unity. Triggers <see langword="this"/> to update.
        /// </summary>
        private void Update()
        {
#if UNITY_2018_1_OR_NEWER
            if (!WasAttachedModelUpdateFunction)
            {
                _modelUpdateFunctions += OnModelUpdate;


                WasAttachedModelUpdateFunction = true;
            }
#endif

        ...

        /// <summary>
        /// Called by Unity. Destroys instance.
        /// </summary>
        private void OnDisable()
        {
#if UNITY_2018_1_OR_NEWER
            if (WasAttachedModelUpdateFunction)
            {
                _modelUpdateFunctions -= OnModelUpdate;


                WasAttachedModelUpdateFunction = false;
            }
#endif
        }
        
        /// <summary>
        /// Called by Unity. Blockingly updates <see langword="this"/> on first frame enabled; otherwise tries async update.
        /// </summary>
        private void OnRenderObject()
        {
#if !UNITY_2018_1_OR_NEWER
            OnModelUpdate();
#endif
        }
          
        ...

        /// <summary>
        /// Update model states.
        /// </summary>
        private void OnModelUpdate()
        {
            
            // 頂点の更新処理
            
        }
この記事はお役に立ちましたか?
はいいいえ
この記事に関するご意見・
ご要望をお聞かせください。