I tried different methods to add footstep sounds, but they all just played continuously without even finishing. I’m going to past all of my code for the better view.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovementScript : MonoBehaviour
{
[Header("Movement")]
private CharacterController controller;
[SerializeField] private float moveSpeed;
[SerializeField] private float walkSpeed;
[SerializeField] private float runSpeed;
public bool isMoving;
AudioSource playSound;
[Header("AudioClips")]
[SerializeField] FootStepGenerator stepGenerator;
[SerializeField] float footStepTimer;
Vector3 moveDirection;
private Vector3 velocity;
[Header("GroundCheck")]
[SerializeField] private bool isGrounded;
[SerializeField] private float groundCheckDistance;
[SerializeField] private LayerMask groundMask;
[SerializeField] private float gravity;
[Header("Crouching")]
[SerializeField] private float crouchHeight = 0.5f;
[SerializeField] private float standingHeight = 8f;
[SerializeField] private float timeToCrouch = 0.5f;
[SerializeField] private Vector3 crouchingCenter = new Vector3(0, 5, 0);
[SerializeField] private Vector3 standingCenter = new Vector3(0, 0, 0);
[SerializeField] private KeyCode crouchKey = KeyCode.C;
[SerializeField] private bool canCrouch = true;
private bool isCrouching;
private bool duringCrouchAnimation;
private bool ShouldCrouch => Input.GetKeyDown(crouchKey) && !duringCrouchAnimation;
void Start()
{
controller = GetComponent<CharacterController>();
playSound = GetComponent<AudioSource>();
isMoving = false;
stepGenerator = GetComponent<FootStepGenerator>();
}
void Update()
{
Move();
if (canCrouch)
HandleCrouch();
}
private void HandleCrouch()
{
if(ShouldCrouch) StartCoroutine(CrouchStand());
}
private IEnumerator CrouchStand()
{
duringCrouchAnimation = true;
float timeElapsed = 0;
float targetHeight = isCrouching ? standingHeight : crouchHeight;
float currentHeight = controller.height;
Vector3 targetCenter = isCrouching ? standingCenter : crouchingCenter;
Vector3 currentCenter = controller.center;
while(timeElapsed < timeToCrouch)
{
controller.height = Mathf.Lerp(currentHeight, targetHeight, timeElapsed/timeToCrouch);
controller.center = Vector3.Lerp(currentCenter, targetCenter, timeElapsed/timeToCrouch);
timeElapsed += Time.deltaTime;
yield return null;
}
controller.height = targetHeight;
controller.center = targetCenter;
isCrouching = !isCrouching;
duringCrouchAnimation = false;
}
private void Move()
{
isGrounded = Physics.CheckSphere(transform.position, groundCheckDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float moveZ = Input.GetAxis("Vertical");
float moveX = Input.GetAxis("Horizontal");
moveDirection = transform.right * moveX + transform.forward * moveZ;
if (moveDirection != Vector3.zero && !Input.GetKey(KeyCode.LeftShift))
{
isMoving = true;
moveSpeed = walkSpeed;
}
else if (moveDirection != Vector3.zero && Input.GetKey(KeyCode.LeftShift))
{
isMoving = true;
moveSpeed = runSpeed;
}
else if(moveDirection == Vector3.zero) isMoving = false;
if (velocity.x < 0 || velocity.x > 0 || velocity.y > 0 || velocity.y < 0 || velocity.z > 0 || velocity.z < 0)
if (isMoving) PlayFootSounds();
controller.Move(moveDirection * Time.deltaTime * moveSpeed);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
void PlayFootSounds()
{
StartCoroutine("PlayStepSound", footStepTimer);
}
IEnumerator PlayStepSound(float timer)
{
var randomIndex = Random.Range(0, 3);
stepGenerator.audioSource.clip = stepGenerator.footStepSounds[randomIndex];
stepGenerator.audioSource.Play();
yield return new WaitForSeconds(timer);
}
}