Expression (Cocos Creator)
最終更新: 2023年3月14日
概要
Expressionは、現在のパラメータの値に対して、表情用のパラメータの値を加算または乗算して設定することができる、Cubismの表情モーションを扱う機能です。
Cocos Creator標準のモーション再生機能であるAnimatorでは、レイヤーに設定できるブレンドモードに乗算(Multiply)が無いため、表現することが出来ません。
表情機能の設定ファイルは.exp3.json形式で書き出されます。
表情の仕組みにつきましては こちら をそれぞれご覧ください。
Expressionを利用するには、あらかじめPrefabに「UpdateControllerの設定方法」と「操作する値の保存/復元を行う」を行う必要があります。
該当のチュートリアル記事は こちら をご覧ください。
表情モーションを再生するには以下の手順を行います。
- [.exp3.asset]を作成
- [.expressionList.asset]を作成し、[.exp3.asset]を追加
- 表情モーションを再生
- 表情モーションの計算と適用
[.exp3.asset]を作成
[.exp3.asset]は、[exp3.json]からコンバートしたScriptableObjectのアセットです。
[.exp3.asset]を変更した場合、正常な動作を保証できません。
[exp.json]を[.exp3.asset]にコンバートするには以下の処理を行います。
- [exp.json]をパース
- CubismExpressionData作成
- [.exp3.asset]作成
[exp.json]をパース
[exp3.json]のパースは CubismExp3Json.loadFrom(string exp3Json) または CubismExp3Json.loadFrom(TextAsset exp3JsonAsset) を使います。
CubismExpressionData作成
CubismExpressionDataは、パースされた.exp3.jsonの情報を記録するクラスで、以下のデータを保持しています。
| フィールド | 型 | 説明 |
|---|---|---|
| Type | string | jsonファイルの種類。.exp3.jsonの場合は “Live2D Expression” が設定される。 |
| FadeInTime | number | 表情がフェードインするまでの時間。値の単位は秒。 |
| FadeOutTime | number | 表情がフェードアウトするまでの時間。値の単位は秒。 |
| Parameters | SerializableExpressionParameter[] | 表情を適用するパラメータのID、適用する値、計算方式。 |
[.exp3.asset]の新規作成には CubismExpressionData.CreateInstance(CubismExp3Json json) を使います。
[.exp3.asset]を上書きするには CubismExpressionData.CreateInstance(CubismExpressionData expressionData, CubismExp3Json json) を使います。
- CubismExp3Json json:CubismExp3Jsonは[exp3.json]をパースしたデータ。
- CubismExpressionData expressionData:上書き対象となるCubismExpressionData。
[.exp3.asset]作成
[.exp3.asset]は以下のように作成します。
const jsonSrc = readFileSync(asset.source, UTF8);
const json = CubismExp3Json.loadFrom(jsonSrc);
if (json == null) {
console.error('CubismExp3Json.loadFrom() is failed.');
return false;
}
const data = CubismExpressionData.createInstance(json);
const serialized = EditorExtends.serialize(data);
writeFileSync(outputFilePath, jsonSrc);
asset.saveToLibrary('.json', serialized);
refresh(outputFilePath);
この処理は CubismExpression3JsonImporter.import() で行っています。
※ ランタイムの場合、CubismExpressionDataを.asset化する必要はありません。
[.expressionList.asset]を作成し、[.exp3.asset]を追加
[.expressionList.asset]は、モデル毎の[.exp3.asset]の参照をリスト化したアセットです。
これはCubismExpressionControllerでCurrentExpressionIndexから再生する表情モーションを取得するために使用します。
[.exp3.asset]リストの順番は[exp3.json]のインポート順で追加されます。
[.expressionList.asset]を作成
[.expressionList.asset]はモデルのプレハブと同じ階層に作成しています。
const source = JSON.parse(readFileSync(asset.source, UTF8));
const expDataUuidsSource = Array.isArray(source.cubismExpressionObjects)
? (source.cubismExpressionObjects as any[])
: undefined;
if (expDataUuidsSource == null) {
console.error('CubismExpressionListImporter.import(): parse error.');
return false;
}
const expDataUuids = purseCubismExpressionObjects(expDataUuidsSource);
if (expDataUuids == null) {
console.error('CubismExpressionListImporter.import(): CubismExpressionObjects parse error.');
return false;
}
const cubismExpressionObjects = new Array<CubismExpressionData>(expDataUuids.length);
for (let i = 0; i < cubismExpressionObjects.length; i++) {
const uuid = expDataUuids[i];
// @ts-ignore
cubismExpressionObjects[i] = EditorExtends.serialize.asAsset(
uuid,
CubismExpressionData
) as CubismExpressionData;
}
const list = new CubismExpressionList();
list.cubismExpressionObjects = cubismExpressionObjects;
await asset.saveToLibrary('.json', EditorExtends.serialize(list));
※この項目の処理は CubismExpressionListImporter.import() で行っています。
[.exp3.asset]を追加
[.expressionList.asset]に[.exp3.asset]を追加するには、以下のように行っています。
const jsonSrc = readFileSync(asset.source, 'utf8');
const json = CubismExp3Json.loadFrom(jsonSrc);
if (json == null) {
console.error('CubismExp3Json.loadFrom() is failed.');
return false;
}
const data = CubismExpressionData.createInstance(json);
const serialized = EditorExtends.serialize(data);
asset.saveToLibrary('.json', serialized);
refresh(outputFilePath);
const dirPath = Path.join(Path.dirname(asset.source), '../');
const dirName = Path.basename(dirPath);
if (dirPath.length == 0) {
console.warn('CubismExpressionDataImporter.import(): Not subdirectory.');
return true;
}
const expressionListFilePath = Path.join(
dirPath,
dirName + `.${CubismExpressionListImporter.extension}`
);
updateExpressionListFile(expressionListFilePath, asset.uuid);
refresh(expressionListFilePath);
※この項目の処理は CubismExpressionDataImporter.import() で行っています。
表情モーションを再生
CubismExpressionController.CurrentExpressionIndexに再生する表情モーションのインデックスを設定することにより、表情モーションを再生・変更することが出来ます。
表情モーションの再生は以下の処理を行っています。
- 再生中の表情モーションの終了タイムを設定
- 新しい表情モーションを初期化し、表情モーションの再生リストに追加
再生中の表情モーションの終了タイムを設定
再生中の表情モーション存在する場合、再生中の表情モーションが終了するように終了時間を設定します。
const playingExpressions = this._playingExpressions;
if (playingExpressions.length > 0) {
const playingExpression = playingExpressions[playingExpressions.length - 1];
playingExpression.expressionEndTime =
playingExpression.expressionUserTime + playingExpression.fadeOutTime;
playingExpressions[playingExpressions.length - 1] = playingExpression;
}
この処理は CubismExpressionController.startExpression() で行っています。
新しい表情モーションを初期化し、表情モーションの再生リストに追加する
表情モーションの再生情報を持つCubismPlayingExpressionを作成します。
CubismPlayingExpressionは、以下の情報を保持しています。
| フィールド | 型 | 説明 |
|---|---|---|
| Type | string | jsonファイルの種類。.exp3.jsonの場合は “Live2D Expression” が設定される。 |
| FadeInTime | number | 表情がフェードインするまでの時間。値の単位は秒。 |
| FadeOutTime | number | 表情がフェードアウトするまでの時間。値の単位は秒。 |
| Weight | number | 表情のウェイト。値の範囲は0から1。 |
| ExpressionUserTime | number | 表情の再生が開始してからの経過時間。値の単位は秒。 |
| ExpressionEndTime | number | 表情の再生が終了する時間。値の単位は秒。 |
| Destinations | CubismParameter[] | 表情が適用するパラメータの配列。 |
| Value | number[] | 表情がパラメータに適用する値。要素数と並び順はDestinationsと同一。 |
| Blend | CubismParameterBlendMode[] | 表情がパラメータに適用する計算方式。要素数と並び順はDestinationsと同一。設定される計算方式はOverride, Additive, Multiply。 |
CubismPlayingExpressionは CubismPlayingExpression.create(CubismModel model, CubismExpressionData expressionData) を使用して作成することができます。
- CubismModel model:表情モーションを再生するモデル。
- CubismExpressionData expressionData:再生する表情モーションの[exp3.asset]データ。
作成した表情モーションは、以下のように再生リストに追加します。
const playingExpression = CubismPlayingExpression.create(
this._model,
expressionsList.cubismExpressionObjects[this.currentExpressionIndex]
);
if (playingExpression == null) {
return;
}
// Add to PlayingExList.
playingExpressions.push(palyingExpression);
この処理は CubismExpressionController.startExpression() で行っています。
表情モーションの計算と適用
表情の計算と適用はCubismExpressionController.onLateUpdate()から呼び出されます。
※ 表情の適用はParameterStore.saveParameters()の後に行う必要があります。
Expressionは、現在の値に対して毎フレーム新たに表情用の値を適用する機能です。
ParameterStore.saveParameters()の前で適用した場合、表情で適用した結果が保存されてしまうため、表情用のパラメータの値が無限に加算または乗算されます。