Files
speckle-unity/Assets/First person controller/Scripts/Components/FirstPersonAudio.cs
T
2021-04-14 14:38:05 +01:00

149 lines
4.8 KiB
C#

using UnityEngine;
public class FirstPersonAudio : MonoBehaviour
{
public FirstPersonMovement character;
public GroundCheck groundCheck;
[Header("Step")]
public AudioSource stepAudio;
public AudioSource runningAudio;
[Tooltip("Minimum velocity for the step audio to play")]
public float velocityThreshold = .01f;
Vector2 lastCharacterPosition;
Vector2 CurrentCharacterPosition => new Vector2(character.transform.position.x, character.transform.position.z);
[Header("Landing")]
public AudioSource landingAudio;
public AudioClip[] landingSFX;
[Header("Jump")]
public Jump jump;
public AudioSource jumpAudio;
public AudioClip[] jumpSFX;
[Header("Crouch")]
public Crouch crouch;
public AudioSource crouchStartAudio, crouchedAudio, crouchEndAudio;
public AudioClip[] crouchStartSFX, crouchEndSFX;
void Reset()
{
// Setup stuff.
character = GetComponentInParent<FirstPersonMovement>();
groundCheck = (transform.parent ?? transform).GetComponentInChildren<GroundCheck>();
stepAudio = GetOrCreateAudioSource("Step audio");
runningAudio = GetOrCreateAudioSource("Running audio");
landingAudio = GetOrCreateAudioSource("Landing audio");
// Jump audio.
jump = GetComponentInParent<Jump>();
if (jump)
jumpAudio = GetOrCreateAudioSource("Jump audio");
// Crouch audio.
crouch = GetComponentInParent<Crouch>();
if (crouch)
{
crouchStartAudio = GetOrCreateAudioSource("Crouch start audio");
crouchStartAudio = GetOrCreateAudioSource("Crouched audio");
crouchStartAudio = GetOrCreateAudioSource("Crouch end audio");
}
}
void OnEnable()
{
// Subscribe to events.
groundCheck.Grounded += PlayLandingAudio;
if (jump)
jump.Jumped += PlayJumpAudio;
if (crouch)
{
crouch.CrouchStart += PlayCrouchStartAudio;
crouch.CrouchEnd += PlayCrouchEndAudio;
}
}
void OnDisable()
{
// Unsubscribe to events.
groundCheck.Grounded -= PlayLandingAudio;
if (jump)
jump.Jumped -= PlayJumpAudio;
if (crouch)
{
crouch.CrouchStart -= PlayCrouchStartAudio;
crouch.CrouchEnd -= PlayCrouchEndAudio;
}
}
void FixedUpdate()
{
// Play moving audio if the character is moving and on the ground.
float velocity = Vector3.Distance(CurrentCharacterPosition, lastCharacterPosition);
if (velocity >= velocityThreshold && groundCheck.isGrounded)
{
if (crouch && crouch.IsCrouched)
UpdateMovingAudios(crouchedAudio, runningAudio, stepAudio);
else if (character.IsRunning)
UpdateMovingAudios(runningAudio, stepAudio, crouchedAudio);
else
UpdateMovingAudios(stepAudio, crouchedAudio, runningAudio);
}
else
UpdateMovingAudios(null, stepAudio, crouchedAudio, runningAudio);
lastCharacterPosition = CurrentCharacterPosition;
}
static void UpdateMovingAudios(AudioSource audioToPlay, params AudioSource[] audiosToPause)
{
// Play audio to play and pause the others.
if (audioToPlay && !audioToPlay.isPlaying)
audioToPlay.Play();
foreach (var audio in audiosToPause)
if (audio)
audio.Pause();
}
void PlayLandingAudio() => PlayRandomClip(landingAudio, landingSFX);
void PlayJumpAudio() => PlayRandomClip(jumpAudio, jumpSFX);
void PlayCrouchStartAudio() => PlayRandomClip(crouchStartAudio, crouchStartSFX);
void PlayCrouchEndAudio() => PlayRandomClip(crouchEndAudio, crouchEndSFX);
#region Utility.
AudioSource GetOrCreateAudioSource(string name)
{
// Try to get the audiosource.
AudioSource result = System.Array.Find(GetComponentsInChildren<AudioSource>(), a => a.name == name);
if (result)
return result;
// Audiosource does not exist, create it.
result = new GameObject(name).AddComponent<AudioSource>();
result.spatialBlend = 1;
result.playOnAwake = false;
result.transform.SetParent(transform, false);
return result;
}
void PlayRandomClip(AudioSource audio, AudioClip[] clips)
{
if (!audio || clips.Length <= 0)
return;
// Get a random clip. If possible, make sure that it's not the same as the clip that is already on the audiosource.
AudioClip clip = clips[Random.Range(0, clips.Length)];
if (clips.Length > 1)
while (clip == audio.clip)
clip = clips[Random.Range(0, clips.Length)];
// Play the clip.
audio.clip = clip;
audio.Play();
}
#endregion
}