EyeBlink (Cocos Creator)

最終更新: 2023年3月14日

概述

EyeBlink是将开/关值应用于眨眼参数的当前值的功能。
参考此处了解如何在模型上设置眨眼参数。

除了在模型本身中设置之外,用户还可以在Cocos Creator上任意指定眨眼参数。

Cubism SDK for Cocos Creator中的EyeBlink包含三种类型的元素。

  1. 参数指定用组件
  2. 将值应用于各参数的组件
  3. 操作2中应用的值

1. 参数指定用组件

使用CubismEyeBlinkParameter指定用于EyeBlink的参数。

CubismEyeBlinkParameter是一个继承Component的组件,它通过附加到置入[Prefab根]/Parameters/下的GameObject来使用。

这会将与附加的GameObject具有相同ID的参数视为眨眼的参数。

如果模型本身设置有眨眼参数,则CubismEyeBlinkParameter将在载入时附加到该参数的GameObject上。

由于CubismEyeBlinkParameter用作获取参考目的地的标记,因此它内部不处理任何内容,也没有数据。

2. 将值应用于各参数的组件

使用CubismEyeBlinkController将打开/关闭值应用于各参数。
这是一个继承自Component的组件,使用时会附加到Cubism的Prefab的根。

在原始化期间获取附加到Prefab的所有CubismEyeBlinkParameters的参考。
如果在执行过程中追加/删除眨眼参数,调用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()时机将CubismEyeBlinkController.eyeOpening的值应用于CubismEyeBlinkParameter标记的参数。

// 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控制,因此您也可以使用它。

另外,由于上述两种设置方法在不同的时间操作相同的值,因此很难在不作任何努力的情况下将两者共存于一个模型中。

通过动态操纵值

当使用设置有眨眼参数的模型通过Cubism的Animator创建动态时,可以设置眨眼曲线。

如果将带有眨眼曲线的.motion3.json载入项目,AnimationClip将以CubismEyeBlinkController.eyeOpening的值为对象生成该曲线。
因此,CubismEyeBlinkController.eyeOpening的值是通过以Animator组件等播放AnimationClip来操作的。

按组件操作值

在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
    这将是眨眼的速度。

    它针对从前一帧经过的时间进行正片叠底。
请问这篇文章对您有帮助吗?
关于本报道,敬请提出您的意见及要求。