続 CubismParameterStore の使い方

【Cubism SDKのバージョン】Cubism 4 SDK for Unity R7
【OS名・バージョン】Windows10
【開発使用ツール】Unity 2021.3.28f1 LTS

以前こちらで質問させて頂いた件なのですが、
「Assets\Scripts\Live2D\Cubism\Samples\Models\Mao」
のサンプルを読み込んでみました。


上の画像がご提案頂いた修正をしてない場合で
下の画像が修正をした場合でです。
修正をした方は手が二重に表示されてしまいました。

特定の「motions」を適用すれば二重表示は解消するのですが、
初期読み込み時からデフォルトのポーズにしたいのです。

何か解決策は御座いますでしょうか?

@KT

いつも弊社製品をご愛顧くださり誠にありがとうございます。

誠に申し訳ありませんが、ポーズ機能はランタイムからのモデルの読み込みに対応しておりません。
お手数でございますが、モーションを再生するなどして対応してください。

ポーズはもともとNative、Webなどでモーション内のパーツ不透明度がパラメータとして適用される仕様を仲介する機能です。
モーションから、存在しないIDのパラメータとしてパーツ不透明度を適用し、ポーズ機能がその値を取得、加工してモデルにパーツ不透明度を反映させます。
しかしCubism SDK for Unityでは、アニメーションからのパーツ不透明度の値は直接パーツ不透明度として適用されるため、パラメータを介しません。
そのため、Unityでのポーズ機能は処理の構造が他と異なり、アニメーションのパーツ不透明度のカーブを直接加工することで実現しています。

Unityで行っているポーズの処理は以下の3つです:
①ポーズで使用するパーツをモデルに設定
②AnimationClipのパーツ不透明度のカーブを加工
③fade.assetのパーツ不透明度のフェード値を加工

①はモデルのPrefabに設定する処理です。
②、③はアニメーションに関連する処理で、Unity独自の処理です。

②:
これはアニメーション内のパーツ表示の遷移を管理するための処理です。
エディタ上のデフォルトでは、下位互換のためにSteppedのカーブで設定されます。
エディタ上では、通常のアニメーション生成・更新処理とアニメーションの加工処理が別に走り、どちらも所定の場所にあるアニメーションの読み込みを試みてから行います。
これらの処理は、すべてランタイムで使用できないカスタムインポーター用のスクリプトで行っており、ランタイムからはアニメーションのカーブを加工させる事ができません。
仮にランタイムでも加工処理を呼び出すのであれば、加工処理をランタイム用のスクリプトに移す必要があります。

③:
これはモーションとモーションの間のパーツ表示の遷移を管理するための処理で、SDK付属のMotionFadeコンポーネントを利用して再現しています。
しかし、ランタイムで生成したアニメーションは、MotionFadeが対応しているAnimatorコンポーネントやCubismMotionControllerで再生することができません。
これはUnityの仕様で、ランタイムでは必ずLegacy方式で生成されます。
このLegacy方式のアニメーションを再生させるには、UnityのAnimationコンポーネントを使用する必要があります。
しかし、MotionFadeコンポーネントは現在Animationコンポーネントに対応していません。

そのため、現状のCubism SDK for Unityでは、ランタイムでPose機能を扱うことはできません。

これらの対応につきましては要望として検討させていただきます。

よろしくお願いいたします。

お返事頂き、ありがとうございます。

ランタイムでPose機能を扱うことは出来ない事は承知しました。

疑問なのですが、
CubismModel の _parameterStore がデフォルトだと null になっていて
その状態だとモデルを読み込んでも全ての腕が表示されないのに、

以前指示された「model._parameterStore = model.gameObject.AddComponent();」
の位置をメソッドの一番上に持っていく事で確実に _parameterStore が
null にならないようにした場合は全ての腕が表示されてしまうのは
どういった働きによるものなのでしょうか?

@KT

チュートリアルのスニペットの他になにか処理を行っていますでしょうか?

