HarmonicMotion (Cocos Creator)
最終更新: 2023年3月14日
概要
HarmonicMotionは、指定したパラメータの値を周期的に反復させる機能です。
主に呼吸のように常に動作し続けるものに対して使用します。
HarmonicMotionの設定方法については こちら をご覧ください。
Cubism SDK for Cocos CreatorにおけるHarmonicMotionは2つの要素によって構成されています。
- 動作させるパラメータ指定用のコンポーネント
- 各パラメータの値を操作するコンポーネント
1. 動作させるパラメータ指定用のコンポーネント
HarmonicMotionに使用するパラメータを指定するには、 CubismHarmonicMotionParameter を使用します。
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
パラメータの中心を基準に、どの範囲で周期的に動作させるかを設定します。
設定項目は以下の3つです。 - 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には、2つの設定項目があります。
/** 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
パラメータに値を適用する際のブレンドモードです。
設定できる値は以下の3つです。- Override : 現在の値を上書きします。
- Additive : 現在の値に加算します。
- Multiply : 現在の値に乗算します。
- channelTimescales
正弦波の周期を設定します。
周期は複数設定できます。