123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- using UnityEngine;
- public class AnimatorController : MonoBehaviour
- {
- [Header("Input")]
- public float speed;
- public bool jump;
- [Header("Player")]
- public float walkSpeed = 2.0f;
- public float runSpeed = 6.0f;
- [Range(0f, 1f)]
- public float freeLookRange;
- public Transform head;
- public Transform lookAtTarget;
- public Camera playerCamera;
- [Space(10)]
- [Header("Jump")]
- //滞空后开始下落动画时间
- public float FallTimeout = 0.15f;
- //判断是否接地
- [Header("Player Grounded")]
- public LayerMask groundLayers;
- public float groundedOffset = -0.14f;
- public float groundedRadius = 0.28f;
- public bool grounded = true;
- //脚步声
- public AudioClip landingAudioClip;
- public AudioClip[] footstepAudioClips;
- [Range(0, 1)]
- public float footstepAudioVolume = 0.5f;
- private Animator _animator;
- private bool _hasAnimator;
- // animation IDs
- private int _animIDSpeed;
- private int _animIDGrounded;
- private int _animIDJump;
- private int _animIDFreeFall;
- // 滞空时间
- private float _fallTimeoutTimer;
- void Start()
- {
- _animIDSpeed = Animator.StringToHash("Speed");
- _animIDGrounded = Animator.StringToHash("Grounded");
- _animIDJump = Animator.StringToHash("Jump");
- _animIDFreeFall = Animator.StringToHash("FreeFall");
- _hasAnimator = TryGetComponent(out _animator);
- if (playerCamera == null)
- playerCamera = Camera.main;
- }
- // Update is called once per frame
- void FixedUpdate()
- {
- JumpAndGravity();
- GroundedCheck();
- Move();
- LookAtTarget();
- }
- private void JumpAndGravity()
- {
- if (grounded)
- {
- // 重置滞空时间
- _fallTimeoutTimer = FallTimeout;
- // 动画设为非空中状态
- if (_hasAnimator)
- {
- _animator.SetBool(_animIDJump, false);
- _animator.SetBool(_animIDFreeFall, false);
- }
- // 满足条件开始跳跃
- //Debug.Log(jump + "*********" + _hasAnimator);
- if (jump)
- {
- if (_hasAnimator)
- {
- _animator.SetBool(_animIDJump, true);
- }
- }
- jump = false;
- }
- else
- {
- // 计算滞空时间
- if (_fallTimeoutTimer >= 0f)
- {
- _fallTimeoutTimer -= Time.deltaTime;
- //Debug.Log(_fallTimeoutTimer);
- }
- else
- {
- // 滞空结束,开始播放下落动画
- if (_hasAnimator)
- {
- //if (GroundedHeight() > 0.3f)
- _animator.SetBool(_animIDFreeFall, true);
- }
- }
- jump = false;
- }
- }
- float GroundedHeight()
- {
- RaycastHit hit;
- if (Physics.Raycast(transform.position, -transform.up, out hit, 100, groundLayers))
- {
- return hit.distance;
- }
- else
- {
- return 0;
- }
- }
- // 检查指定位置的球体与地面接触,判断是否接地
- private void GroundedCheck()
- {
- Vector3 spherePosition = new Vector3(
- transform.position.x,
- transform.position.y - groundedOffset,
- transform.position.z
- );
- grounded = Physics.CheckSphere(
- spherePosition,
- groundedRadius,
- groundLayers,
- QueryTriggerInteraction.Ignore
- );
- if (_hasAnimator)
- {
- _animator.SetBool(_animIDGrounded, grounded);
- }
- }
- private void Move()
- {
- float animSpeed = 0f;
- if (_hasAnimator)
- {
- if (speed >= 0 && speed <= walkSpeed)
- {
- animSpeed = RemapNum(speed, 0f, walkSpeed, 0f, 2f);
- }
- if (speed > walkSpeed)
- {
- speed = Mathf.Clamp(speed, 0f, 6.0f);
- animSpeed = RemapNum(speed, walkSpeed, runSpeed, 2f, 6f);
- }
- _animator.SetFloat(_animIDSpeed, animSpeed);
- }
- }
- private void LookAtTarget()
- {
- Vector3 cameraForward = playerCamera.transform.forward;
- if (Vector3.Dot(cameraForward, head.forward) < freeLookRange)
- {
- lookAtTarget.position = Vector3.Lerp(
- lookAtTarget.position,
- head.position + head.forward,
- 0.1f
- );
- }
- else
- {
- lookAtTarget.position = Vector3.Lerp(
- lookAtTarget.position,
- head.position + cameraForward,
- 0.1f
- );
- }
- }
- private float RemapNum(float input, float oldMin, float oldMax, float newMin, float newMax)
- {
- float result = (newMax - newMin) / (oldMax - oldMin) * (input - oldMin) + newMin;
- return result;
- }
- //球体与地面接触判断触地可视
- private void OnDrawGizmosSelected()
- {
- Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
- Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
- if (grounded)
- Gizmos.color = transparentGreen;
- else
- Gizmos.color = transparentRed;
- // when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
- Gizmos.DrawSphere(
- new Vector3(
- transform.position.x,
- transform.position.y - groundedOffset,
- transform.position.z
- ),
- groundedRadius
- );
- }
- private void OnFootstep(AnimationEvent animationEvent)
- {
- if (animationEvent.animatorClipInfo.weight > 0.5f)
- {
- if (footstepAudioClips.Length > 0)
- {
- var index = Random.Range(0, footstepAudioClips.Length);
- AudioSource.PlayClipAtPoint(
- footstepAudioClips[index],
- transform.transform.position,
- footstepAudioVolume
- );
- }
- }
- }
- private void OnLand(AnimationEvent animationEvent)
- {
- if (animationEvent.animatorClipInfo.weight > 0.5f)
- {
- AudioSource.PlayClipAtPoint(landingAudioClip, transform.position, footstepAudioVolume);
- }
- }
- }
|