EyeBlink
最終更新: 2020年1月30日
概要
EyeBlinkは、まばたき用パラメータの現在の値に対して開閉状態の値を適用する機能です。
モデルにまばたきのパラメータを設定する方法については こちら をご覧ください。
まばたき用のパラメータの指定は、モデル自体に設定しておく他、Unity上でユーザが任意に指定することができます。
Cubism SDK for Unity におけるEyeBlinkは3種類の要素によって構成されています。
- パラメータ指定用のコンポーネント
- 各パラメータに値を適用するコンポーネント
- 2で適用する値の操作
1. パラメータ指定用のコンポーネント
EyeBlinkに使用するパラメータを指定するには、CubismEyeBlinkParameterを使用します。
CubismEyeBlinkParameterはMonoBehaviourを継承したコンポーネントで、
[Prefabのルート]/Parameters/ 以下に配置されたGameObjectにアタッチして使用します。
これがアタッチされたGameObjectと同じIDのパラメータをまばたき用のパラメータとして扱います。
モデル自体にまばたき用のパラメータが設定されている場合、インポートの際にそのパラメータのGameObjectにCubismEyeBlinkParameterがアタッチされます。
CubismEyeBlinkParameterは参照先を取得するためのマーカーとして使用しているので、内部では何も処理を行っておらず、データも持っていません。
2. 各パラメータに値を適用するコンポーネント
各パラメータに開閉の値を適用するには、CubismEyeBlinkControllerを使用します。
これはMonoBehaviourを継承したコンポーネントで、使用する際はCubismのPrefabのルートにアタッチします。
初期化時に、PrefabにアタッチされたすべてのCubismEyeBlinkParameterの参照を取得します。
実行中にまばたき用のパラメータを追加/削除した場合、CubismEyeBlinkController.Refresh()を呼んで参照を取得し直します。
/// <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は、毎フレームのLateUpdate()のタイミングで、CubismEyeBlinkParameterでマーキングされたパラメータに対してCubismEyeBlinkController.EyeOpeningの値を適用します。
// Apply value.
Destinations.BlendToValue(BlendMode, EyeOpening);
EyeOpeningに設定する値は0.0f~1.0fの範囲です。
CubismEyeBlinkControllerはこの値を対象のパラメータに対して、CubismEyeBlinkController.BlendModeで設定された計算方式で適用します。
このEyeOpeningの値を外から操作することで、モデルの目を開閉させることができます。
/// <summary>
/// Opening of the eyes.
/// </summary>
[SerializeField, Range(0f, 1f)]
public float EyeOpening = 1f;
3. 2で適用する値の操作
「2. 各パラメータに値を適用するコンポーネント」で説明した通り、CubismEyeBlinkController.EyeOpeningの値を操作することで、まばたき用のパラメータに値を適用できます。
Cubism SDK for Unity には、以下の2種類の方法でこの値を操作することができます。
- モーションによって値を操作
- コンポーネントによって値を操作
また、ユーザ側でこの値を操作する処理を実装していただくことで、まばたきの速度やタイミング等を独自にカスタマイズすることができます。
Tips
CubismEyeBlinkController.EyeOpeningを操作するコンポーネントの実行順がCubismEyeBlinkControllerよりも後である場合、意図した動作にならない可能性があります。
もし動作に問題が生じた、ユーザ側で明示的にコンポーネントの実行順を制御することで回避が可能です。
Cubism SDK for Unity では各コンポーネントの実行順をのCubismUpdateControllerで制御しているので、これを利用することもできます。
また、上記2種類の設定方法はそれぞれ異なるタイミングで同じ値を操作しているため、工夫無しで一つのモデルに両方を共存させることは難しくなっております。
モーションによって値を操作
まばたき用のパラメータを設定したモデルを使用してCubismのAnimatorでモーションを作成する場合、まばたき用のカーブを設定することが可能です。
まばたき用のカーブが設定された.motion3.jsonをUnityプロジェクトにインポートした場合、AnimationClipにはCubismEyeBlinkController.EyeOpeningの値を対象としてそのカーブが生成されます。
そのため、そのAnimationClipをAnimatorコンポーネントなどで再生することでCubismEyeBlinkController.EyeOpeningの値が操作されます。
コンポーネントによって値を操作
Cubism SDK for Unityでは、CubismAutoEyeBlinkInput コンポーネントによってもまばたき用の値を操作することができます。
CubismAutoEyeBlinkInputは、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には3つの設定項目があります。
- 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
まばたきを行うまでの時間を設定します。
単位は秒になります。
実際は、この値に Maximum Deviationによる誤差を足した時間が使われます。
- MaximumDeviation
Meanに設定した時間に加えるランダムな揺らぎの幅を設定します。
これらは以下のように値を計算されます。
Mean + Random.Range(-MaximumDeviation, MaximumDeviation)
- Timescale
まばたきを行う速度になります。
前フレームからの経過時間に対して乗算されます。