「Mao」のアセットを「Assets/StreamingAssets」に入れて
その時に「Hierarchy」に表示されたモデルは動的に読み込む為に削除します。
下記のソースコードを「main.cs」として「Assets」フォルダに入れて
「Main Camera」にそのスクリプトを「Add Component」して再生させました。
モデルは再生後にスケールを10倍にしてます。

using System;
using System.IO;
using Live2D.Cubism.Framework.Json;
using UnityEngine;

public class main : MonoBehaviour {
void Start(){
var path = Application.streamingAssetsPath + “/Mao.model3.json”;
var model3Json = CubismModel3Json.LoadAtPath(path, BuiltinLoadAssetAtPath);
var model = model3Json.ToModel();
}
public static object BuiltinLoadAssetAtPath(Type assetType, string absolutePath){
if (assetType == typeof(byte)){
return File.ReadAllBytes(absolutePath);
} else if(assetType == typeof(string)){
return File.ReadAllText(absolutePath);
} else if (assetType == typeof(Texture2D)){
var texture = new Texture2D(1,1);
texture.LoadImage(File.ReadAllBytes(absolutePath));
return texture;
}
throw new NotSupportedException();
}
}

@KT

回答ありがとうございます。

こちらの手順で確認しましたが、修正前の状態でもすべての腕のパーツが表示状態となり、添付していただいた画像の状態の再現を確認できませんでした。
上記スクリプト以外でなにか処理を行っていないか、再度ご確認をお願いできますでしょうか?

よろしくお願いいたします。

main.zip (898 バイト)

申し訳ございません。

こちらで説明されていた、
CubismPoseMotionImporter.InitializePosePart()
部分のポーズ処理が入っていたのを失念しておりました。

ポーズ機能はランタイムからのモデルの読み込みに対応していない
との事なのですが修正前であれば
この部分を移植すると機能させる事が出来ていたようでした。

修正したソースファイルを添付しておりますので
ご確認頂けますでしょうか。

@KT

@ono-at-live2d-com に代わりましてご連絡差し上げます。
本件回答をお待たせしており、大変申し訳ございません。
こちらご返信いただいてから時間が経過しておりますが、現在調査中ですのでもうしばらくお待ちいただけますようお願いいたします。

いつも弊社製品をご愛顧のほど誠にありがとうございます。

お問い合わせ頂いたポーズ処理の件につきまして、調査が完了しましたのでご連絡差し上げます。

先に結論から申し上げますと、今回本スレッドで @KT 様にご提示いただいた修正内容で問題ございません。
その際、以前のスレッド でご提案させていただいた修正内容が不要となります。ご案内に不備があり混乱をお招きし、大変ご迷惑をおかけいたしました。

以下挙動調査の詳細となります。

症状が異なる原因について

_parameterStore が null であるかどうかで挙動が変化いたします。

_parameterStore位置修正前

CubismModel.Revive関数内の CubismModel.CanRevive が一度も有効にならないため、どの状態でも_parameterStore は null のままで main.Start関数は終了します。

_parameterStore位置修正後

いかなる条件であっても CubismModel.Revive関数が呼ばれた段階で _parameterStoreGetComponent関数で更新します。
この結果、main.Start関数内の、CubismModel3Json.ToModel関数やCubismModel.ForceUpdateNow関数でCubismModel.Revive関数が呼ばれると、_parameterStore に参照が入り、nullではなくなります。

この違いによる影響

main.Start関数内でCubismPoseController.Refresh関数を呼んだ際に CubismPoseController.defaultPoseIndex で設定されているインデックス以外は0.0に設定されます。
ただし、_parameterStore が設定されていると CubismParameterStore.Update関数で毎フレーム保存済みの値が適用され、この時点での各パーツの不透明度がポーズ適用前の値であるため全て1.0となります。
CubismParameterStore.SaveParameter関数で最新の値へ更新するのはCubismParameterStore.Refresh関数のため、常に毎フレーム1.0がパーツの不透明度に反映されている状態。

