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()の前で適用した場合、表情で適用した結果が保存されてしまうため、表情用のパラメータの値が無限に加算または乗算されます。