Expression (Cocos Creator)

업데이트: 2023/03/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() 전에 적용했을 경우 표정으로 적용한 결과가 저장되어 버리기 때문에, 표정용 파라미터의 값이 무한 가산 또는 곱셈됩니다.

이 기사가 도움이 되었나요?
아니요
이 기사에 관한 의견 및 요청사항을 보내 주시기 바랍니다.