123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Serialization;
- using Quaternion = System.Numerics.Quaternion;
- 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 >= 0.0f)
- {
- _fallTimeoutTimer -= Time.deltaTime;
- }
- else
- {
- // 滞空结束,开始播放下落动画
- if (_hasAnimator)
- {
- _animator.SetBool(_animIDFreeFall, true);
- }
- }
- jump = false;
- }
- }
-
- // 检查指定位置的球体与地面接触,判断是否接地
- 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);
- }
- }
- }
|