HarmonicMotion (Cocos Creator)
最終更新: 2023年3月14日
概述
HarmonicMotion是一种定期重复指定参数值的功能。
它主要用于呼吸等不断动作的事物。
单击此处了解如何设置HarmonicMotion。
Cubism SDK for Cocos Creator中的HarmonicMotion包含两个元素。
- 用于指定要动作的参数的组件
- 操作各参数值的组件
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
设置正弦波的周期。
您可以设置多个周期。