CubismHarmonicMotionController.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. namespace Live2D.Cubism.Framework.HarmonicMotion
  10. {
  11. /// <summary>
  12. /// Controller for <see cref="CubismHarmonicMotionParameter"/>s.
  13. /// </summary>
  14. public sealed class CubismHarmonicMotionController : MonoBehaviour, ICubismUpdatable
  15. {
  16. /// <summary>
  17. /// Default number of channels.
  18. /// </summary>
  19. private const int DefaultChannelCount = 1;
  20. /// <summary>
  21. /// Blend mode.
  22. /// </summary>
  23. [SerializeField]
  24. public CubismParameterBlendMode BlendMode = CubismParameterBlendMode.Additive;
  25. /// <summary>
  26. /// The timescales for each channel.
  27. /// </summary>
  28. [SerializeField]
  29. public float[] ChannelTimescales;
  30. /// <summary>
  31. /// Sources.
  32. /// </summary>
  33. private CubismHarmonicMotionParameter[] Sources { get; set; }
  34. /// <summary>
  35. /// Destinations.
  36. /// </summary>
  37. private CubismParameter[] Destinations { get; set; }
  38. /// <summary>
  39. /// Model has update controller component.
  40. /// </summary>
  41. [HideInInspector]
  42. public bool HasUpdateController { get; set; }
  43. /// <summary>
  44. /// Refreshes the controller. Call this method after adding and/or removing <see cref="CubismHarmonicMotionParameter"/>.
  45. /// </summary>
  46. public void Refresh()
  47. {
  48. var model = this.FindCubismModel();
  49. // Catch sources and destinations.
  50. Sources = model
  51. .Parameters
  52. .GetComponentsMany<CubismHarmonicMotionParameter>();
  53. Destinations = new CubismParameter[Sources.Length];
  54. for (var i = 0; i < Sources.Length; ++i)
  55. {
  56. Destinations[i] = Sources[i].GetComponent<CubismParameter>();
  57. }
  58. // Get cubism update controller.
  59. HasUpdateController = (GetComponent<CubismUpdateController>() != null);
  60. }
  61. /// <summary>
  62. /// Called by cubism update controller. Order to invoke OnLateUpdate.
  63. /// </summary>
  64. public int ExecutionOrder
  65. {
  66. get { return CubismUpdateExecutionOrder.CubismHarmonicMotionController; }
  67. }
  68. /// <summary>
  69. /// Called by cubism update controller. Needs to invoke OnLateUpdate on Editing.
  70. /// </summary>
  71. public bool NeedsUpdateOnEditing
  72. {
  73. get { return false; }
  74. }
  75. /// <summary>
  76. /// Called by cubism update controller. Updates controller.
  77. /// </summary>
  78. public void OnLateUpdate()
  79. {
  80. // Return if it is not valid or there's nothing to update.
  81. if (!enabled || Sources == null)
  82. {
  83. return;
  84. }
  85. // Update sources and destinations.
  86. for (var i = 0; i < Sources.Length; ++i)
  87. {
  88. Sources[i].Play(ChannelTimescales);
  89. Destinations[i].BlendToValue(BlendMode, Sources[i].Evaluate());
  90. }
  91. }
  92. #region Unity Events Handling
  93. /// <summary>
  94. /// Called by Unity. Makes sure cache is initialized.
  95. /// </summary>
  96. private void Start()
  97. {
  98. // Initialize cache.
  99. Refresh();
  100. }
  101. /// <summary>
  102. /// Called by Unity. Updates controller.
  103. /// </summary>
  104. private void LateUpdate()
  105. {
  106. if (!HasUpdateController)
  107. {
  108. OnLateUpdate();
  109. }
  110. }
  111. /// <summary>
  112. /// Called by Unity. Resets channels.
  113. /// </summary>
  114. private void Reset()
  115. {
  116. // Reset/Initialize channel timescales.
  117. ChannelTimescales = new float[DefaultChannelCount];
  118. for (var s = 0; s < DefaultChannelCount; ++s)
  119. {
  120. ChannelTimescales[s] = 1f;
  121. }
  122. }
  123. #endregion
  124. }
  125. }