EyeBlink

Updated: 01/30/2020

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 Unity.

EyeBlink in Cubism SDK for Unity consists of three types of elements.

  1. Components for specifying parameters
  2. Components that apply values to each parameter
  3. 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 MonoBehaviour and attaches to GameObjects 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 MonoBehaviour 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.

        /// <summary>
        /// Refreshes controller. Call this method after adding and/or removing <see cref="CubismEyeBlinkParameter"/>s.
        /// </summary>
        public void Refresh()
        {
            var model = this.FindCubismModel();
 
 
            // Fail silently...
            if (model == null)
            {
                return;
            }
 
 
            // Cache destinations.
            var tags = model
                .Parameters
                .GetComponentsMany<CubismEyeBlinkParameter>();
 
 
            Destinations = new CubismParameter[tags.Length];
 
 
            for (var i = 0; i < tags.Length; ++i)
            {
                Destinations[i] = tags[i].GetComponent<CubismParameter>();
            }
 
            // Get cubism update controller.
            HasUpdateController = (GetComponent<CubismUpdateController>() != null);
        }
        
        
        ...
        
        
        /// <summary>
        /// Called by Unity. Makes sure cache is initialized.
        /// </summary>
        private void Start()
        {
            // Initialize cache.
            Refresh();
        }

CubismEyeBlinkController applies the value of CubismEyeBlinkController.EyeOpening to the parameters marked by CubismEyeBlinkParameter at the timing of LateUpdate() in every frame.

            // Apply value.
            Destinations.BlendToValue(BlendMode, 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.

        /// <summary>
        /// Opening of the eyes.
        /// </summary>
        [SerializeField, Range(0f, 1f)]
        public float EyeOpening = 1f;

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.
The Cubism SDK for Unity includes two different 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 Unity 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 Unity 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 Unity, 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.

       private void LateUpdate()
        {
            // Fail silently.
            if (Controller == null)
            {
                return;
            }
 
 
            // Wait for time until blink.
            if (CurrentPhase == Phase.Idling)
            {
                T -= Time.deltaTime;
 
 
                if (T < 0f)
                {
                    T = (Mathf.PI * -0.5f);
                    LastValue = 1f;
                    CurrentPhase = Phase.ClosingEyes;
                }
                else
                {
                    return;
                }
            }
 
 
            // Evaluate eye blinking.
            T += (Time.deltaTime * Timescale);
            var value = Mathf.Abs(Mathf.Sin(T));
 
 
            if (CurrentPhase == Phase.ClosingEyes && value > LastValue)
            {
                CurrentPhase = Phase.OpeningEyes;
            }
            else if (CurrentPhase == Phase.OpeningEyes && value < LastValue)
            {
                value = 1f;
                CurrentPhase = Phase.Idling;
                T = Mean + Random.Range(-MaximumDeviation, MaximumDeviation);
            }
 
 
            Controller.EyeOpening = value;
            LastValue = value;
        }

CubismAutoEyeBlinkInput has three settings.

  • Mean
  • MaximumDeviation
  • Timescale
        /// <summary>
        /// Mean time between eye blinks in seconds.
        /// </summary>
        [SerializeField, Range(1f, 10f)]
        public float Mean = 2.5f;
 
        /// <summary>
        /// Maximum deviation from <see cref="Mean"/> in seconds.
        /// </summary>
        [SerializeField, Range(0.5f, 5f)]
        public float MaximumDeviation = 2f;
 
        /// <summary>
        /// Timescale.
        /// </summary>
        [SerializeField, Range(1f, 20f)]
        public float Timescale = 10f;
  • Mean

Sets the time until eye blinking is performed.
The unit is seconds.
In practice, the time is calculated by adding the error due to Maximum 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.

 Mean + Random.Range(-MaximumDeviation, MaximumDeviation)
  • Timescale

This is the speed of eye blinking.
It is multiplied by the elapsed time from the previous frame.

Please let us know what you think about this article.