HarmonicMotion (Cocos Creator)

最終更新: 2023年3月14日

概述

HarmonicMotion是一种定期重复指定参数值的功能。
它主要用于呼吸等不断动作的事物。
单击此处了解如何设置HarmonicMotion。

Cubism SDK for Cocos Creator中的HarmonicMotion包含两个元素。

  1. 用于指定要动作的参数的组件
  2. 操作各参数值的组件

1. 用于指定要动作的参数的组件

使用CubismHarmonicMotionParameter指定用于HarmonicMotion的参数。

CubismHarmonicMotionParameter是一个继承Component的组件,
它通过附加到置入[Prefab根]/Parameters/下的Node来使用。
这将使与附加Node具有相同ID的参数值定期动作。

CubismHarmonicMotionParameter有5个设置项目。

  /** Timescale channel. */
  @property({ type: CCInteger, serializable: true, visible: true })
  public channel: number = 0;

  /** Motion direction. */
  @property({ type: Enum(CubismHarmonicMotionDirection), serializable: true, visible: true })
  public direction: CubismHarmonicMotionDirection = CubismHarmonicMotionDirection.Left;

  /**
   * Normalized origin of motion.
   * The actual origin used for evaluating the motion depends limits of the {@link CubismParameter}.
   */
  @property({ type: CCFloat, slide: true, range: [0.0, 1.0, 0.01], serializable: true, visible: true, })
  public normalizedOrigin: number = 0.5;

  /**
   * Normalized range of motion.
   * The actual origin used for evaluating the motion depends limits of the {@link CubismParameter}.
   */
  @property({ type: CCFloat, slide: true, range: [0.0, 1.0, 0.01], serializable: true, visible: true, })
  public normalizedRange: number = 0.5;

  /** Duration of one motion cycle in seconds. */
  @property({ type: CCFloat, slide: true, range: [0.01, 10.0, 0.01], serializable: true, visible: true, })
  public duration: number = 3.0;
  • channel

    指定在CubismHarmonicMotionController中设置的正弦波周期的倍率。

    在HarmonicMotion中,您可以为一个模型设置多个周期,且可以在CubismHarmonicMotionController中设置它们。

    在此处设置CubismHarmonicMotionController.channelTimescales的索引。
  • direction

    以参数的中心为基准,设置周期动作的范围。

    有以下三个设置项目。
  • Left:它仅在参数中心的左半部分动作。
  • Right:它仅在参数中心的右半部分动作。
  • Centric:它在参数全体动作。
  • normalizedOrigin

    在direction中设置要用作基准的参数中心。

    以该参数最小值为0、最大值为1时的值为中心进行设置。
  • normalizedRange

    设置使值从normalizedOrigin中设置的值的中心动作的幅度。

    设置该参数最小值为0、最大值为1时,从中心移动的距离。

    该值只能设置在normalizedOrigin设置的中心位置到参数的最小值或最大值的范围内。
  • duration

    调整参数周期。
  /** Evaluates the parameter. */
  public evaluate(): number {
    // Lazily initialize.
    if (!this.isInitialized) {
      this.initialize();
    }

    // Restore origin and range.
    let origin = this.minimumValue + this.normalizedOrigin * this.valueRange;
    let range = this.normalizedRange * this.valueRange;

    // Clamp the range so that it stays within the limits.
    const outputArray = this.clamp(origin, range);

    const originIndex = 0;
    const rangeIndex = 1;
    origin = outputArray[originIndex];
    range = outputArray[rangeIndex];

    // Return result.
    return origin + range * Math.sin((this.t * (2 * Math.PI)) / this.duration);
  }

  /**
   * Clamp origin and range based on {@link direction}.
   * @param origin Origin to clamp.
   * @param range Range to clamp.
   * @returns
   */
  private clamp(origin: number, range: number): [number, number] {
    switch (this.direction) {
      case CubismHarmonicMotionDirection.Left: {
        if (origin - range >= this.minimumValue) {
          range /= 2;
          origin -= range;
        } else {
          range = (origin - this.minimumValue) / 2.0;
          origin = this.minimumValue + range;
          this.normalizedRange = (range * 2.0) / this.valueRange;
        }
        break;
      }
      case CubismHarmonicMotionDirection.Right: {
        if (origin + range <= this.maximumValue) {
          range /= 2.0;
          origin += range;
        } else {
          range = (this.maximumValue - origin) / 2.0;
          origin = this.maximumValue - range;
          this.normalizedRange = (range * 2.0) / this.valueRange;
        }
        break;
      }
      case CubismHarmonicMotionDirection.Centric:
        break;
      default: {
        const neverCheck: never = this.direction;
        break;
      }
    }

    // Clamp both range and NormalizedRange.
    if (origin - range < this.minimumValue) {
      range = origin - this.minimumValue;
      this.normalizedRange = range / this.valueRange;
    } else if (origin + range > this.maximumValue) {
      range = this.maximumValue - origin;
      this.normalizedRange = range / this.valueRange;
    }

    return [origin, range];
  }

此外,CubismHarmonicMotionParameter也被用作CubismHarmonicMotionController获取参考目标的标记。

2. 操作各参数值的组件

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

获取在原始化时附加到Prefab的所有CubismHarmonicMotionParameter的参考。
如果在执行过程中追加/删除周期性运行值的参数,将调用CubismHarmonicMotionController.refresh()再次获取参考。

  /** Refreshes the controller. Call this method after adding and/or removing {@link CubismHarmonicMotionParameter}. */
  public refresh() {
    const model = CoreComponentExtensionMethods.findCubismModel(this);

    if (model == null || model.parameters == null) {
      return;
    }

    // Catch sources and destinations.
    this.sources = FrameworkComponentExtensionMethods.getComponentsMany(
      model.parameters,
      CubismHarmonicMotionParameter
    );
    this.destinations = new Array<CubismParameter>(this.sources.length);

    for (let i = 0; i < this.sources.length; ++i) {
      this.destinations[i] = this.sources[i].getComponent(CubismParameter);
    }

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

  ...

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

CubismHarmonicMotionController在每帧的lateUpdate()时,应用为CubismHarmonicMotionParameter标记的参数计算的值。

  /** Called by cubism update controller. Updates controller. */
  protected onLateUpdate(deltaTime: number) {
    // Return if it is not valid or there's nothing to update.
    if (!this.enabled || this.sources == null) {
      return;
    }

    // Update sources and destinations.
    for (let i = 0; i < this.sources.length; ++i) {
      this.sources[i].play(this.channelTimescales);

      CubismParameterExtensionMethods.blendToValue(
        this.destinations[i],
        this.blendMode,
        this.sources[i].evaluate()
      );
    }
  }

  ...

  /** Called by Cocos Creator. Updates controller. */
  protected lateUpdate(deltaTime: number) {
    if (!this.hasUpdateController) {
      this.onLateUpdate(deltaTime);
    }
  }

CubismHarmonicMotionController有两个设置项目。

  /** Blend mode. */
  @property({ type: Enum(CubismParameterBlendMode), serializable: true, visible: true })
  public blendMode: CubismParameterBlendMode = CubismParameterBlendMode.Additive;

  /** The timescales for each channel. */
  @property({ type: [CCFloat], serializable: true, visible: true })
  public channelTimescales: number[] = [];
  • blendMode

    用于将值应用于到参数的混合模式。

    可以设置以下三个值。
    • Override:覆盖当前值。
    • Additive:加算到当前值。
    • Multiply:正片叠底当前值。
  • channelTimescales

    设置正弦波的周期。
    您可以设置多个周期。
请问这篇文章对您有帮助吗?
关于本报道,敬请提出您的意见及要求。