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