CubismAutoEyeBlinkInput.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /**
  2. * Copyright(c) Live2D Inc. All rights reserved.
  3. *
  4. * Use of this source code is governed by the Live2D Open Software license
  5. * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
  6. */
  7. using UnityEngine;
  8. namespace Live2D.Cubism.Framework
  9. {
  10. /// <summary>
  11. /// Automatic mouth movement.
  12. /// </summary>
  13. public sealed class CubismAutoEyeBlinkInput : MonoBehaviour
  14. {
  15. /// <summary>
  16. /// Mean time between eye blinks in seconds.
  17. /// </summary>
  18. [SerializeField, Range(1f, 10f)]
  19. public float Mean = 2.5f;
  20. /// <summary>
  21. /// Maximum deviation from <see cref="Mean"/> in seconds.
  22. /// </summary>
  23. [SerializeField, Range(0.5f, 5f)]
  24. public float MaximumDeviation = 2f;
  25. /// <summary>
  26. /// Timescale.
  27. /// </summary>
  28. [SerializeField, Range(1f, 20f)]
  29. public float Timescale = 10f;
  30. /// <summary>
  31. /// Target controller.
  32. /// </summary>
  33. private CubismEyeBlinkController Controller { get; set; }
  34. /// <summary>
  35. /// Time until next eye blink.
  36. /// </summary>
  37. private float T { get; set; }
  38. /// <summary>
  39. /// Control over whether output should be evaluated.
  40. /// </summary>
  41. private Phase CurrentPhase { get; set; }
  42. /// <summary>
  43. /// Used for switching from <see cref="Phase.ClosingEyes"/> to <see cref="Phase.OpeningEyes"/> and back to <see cref="Phase.Idling"/>.
  44. /// </summary>
  45. private float LastValue { get; set; }
  46. /// <summary>
  47. /// Resets the input.
  48. /// </summary>
  49. public void Reset()
  50. {
  51. T = 0f;
  52. }
  53. #region Unity Event Handling
  54. /// <summary>
  55. /// Called by Unity. Initializes input.
  56. /// </summary>
  57. private void Start()
  58. {
  59. Controller = GetComponent<CubismEyeBlinkController>();
  60. }
  61. /// <summary>
  62. /// Called by Unity. Updates controller.
  63. /// </summary>
  64. /// <remarks>
  65. /// Make sure this method is called after any animations are evaluated.
  66. /// </remarks>
  67. private void LateUpdate()
  68. {
  69. // Fail silently.
  70. if (Controller == null)
  71. {
  72. return;
  73. }
  74. // Wait for time until blink.
  75. if (CurrentPhase == Phase.Idling)
  76. {
  77. T -= Time.deltaTime;
  78. if (T < 0f)
  79. {
  80. T = (Mathf.PI * -0.5f);
  81. LastValue = 1f;
  82. CurrentPhase = Phase.ClosingEyes;
  83. }
  84. else
  85. {
  86. return;
  87. }
  88. }
  89. // Evaluate eye blinking.
  90. T += (Time.deltaTime * Timescale);
  91. var value = Mathf.Abs(Mathf.Sin(T));
  92. if (CurrentPhase == Phase.ClosingEyes && value > LastValue)
  93. {
  94. CurrentPhase = Phase.OpeningEyes;
  95. }
  96. else if (CurrentPhase == Phase.OpeningEyes && value < LastValue)
  97. {
  98. value = 1f;
  99. CurrentPhase = Phase.Idling;
  100. T = Mean + Random.Range(-MaximumDeviation, MaximumDeviation);
  101. }
  102. Controller.EyeOpening = value;
  103. LastValue = value;
  104. }
  105. #endregion
  106. /// <summary>
  107. /// Internal states.
  108. /// </summary>
  109. private enum Phase
  110. {
  111. /// <summary>
  112. /// Idle state.
  113. /// </summary>
  114. Idling,
  115. /// <summary>
  116. /// State when closing eyes.
  117. /// </summary>
  118. ClosingEyes,
  119. /// <summary>
  120. /// State when opening eyes.
  121. /// </summary>
  122. OpeningEyes
  123. }
  124. }
  125. }