EyeBlink (Cocos Creator)

업데이트: 2023/03/14

개요

EyeBlink는 눈 깜빡임용 파라미터의 현재 값에 개폐 상태 값을 적용하는 기능입니다.
모델에 눈 깜빡임용 파라미터를 설정하는 방법은 여기를 참조하십시오.

눈 깜빡임용 파라미터 지정은 모델 자체에 설정하는 것 외에 Cocos Creator에서 사용자가 임의로 지정할 수 있습니다.

Cubism SDK for Cocos Creator의 EyeBlink는 세 가지 요소로 구성됩니다.

  1. 파라미터 지정용 컴포넌트
  2. 각 파라미터에 값을 적용하는 컴포넌트
  3. 2에서 적용하는 값 조작

1. 파라미터 지정용 컴포넌트

EyeBlink에 사용할 파라미터를 지정하려면 CubismEyeBlinkParameter를 사용합니다.

CubismEyeBlinkParameter는 Component를 상속받은 컴포넌트로,
[Prefab 루트]/Parameters/ 아래에 배치된 GameObject에 연결하여 사용합니다.
이것이 연결된 GameObject와 같은 ID의 파라미터를 눈 깜빡임용 파라미터로서 취급합니다.

모델 자체에 눈 깜빡임용 파라미터가 설정되어 있으면 가져올 때 해당 파라미터의 GameObject에 CubismEyeBlinkParameter가 연결됩니다.

CubismEyeBlinkParameter는 참조처를 취득하기 위한 마커로서 사용하므로, 내부에서는 아무것도 처리하지 않고 데이터도 가지고 있지 않습니다.

2. 각 파라미터에 값을 적용하는 컴포넌트

각 파라미터에 개폐 값을 적용하려면 CubismEyeBlinkController를 사용합니다.
이것은 Component를 상속받은 컴포넌트이며, 사용할 때 Cubism의 Prefab 루트에 연결됩니다.

초기화 시 Prefab에 연결된 모든 CubismEyeBlinkParameter의 참조를 취득합니다.
실행 중에 눈 깜빡임용 파라미터를 추가/삭제한 경우 CubismEyeBlinkController.refresh()를 호출해 참조를 다시 취득합니다.

  /** Refreshes controller. Call this method after adding and/or removing <see cref="CubismEyeBlinkParameter"/>s. */
  public refresh(): void {
    const model = CoreComponentExtensionMethods.findCubismModel(this);

    // Fail silently...
    if (model == null) {
      return;
    }

    // Cache destinations.
    const tags =
      model.parameters ! = null
        ? ComponentExtensionMethods.getComponentsMany(model.parameters, CubismEyeBlinkParameter)
        : null;

    this.destinations = new Array(tags?.length ?? 0);

    for (var i = 0; i < this.destinations.length; i++) {
      this.destinations[i] = tags! [i].getComponent(CubismParameter);
    }

    // Get cubism update controller.
    this.hasUpdateController = this.getComponent(CubismUpdateController) ! = null;
  }

...

  /** Called by Cocos Creator. Makes sure cache is initialized. */
  protected start(): void {
    // Initialize cache.
    this.refresh();
  }

CubismEyeBlinkController는 매 프레임의 onLateUpdate() 타이밍에 CubismEyeBlinkParameter로 마킹된 파라미터에 CubismEyeBlinkController.eyeOpening의 값을 적용합니다.

// Apply value.
CubismParameterExtensionMethods.blendToValueArray(
  this.destinations,
  this.blendMode,
  this.eyeOpening
);

EyeOpening에 설정하는 값은 0.0f~1.0f 범위입니다.
CubismEyeBlinkController는 이 값을 대상 파라미터에 CubismEyeBlinkController.blendMode에서 설정된 계산 방식으로 적용합니다.

이 EyeOpening의 값을 밖에서 조작하면 모델의 눈을 열고 닫을 수 있습니다.

/** Opening of the eyes. */
@property({ type: CCFloat, visible: true, serializable: true, range: [0.0, 1.0, 0.01] })
public eyeOpening: number = 1.0;

3. 2에서 적용하는 값의 조작

「2. 각 파라미터에 값을 적용하는 컴포넌트」에서 설명한 대로 CubismEyeBlinkController.eyeOpening의 값을 조작하여 눈 깜빡임용 파라미터에 값을 적용할 수 있습니다.
Cubism SDK for Cocos Creator에서는 다음 두 가지 방법으로 이 값을 조작할 수 있습니다.

  • 모션으로 값 조작
  • 컴포넌트로 값 조작

