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() { // 頂点の更新処理 }