CubismLookController.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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 Live2D.Cubism.Core;
  8. using UnityEngine;
  9. using Object = UnityEngine.Object;
  10. namespace Live2D.Cubism.Framework.LookAt
  11. {
  12. /// <summary>
  13. /// Controls <see cref="CubismLookParameter"/>s.
  14. /// </summary>
  15. public sealed class CubismLookController : MonoBehaviour, ICubismUpdatable
  16. {
  17. /// <summary>
  18. /// Blend mode.
  19. /// </summary>
  20. [SerializeField]
  21. public CubismParameterBlendMode BlendMode = CubismParameterBlendMode.Additive;
  22. /// <summary>
  23. /// <see cref="Target"/> backing field.
  24. /// </summary>
  25. [SerializeField, HideInInspector] private Object _target;
  26. /// <summary>
  27. /// Target.
  28. /// </summary>
  29. public Object Target
  30. {
  31. get { return _target; }
  32. set { _target = value.ToNullUnlessImplementsInterface<ICubismLookTarget>(); }
  33. }
  34. /// <summary>
  35. /// <see cref="TargetInterface"/> backing field.
  36. /// </summary>
  37. private ICubismLookTarget _targetInterface;
  38. /// <summary>
  39. /// Interface of target.
  40. /// </summary>
  41. private ICubismLookTarget TargetInterface
  42. {
  43. get
  44. {
  45. if (_targetInterface == null)
  46. {
  47. _targetInterface = Target.GetInterface<ICubismLookTarget>();
  48. }
  49. return _targetInterface;
  50. }
  51. }
  52. /// <summary>
  53. /// Local center position.
  54. /// </summary>
  55. public Transform Center;
  56. /// <summary>
  57. /// Damping to apply.
  58. /// </summary>
  59. public float Damping = 0.15f;
  60. /// <summary>
  61. /// Source parameters.
  62. /// </summary>
  63. private CubismLookParameter[] Sources { get; set; }
  64. /// <summary>
  65. /// The actual parameters to apply the source values to.
  66. /// </summary>
  67. private CubismParameter[] Destinations { get; set; }
  68. /// <summary>
  69. /// Position at last frame.
  70. /// </summary>
  71. private Vector3 LastPosition { get; set; }
  72. /// <summary>
  73. /// Goal position.
  74. /// </summary>
  75. private Vector3 GoalPosition { get; set; }
  76. /// <summary>
  77. /// Buffer for <see cref="Mathf.SmoothDamp(float, float, ref float, float)"/> velocity.
  78. /// </summary>
  79. // ReSharper disable once InconsistentNaming
  80. private Vector3 VelocityBuffer;
  81. /// <summary>
  82. /// Model has update controller component.
  83. /// </summary>
  84. [HideInInspector]
  85. public bool HasUpdateController { get; set; }
  86. /// <summary>
  87. /// Refreshes the controller. Call this method after adding and/or removing <see cref="CubismLookParameter"/>s.
  88. /// </summary>
  89. public void Refresh()
  90. {
  91. var model = this.FindCubismModel();
  92. // Catch sources and destinations.
  93. Sources = model
  94. .Parameters
  95. .GetComponentsMany<CubismLookParameter>();
  96. Destinations = new CubismParameter[Sources.Length];
  97. for (var i = 0; i < Sources.Length; ++i)
  98. {
  99. Destinations[i] = Sources[i].GetComponent<CubismParameter>();
  100. }
  101. // Get cubism update controller.
  102. HasUpdateController = (GetComponent<CubismUpdateController>() != null);
  103. }
  104. /// <summary>
  105. /// Called by cubism update controller. Order to invoke OnLateUpdate.
  106. /// </summary>
  107. public int ExecutionOrder
  108. {
  109. get { return CubismUpdateExecutionOrder.CubismLookController; }
  110. }
  111. /// <summary>
  112. /// Called by cubism update controller. Needs to invoke OnLateUpdate on Editing.
  113. /// </summary>
  114. public bool NeedsUpdateOnEditing
  115. {
  116. get { return false; }
  117. }
  118. /// <summary>
  119. /// Called by cubism update controller. Updates controller.
  120. /// </summary>
  121. public void OnLateUpdate()
  122. {
  123. // Return if it is not valid or there's nothing to update.
  124. if (!enabled || Destinations == null)
  125. {
  126. return;
  127. }
  128. // Return early if no target is available or if target is inactive.
  129. var target = TargetInterface;
  130. if (target == null || !target.IsActive())
  131. {
  132. return;
  133. }
  134. // Update position.
  135. var position = LastPosition;
  136. GoalPosition = transform.InverseTransformPoint(target.GetPosition()) - Center.localPosition;
  137. if (position != GoalPosition)
  138. {
  139. position = Vector3.SmoothDamp(
  140. position,
  141. GoalPosition,
  142. ref VelocityBuffer,
  143. Damping);
  144. }
  145. // Update sources and destinations.
  146. for (var i = 0; i < Destinations.Length; ++i)
  147. {
  148. Destinations[i].BlendToValue(BlendMode, Sources[i].TickAndEvaluate(position));
  149. }
  150. // Store position.
  151. LastPosition = position;
  152. }
  153. #region Unity Events Handling
  154. /// <summary>
  155. /// Called by Unity. Makes sure cache is initialized.
  156. /// </summary>
  157. private void Start()
  158. {
  159. // Default center if necessary.
  160. if (Center == null)
  161. {
  162. Center = transform;
  163. }
  164. // Initialize cache.
  165. Refresh();
  166. }
  167. /// <summary>
  168. /// Called by Unity. Updates controller.
  169. /// </summary>
  170. private void LateUpdate()
  171. {
  172. if (!HasUpdateController)
  173. {
  174. OnLateUpdate();
  175. }
  176. }
  177. #endregion
  178. }
  179. }