CubismSampleController.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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 Live2D.Cubism.Framework;
  9. using Live2D.Cubism.Framework.Expression;
  10. using Live2D.Cubism.Framework.Motion;
  11. using Live2D.Cubism.Framework.Raycasting;
  12. using System;
  13. using System.Collections.Generic;
  14. using UnityEngine;
  15. namespace Live2D.Cubism.Samples.OriginalWorkflow.Demo
  16. {
  17. [RequireComponent(typeof(CubismMotionController))]
  18. [RequireComponent(typeof(CubismRaycaster))]
  19. public class CubismSampleController : MonoBehaviour
  20. {
  21. /// <summary>
  22. /// MotionController to be operated.
  23. /// </summary>
  24. private CubismMotionController _motionController;
  25. /// <summary>
  26. /// ExpressionController to be operated.
  27. /// </summary>
  28. private CubismExpressionController _expressionController;
  29. /// <summary>
  30. /// Operation animation clip from the inspector.
  31. /// </summary>
  32. [SerializeField]
  33. private AnimationClip _bodyAnimation;
  34. /// <summary>
  35. /// Array of motion set in tapbody.
  36. /// </summary>
  37. [SerializeField]
  38. private AnimationClip[] _tapBodyMotions;
  39. /// <summary>
  40. /// Motion set in loop motion.
  41. /// </summary>
  42. private AnimationClip _loopMotion;
  43. /// <summary>
  44. /// List of Drawables info.
  45. /// </summary>
  46. private List<HitDrawableInfomation> _hasHitDrawables;
  47. /// <summary>
  48. /// Component that performs ray judgment on Drawables of model.
  49. /// </summary>
  50. private CubismRaycaster _raycaster;
  51. /// <summary>
  52. /// Raycast Hit Results.
  53. /// </summary>
  54. private CubismRaycastHit[] _raycastResults;
  55. /// <summary>
  56. /// Enumeration type for hit area discrimination.
  57. /// </summary>
  58. private enum HitArea
  59. {
  60. Head,
  61. Body
  62. }
  63. /// <summary>
  64. /// Structure that stores Drawable information for which hit area is specified.
  65. /// </summary>
  66. private struct HitDrawableInfomation
  67. {
  68. /// <summary>
  69. /// Drawable with component set.
  70. /// </summary>
  71. public CubismDrawable drawable;
  72. /// <summary>
  73. /// HitArea.
  74. /// </summary>
  75. public HitArea hitArea;
  76. }
  77. /// <summary>
  78. /// Load model.
  79. /// </summary>
  80. private void Start()
  81. {
  82. var model = this.FindCubismModel();
  83. // Get components.
  84. _motionController = model.GetComponent<CubismMotionController>();
  85. _expressionController = model.GetComponent<CubismExpressionController>();
  86. _raycaster = model.GetComponent<CubismRaycaster>();
  87. // Set behavior at the end of animation.
  88. _motionController.AnimationEndHandler = AnimationEnded;
  89. // Get up to 4 results of collision detection.
  90. _raycastResults = new CubismRaycastHit[4];
  91. // Cache the drawable in which the component is set.
  92. {
  93. _hasHitDrawables = new List<HitDrawableInfomation>();
  94. var hitAreas = Enum.GetValues(typeof(HitArea));
  95. var drawables = model.Drawables;
  96. for (var i = 0; i < hitAreas.Length; i++)
  97. {
  98. for (var j = 0; j < drawables.Length; j++)
  99. {
  100. var cubismHitDrawable = drawables[j].GetComponent<CubismHitDrawable>();
  101. if (cubismHitDrawable)
  102. {
  103. if (cubismHitDrawable.Name == hitAreas.GetValue(i).ToString())
  104. {
  105. var hitDrawable = new HitDrawableInfomation();
  106. hitDrawable.drawable = drawables[j];
  107. hitDrawable.hitArea = (HitArea)i;
  108. _hasHitDrawables.Add(hitDrawable);
  109. break;
  110. }
  111. }
  112. }
  113. }
  114. }
  115. }
  116. /// <summary>
  117. /// Update.
  118. /// </summary>
  119. private void Update()
  120. {
  121. // Play if animation is specified.
  122. SpecifiedAnimationCheck();
  123. if(!Input.GetMouseButtonDown(0))
  124. {
  125. if (!_motionController.IsPlayingAnimation())
  126. {
  127. Debug.Log("Body animation : Play : " + _loopMotion.name);
  128. _motionController.PlayAnimation(_loopMotion, priority: CubismMotionPriority.PriorityIdle);
  129. }
  130. return;
  131. }
  132. // Cast ray from pointer position.
  133. var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  134. var hitCount = _raycaster.Raycast(ray, _raycastResults);
  135. // Motion playback according to the hit location.
  136. for (var i = 0; i < hitCount; i++)
  137. {
  138. var hitDrawable = _raycastResults[i].Drawable;
  139. for (var j = 0; j < _hasHitDrawables.Count; j++)
  140. {
  141. if (hitDrawable == _hasHitDrawables[j].drawable)
  142. {
  143. var hitArea = _hasHitDrawables[j].hitArea;
  144. // Tap body.
  145. if (hitArea == HitArea.Body)
  146. {
  147. // Decide motion to play at random.
  148. var motionIndex = UnityEngine.Random.Range(0, _tapBodyMotions.Length);
  149. Debug.Log("Tap body : Play : " + _tapBodyMotions[motionIndex].name);
  150. _motionController.PlayAnimation(_tapBodyMotions[motionIndex], isLoop: false, priority:CubismMotionPriority.PriorityNormal);
  151. }
  152. // Tap head.
  153. else if (hitArea == HitArea.Head)
  154. {
  155. // Decide expression motion to play at random.
  156. var expressionNum = _expressionController.ExpressionsList.CubismExpressionObjects.Length;
  157. var expressionIndex = UnityEngine.Random.Range(0, expressionNum);
  158. _expressionController.CurrentExpressionIndex = expressionIndex;
  159. Debug.Log("Tap head : Play : " + _expressionController.ExpressionsList.CubismExpressionObjects[expressionIndex].name);
  160. }
  161. break;
  162. }
  163. }
  164. }
  165. }
  166. /// <summary>
  167. /// Check the specified animation and play it.
  168. /// </summary>
  169. private void SpecifiedAnimationCheck()
  170. {
  171. if(_bodyAnimation != _loopMotion)
  172. {
  173. _loopMotion = _bodyAnimation;
  174. Debug.Log("Body animation : Play : " + _loopMotion.name);
  175. _motionController.PlayAnimation(_loopMotion, priority:CubismMotionPriority.PriorityIdle);
  176. }
  177. }
  178. /// <summary>
  179. /// Called at the end of the animation.
  180. /// </summary>
  181. /// <param name="instanceId"></param>
  182. private void AnimationEnded(int instanceId)
  183. {
  184. Debug.Log("AnimationEnded");
  185. }
  186. }
  187. }