또 유저 측에서 이 값을 조작하는 처리를 구현하시면 눈 깜빡임 속도나 타이밍 등을 독자적으로 커스터마이즈 할 수 있습니다.

TIPS

CubismEyeBlinkController.eyeOpening을 조작하는 컴포넌트의 실행 순서가 CubismEyeBlinkController보다 나중인 경우 의도한 동작이 되지 않을 가능성이 있습니다.
만약 동작에 문제가 생겼다면 유저 측에서 명시적으로 컴포넌트의 실행 순서를 제어하여 회피할 수 있습니다.
Cubism SDK for Cocos Creator는 각 컴포넌트의 실행 순서를 CubismUpdateController로 제어하므로 이를 활용할 수도 있습니다.

또한 상기 2종류의 설정 방법은 각각 다른 타이밍에 같은 값을 조작하고 있기 때문에, 궁리 없이 하나의 모델에 양쪽을 공존시키는 것은 어렵습니다.

모션으로 값 조작

눈 깜빡임용 파라미터를 설정한 모델을 사용하여 Cubism의 Animator에서 모션을 만들 경우 눈 깜빡임용 커브를 설정할 수 있습니다.

눈 깜빡임용 커브가 설정된 .motion3.json을 프로젝트로 가져온 경우 AnimationClip은 CubismEyeBlinkController.eyeOpening의 값을 대상으로 커브를 생성합니다.
그 때문에, AnimationClip을 Animator 컴포넌트 등에서 재생하면 CubismEyeBlinkController.eyeOpening의 값이 조작됩니다.

컴포넌트로 값 조작

Cubism SDK for Cocos Creator에서는 CubismAutoEyeBlinkInput 컴포넌트를 사용하여 눈 깜빡임용 값을 조작할 수도 있습니다.

CubismAutoEyeBlinkInput은 Inspector에서 설정한 속도나 간격, 간격에 가하는 랜덤한 흔들림의 폭으로부터 눈 깜빡임용 값을 산출해 설정합니다.

protected lateUpdate(dt: number): void {
  // Fail silently.
  if (this.controller == null) {
    return;
  }

  // Wait for time until blink.
  if (this.currentPhase == Phase.Idling) {
    this.t -= dt;

    if (this.t < 0) {
      this.t = Math.PI * -0.5;
      this.lastValue = 1;
      this.currentPhase = Phase.ClosingEyes;
    } else {
      return;
    }
  }

  // Evaluate eye blinking.
  this.t += dt * this.timescale;
  let value = Math.abs(Math.sin(this.t));

  if (this.currentPhase == Phase.ClosingEyes && value > this.lastValue) {
    this.currentPhase = Phase.OpeningEyes;
  } else if (this.currentPhase == Phase.OpeningEyes && value < this.lastValue) {
    value = 1;
    this.currentPhase = Phase.Idling;
    const range = this.maximumDeviation * 2;
    this.t = this.mean + random() * range - this.maximumDeviation;
  }

  this.controller.eyeOpening = value;
  this.lastValue = value;
}

CubismAutoEyeBlinkInput에는 세 가지 설정 항목이 있습니다.

  • mean
  • maximumDeviation
  • timescale
/** Mean time between eye blinks in seconds. */
@property({ type: CCFloat, serializable: true, range: [1.0, 10.0, 0.001] })
public mean: number = 2.5;

/** Maximum deviation from {@link mean} in seconds. */
@property({ type: CCFloat, serializable: true, range: [0.5, 5.0, 0.001] })
public maximumDeviation: number = 2.0;

/** Timescale. */
@property({ type: CCFloat, serializable: true, range: [1.0, 20.0, 0.001] })
public timescale: number = 10.0;
  • mean
    눈 깜빡임까지의 시간을 설정합니다.

    단위는 초입니다.

    실제로는 이 값에 Maximum Deviation에 의한 오차를 더한 시간이 사용됩니다.
  • maximumDeviation
    Mean에 설정한 시간에 추가하는 임의의 흔들림 폭을 설정합니다.

    이들은 다음과 같이 값을 계산합니다.
const range = this.maximumDeviation * 2;
this.t = this.mean + random() * range - this.maximumDeviation;
  • timescale
    눈 깜빡임 속도입니다.

    이전 프레임으로부터의 경과 시간에 곱해집니다.
이 기사가 도움이 되었나요?
아니요
이 기사에 관한 의견 및 요청사항을 보내 주시기 바랍니다.