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

最終更新: 2020年1月31日

このページはCubism 4.2以前の古いバージョン向けです。 最新のページはこちら

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()の後に呼び出されるよう登録しています。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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()
{
// 頂点の更新処理
}
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() { // 頂点の更新処理 }
        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()
        {
            
            // 頂点の更新処理
            
        }
この記事はお役に立ちましたか?
はいいいえ
この記事に関するご意見・
ご要望をお聞かせください。