EyeBlink (Cocos Creator)
Updated: 03/14/2023
Summary
EyeBlink is a function that applies an open/close state value to the current value of the parameter for eye blinking.
Click here for information on how to set eye blink parameters for your model.
The parameters for eye blinking can be set in the model itself or specified as desired by the user in Cocos Creator.
EyeBlink in the Cubism SDK for Cocos Creator consists of three types of elements.
- Components for specifying parameters
- Components that apply values to each parameter
- Manipulation of the values applied in number 2
1. Components for Specifying Parameters
Use CubismEyeBlinkParameter to specify the parameters to be used for EyeBlink.
CubismEyeBlinkParameter is a component that inherits from Component and attaches to the GameObject placed under [Prefab root]/Parameters/.
The parameter with the same ID as the GameObject to which it is attached is treated as the parameter for eye blinking.
If the model itself has parameters for eye blinking, the CubismEyeBlinkParameter will be attached to the GameObject for that parameter during import.
CubismEyeBlinkParameter is used as a marker to get a reference, so it does not process anything internally and has no data.
2. Components that Apply Values to Each Parameter
Use CubismEyeBlinkController to apply opening and closing values to each parameter.
This is a component that inherits from Component and attaches to the root of Cubism’s Prefab when used.
It gets a reference to all CubismEyeBlinkParameters attached to the Prefab at initialization.
If you add/remove parameters for eye blinking during execution, call CubismEyeBlinkController.refresh() to get the reference again.
/** 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 applies the value of CubismEyeBlinkController.eyeOpening to the parameters marked by CubismEyeBlinkParameter at the timing of onLateUpdate() in every frame.
// Apply value. CubismParameterExtensionMethods.blendToValueArray( this.destinations, this.blendMode, this.eyeOpening );
The value set for EyeOpening ranges from 0.0f to 1.0f.
CubismEyeBlinkController applies this value to the target parameter using the calculation method set in CubismEyeBlinkController.blendMode.
By manipulating this EyeOpening value from the outside, the model’s eyes can be opened and closed.
/** Opening of the eyes. */ @property({ type: CCFloat, visible: true, serializable: true, range: [0.0, 1.0, 0.01] }) public eyeOpening: number = 1.0;
3. Manipulation of the Values Applied in Number 2
As described in “2. Components that Apply Values to Each Parameter,” values can be applied to the parameters for eye blinking by manipulating the values of CubismEyeBlinkController.eyeOpening.
Cubism SDK for Cocos Creator provides the following two ways to manipulate this value.
- Manipulate values by motion
- Manipulate values by component
You can also customize your own eye blinking speed and timing by implementing a process to manipulate this value.
TIPS
It may not work as intended if the order of execution of the components operating CubismEyeBlinkController.eyeOpening is later than CubismEyeBlinkController.
If a problem arises, it is possible to work around it by explicitly controlling the order in which components are executed on the user side.
Cubism SDK for Cocos Creator controls the execution order of each component with CubismUpdateController, which can also be used.
In addition, since the above two setting methods manipulate the same value at different times, it is difficult for both to coexist in a single model without an innovative solution.
Manipulate values by motion
When creating motion in Cubism’s Animator using a model with parameters set for eye blinking, it is possible to set a curve for eye blinking.
If a .motion3.json with a curve set for eye blinking is imported into a project, the AnimationClip will have that curve generated for the CubismEyeBlinkController.eyeOpening value.
Therefore, the value of CubismEyeBlinkController.eyeOpening is manipulated by playing that AnimationClip in the Animator component, etc.
Manipulate values by component
In the Cubism SDK for Cocos Creator, the CubismAutoEyeBlinkInput component can also manipulate values for eye blinking.
CubismAutoEyeBlinkInput calculates and sets the value for eye blinking from the speed, interval, and random fluctuation width added to the interval set from the 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 has three settings.
- 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
Sets the time until eye blinking is performed.
The unit is seconds.
In practice, the time is calculated by adding the error due toMaximum Deviation to this value. - maximumDeviation
Sets the width of the random fluctuation to be added to the time set for Mean.
These are calculated as follows.
const range = this.maximumDeviation * 2; this.t = this.mean + random() * range - this.maximumDeviation;
- timescale
This is the speed of eye blinking.
It is multiplied by the elapsed time from the previous frame.