対応について

CubismPoseMotionImporter.InitializePosePart 関数の移植は問題ございません。また_parameterStore位置修正は不要となります。
なお、CubismModel3Json.ToModel関数は内部でCubismModel.InstantiateFrom関数を経由してCubismModel.Reset関数を呼んでいるため、その場でCubismModel.TaskableModelが生成されてその後は CubismModel.IsRevived が有効となり、CubismModel.CanRevive の条件式に入りません。

以上ご確認いただけますと幸いでございます。

詳しくご説明ありがとうございます。

以前のスレッド でご提案させていただいた修正内容が不要となります。

との事ですが、以前のスレッドの修正内容は
_parameterStore が null のままだと
表情の切り替えが正常に行われない為でした。

main.zip (1.2 KB)
サンプルソースを添付致します。
↑↓キーで表情が変更されます。

・_parameterStore位置修正前
ポーズは正常に表示される
表情の変更がおかしくなる

・_parameterStore位置修正後
ポーズは腕が4つ表示される
表情の変更は正常にできる

という、あちらが立てばこちらが立たずな状態なのです。

ご確認ありがとうございます。

再調査いたしまして、@KT 様のご指摘どおり_parameterStore位置修正前後でpose及び表情の変更が両立しないことを確認いたしました。

表情を正常に動作させつつposeを適用する場合、以下のような処理を追加することで実現するかと思います。

  1. CubismModel に以下のような関数を追加します。
/// <summary>
/// パラメータストアを最新の情報に更新する。
/// </summary>
public void RefreshParameterStore()
{
// CubismParameterStore を取得する。
_parameterStore = GetComponent<CubismParameterStore>();

// 最新の情報に更新する。
_parameterStore.Refresh();
}
  1. いただいたmainクラスの poseController.Refresh()model.ForceUpdateNow() の間に、先ほど作成したRefreshParameterStore()関数の呼び出しを追加します。
...
poseController.Refresh();
// --- ここに追加
model.RefreshParameterStore();
// ---
model.ForceUpdateNow();

CubismExp3Json[] expression3Jsons = model3Json.Expression3Jsons;
...

以上の修正となります。

処理としては、poseController.Refresh() のあとで _parameterStore.Refresh() を呼び出し、ポーズを適用した状態のパラメータ値やポーズの不透明度を保存しています。
この内容は _parameterStoreの呼び出し位置修正前後どちらでも正常に動作するかと思います。

この修正をお試しいただけますでしょうか。
度重なる修正、並びにご案内に不備があり大変ご迷惑をおかけしましたこと誠に申し訳ございません。
上記ご確認のほど何卒よろしくお願いいたします。

ご提示頂きました方法を使いました所、
ポーズと表情変更が問題なく動作する事を確認しました。
ご丁寧に教えて下さり、ありがとうございました。

因みにですが、今回の「RefreshParameterStore()」が
正式に「CubismModel.cs」に組み込まれたりだとか
もしくは「RefreshParameterStore()」を使わなくても
「_parameterStore」がランタイムで有効になるように
今後のバージョンで修正が入る可能性はあるのでしょうか?

@KT

ご確認ありがとうございました。
問題なく動作すること、安心いたしました。

本件の修正につきまして問題の再調査をおこないましたが、結論としては _parameterStore はReviveの状態によらず有効になるべきですので、先日お渡しした RefreshParameterStore() が CubismModel に組み込まれるよう、今後の製品リリースにて対応する予定でございます。
もし製品に本不具合の修正が入ったものを利用したい際は、お手数をおかけいたしますが今後のリリースをお待ちいただき、リリースされた際に再度お試しいただけると幸いでございます。

以上何卒よろしくお願いいたします。

お返事頂き、ありがとうございます。

今後、追加される予定との事、承知致しました。
それまでは自分でメソッドを追加して対応しようと思います。

それでは失礼致します。

「いいね!」 1