HarmonicMotion (Cocos Creator)
업데이트: 2023/03/14
개요
HarmonicMotion은 지정된 파라미터의 값을 주기적으로 반복하는 기능입니다.
주로 호흡처럼 항상 계속 동작하는 것에 사용합니다.
HarmonicMotion을 설정하는 방법은 여기를 참조하십시오.
Cubism SDK for Cocos Creator의 HarmonicMotion은 두 가지 요소로 구성됩니다.
- 동작시키는 파라미터 지정용 컴포넌트
- 각 파라미터의 값을 조작하는 컴포넌트
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에는 두 가지 설정 항목이 있습니다.
/** 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
사인파의 주기를 설정합니다.
주기는 복수 설정할 수 있습니다.