AnimatorController.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Serialization;
  5. using Quaternion = System.Numerics.Quaternion;
  6. public class AnimatorController : MonoBehaviour
  7. {
  8. [Header("Input")]
  9. public float speed;
  10. public bool jump;
  11. [Header("Player")]
  12. public float walkSpeed = 2.0f;
  13. public float runSpeed = 6.0f;
  14. [Range(0f,1f)]
  15. public float freeLookRange;
  16. public Transform head;
  17. public Transform lookAtTarget;
  18. public Camera playerCamera;
  19. [Space(10)]
  20. [Header("Jump")]
  21. //滞空后开始下落动画时间
  22. public float FallTimeout = 0.15f;
  23. //判断是否接地
  24. [Header("Player Grounded")]
  25. public LayerMask groundLayers;
  26. public float groundedOffset = -0.14f;
  27. public float groundedRadius = 0.28f;
  28. public bool grounded = true;
  29. //脚步声
  30. public AudioClip landingAudioClip;
  31. public AudioClip[] footstepAudioClips;
  32. [Range(0, 1)] public float footstepAudioVolume = 0.5f;
  33. private Animator _animator;
  34. private bool _hasAnimator;
  35. // animation IDs
  36. private int _animIDSpeed;
  37. private int _animIDGrounded;
  38. private int _animIDJump;
  39. private int _animIDFreeFall;
  40. // 滞空时间
  41. private float _fallTimeoutTimer;
  42. void Start()
  43. {
  44. _animIDSpeed = Animator.StringToHash("Speed");
  45. _animIDGrounded = Animator.StringToHash("Grounded");
  46. _animIDJump = Animator.StringToHash("Jump");
  47. _animIDFreeFall = Animator.StringToHash("FreeFall");
  48. _hasAnimator = TryGetComponent(out _animator);
  49. if(playerCamera==null) playerCamera=Camera.main;
  50. }
  51. // Update is called once per frame
  52. void FixedUpdate()
  53. {
  54. JumpAndGravity();
  55. GroundedCheck();
  56. Move();
  57. LookAtTarget();
  58. }
  59. private void JumpAndGravity()
  60. {
  61. if (grounded)
  62. {
  63. // 重置滞空时间
  64. _fallTimeoutTimer = FallTimeout;
  65. // 动画设为非空中状态
  66. if (_hasAnimator )
  67. {
  68. _animator.SetBool(_animIDJump, false);
  69. _animator.SetBool(_animIDFreeFall, false);
  70. }
  71. // 满足条件开始跳跃
  72. Debug.Log(jump + "*********" + _hasAnimator);
  73. if (jump)
  74. {
  75. if (_hasAnimator)
  76. {
  77. _animator.SetBool(_animIDJump, true);
  78. }
  79. }
  80. jump = false;
  81. }
  82. else
  83. {
  84. // 计算滞空时间
  85. if (_fallTimeoutTimer >= 0.0f)
  86. {
  87. _fallTimeoutTimer -= Time.deltaTime;
  88. }
  89. else
  90. {
  91. // 滞空结束,开始播放下落动画
  92. if (_hasAnimator)
  93. {
  94. _animator.SetBool(_animIDFreeFall, true);
  95. }
  96. }
  97. jump = false;
  98. }
  99. }
  100. // 检查指定位置的球体与地面接触,判断是否接地
  101. private void GroundedCheck()
  102. {
  103. Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - groundedOffset, transform.position.z);
  104. grounded = Physics.CheckSphere(spherePosition, groundedRadius, groundLayers, QueryTriggerInteraction.Ignore);
  105. if (_hasAnimator)
  106. {
  107. _animator.SetBool(_animIDGrounded, grounded);
  108. }
  109. }
  110. private void Move()
  111. {
  112. float animSpeed=0f;
  113. if (_hasAnimator)
  114. {
  115. if (speed >= 0 && speed <= walkSpeed)
  116. {
  117. animSpeed = RemapNum(speed, 0f, walkSpeed, 0f, 2f);
  118. }
  119. if (speed >walkSpeed)
  120. {
  121. speed = Mathf.Clamp(speed, 0f, 6.0f);
  122. animSpeed = RemapNum(speed, walkSpeed, runSpeed, 2f, 6f);
  123. }
  124. _animator.SetFloat(_animIDSpeed, animSpeed);
  125. }
  126. }
  127. private void LookAtTarget()
  128. {
  129. Vector3 cameraForward = playerCamera.transform.forward;
  130. if (Vector3.Dot(cameraForward, head.forward) < freeLookRange)
  131. {
  132. lookAtTarget.position = Vector3.Lerp(lookAtTarget.position ,head.position + head.forward,0.1f);
  133. }
  134. else
  135. {
  136. lookAtTarget.position =Vector3.Lerp(lookAtTarget.position ,head.position + cameraForward,0.1f);
  137. }
  138. }
  139. private float RemapNum(float input, float oldMin, float oldMax, float newMin, float newMax)
  140. {
  141. float result = (newMax - newMin) / (oldMax - oldMin) * (input - oldMin) + newMin;
  142. return result;
  143. }
  144. //球体与地面接触判断触地可视
  145. private void OnDrawGizmosSelected()
  146. {
  147. Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
  148. Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
  149. if (grounded) Gizmos.color = transparentGreen;
  150. else Gizmos.color = transparentRed;
  151. // when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
  152. Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - groundedOffset, transform.position.z), groundedRadius);
  153. }
  154. private void OnFootstep(AnimationEvent animationEvent)
  155. {
  156. if (animationEvent.animatorClipInfo.weight > 0.5f)
  157. {
  158. if (footstepAudioClips.Length > 0)
  159. {
  160. var index = Random.Range(0, footstepAudioClips.Length);
  161. AudioSource.PlayClipAtPoint(footstepAudioClips[index], transform.transform.position, footstepAudioVolume);
  162. }
  163. }
  164. }
  165. private void OnLand(AnimationEvent animationEvent)
  166. {
  167. if (animationEvent.animatorClipInfo.weight > 0.5f)
  168. {
  169. AudioSource.PlayClipAtPoint(landingAudioClip, transform.position, footstepAudioVolume);
  170. }
  171. }
  172. }