Expression (Cocos Creator)

最終更新: 2023年3月14日

概要

Expressionは、現在のパラメータの値に対して、表情用のパラメータの値を加算または乗算して設定することができる、Cubismの表情モーションを扱う機能です。
Cocos Creator標準のモーション再生機能であるAnimatorでは、レイヤーに設定できるブレンドモードに乗算(Multiply)が無いため、表現することが出来ません。

表情機能の設定ファイルは.exp3.json形式で書き出されます。
表情の仕組みにつきましては こちら をそれぞれご覧ください。

Expressionを利用するには、あらかじめPrefabに「UpdateControllerの設定方法」と「操作する値の保存/復元を行う」を行う必要があります。

該当のチュートリアル記事は こちら をご覧ください。

表情モーションを再生するには以下の手順を行います。

  1. [.exp3.asset]を作成
  2. [.expressionList.asset]を作成し、[.exp3.asset]を追加
  3. 表情モーションを再生
  4. 表情モーションの計算と適用

[.exp3.asset]を作成

[.exp3.asset]は、[exp3.json]からコンバートしたScriptableObjectのアセットです。
[.exp3.asset]を変更した場合、正常な動作を保証できません。

[exp.json]を[.exp3.asset]にコンバートするには以下の処理を行います。

  1. [exp.json]をパース
  2. CubismExpressionData作成
  3. [.exp3.asset]作成

[exp.json]をパース

[exp3.json]のパースは CubismExp3Json.loadFrom(string exp3Json) または CubismExp3Json.loadFrom(TextAsset exp3JsonAsset) を使います。

CubismExpressionData作成

CubismExpressionDataは、パースされた.exp3.jsonの情報を記録するクラスで、以下のデータを保持しています。

フィールド説明
Typestringjsonファイルの種類。.exp3.jsonの場合は “Live2D Expression” が設定される。
FadeInTimenumber表情がフェードインするまでの時間。値の単位は秒。
FadeOutTimenumber表情がフェードアウトするまでの時間。値の単位は秒。
ParametersSerializableExpressionParameter[]表情を適用するパラメータの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に再生する表情モーションのインデックスを設定することにより、表情モーションを再生・変更することが出来ます。

表情モーションの再生は以下の処理を行っています。

  1. 再生中の表情モーションの終了タイムを設定
  2. 新しい表情モーションを初期化し、表情モーションの再生リストに追加

再生中の表情モーションの終了タイムを設定

再生中の表情モーション存在する場合、再生中の表情モーションが終了するように終了時間を設定します。

    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は、以下の情報を保持しています。

フィールド説明
Typestringjsonファイルの種類。.exp3.jsonの場合は “Live2D Expression” が設定される。
FadeInTimenumber表情がフェードインするまでの時間。値の単位は秒。
FadeOutTimenumber表情がフェードアウトするまでの時間。値の単位は秒。
Weightnumber表情のウェイト。値の範囲は0から1。
ExpressionUserTimenumber表情の再生が開始してからの経過時間。値の単位は秒。
ExpressionEndTimenumber表情の再生が終了する時間。値の単位は秒。
DestinationsCubismParameter[]表情が適用するパラメータの配列。
Valuenumber[]表情がパラメータに適用する値。要素数と並び順はDestinationsと同一。
BlendCubismParameterBlendMode[]表情がパラメータに適用する計算方式。要素数と並び順は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()の前で適用した場合、表情で適用した結果が保存されてしまうため、表情用のパラメータの値が無限に加算または乗算されます。

この記事はお役に立ちましたか?
はいいいえ
この記事に関するご意見・
ご要望をお聞かせください。