Space-Smash-Out/Assets/Scripts/ManageableAudio.cs

185 lines
3.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using log4net;
using Managers;
using PrimeTween;
using Unity.VisualScripting;
using UnityEngine;
public enum AudioEffects
{
LowPass
}
public class ManageableAudio : MonoBehaviour
{
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public int id = 0;
public string audioTag = "audio";
public float pitchRange = 0.3f;
public float volumeRange = 0.3f;
public AudioSource AudioSource { get; set; }
private float initialVolume;
private float initialPitch;
private bool IsUpdating = false;
private bool WasOneShotTriggered = false;
void Awake()
{
if (gameObject.TryGetComponent(out AudioSource audioS))
{
AudioSource = audioS;
initialVolume = AudioSource.volume;
initialPitch = AudioSource.pitch;
}
else
{
Log.Warn("Managable Audio Instance hasn't got an audio source game object"
+ $". Tag:{audioTag} ID:{id}");
return;
}
}
void Start()
{
AudioManager.G.AudioEffectBroadcasted += SwitchAudioEffect;
}
/// <summary>
/// Start playing the sound source.
/// </summary>
/// <param name="playLooping">Should the sound loop</param>
/// <param name="isOneShot">Play sound only once until reset</param>
public void PlayAudio(bool playLooping, bool isOneShot = false)
{
if (AudioSource == null
|| IsUpdating
|| AudioSource.isPlaying
|| WasOneShotTriggered)
{
return;
}
if (isOneShot)
{
WasOneShotTriggered = true;
}
AudioSource.enabled = true;
AudioSource.loop = playLooping;
AudioSource.Play();
}
public void StopAudio()
{
if (AudioSource == null || IsUpdating)
{
return;
}
if (AudioSource.isPlaying)
{
AudioSource.Stop();
// TODO: Reset audio properties?
}
}
public void DestroyAudio()
{
Destroy(gameObject);
}
/// <summary>
/// Updates the pitch of the audio clip.
/// </summary>
/// <param name="changeValue">-1 to 1 times the max pitch range
/// of this sound. </param>
public void ChangePitch(float changeValue)
{
changeValue = Mathf.Clamp(changeValue, -1, 1);
AudioSource.pitch = initialPitch + (changeValue * pitchRange);
}
public void ChangeVolume(float changeValue)
{
AudioSource.volume = initialVolume + (changeValue * volumeRange);
}
/// <summary>
/// Fades the volume of the audio source to 0 in the given interval.
/// </summary>
/// <param name="duration">Time for fade out</param>
/// <param name="destroyedAfter">Destroy the object after fade out?</param>
public void FadeOutAudio(float duration = 1, bool destroyedAfter = false)
{
if (IsUpdating)
{
return;
}
IsUpdating = true;
float initVolume = AudioSource.volume;
Tween.Custom(initVolume, 0, duration, onValueChange: value =>
{
if (AudioSource.IsDestroyed())
{
return;
}
AudioSource.volume = value;
})
.OnComplete(() =>
{
if (AudioSource.IsDestroyed())
{
return;
}
IsUpdating = false;
StopAudio();
AudioSource.volume = initVolume;
if (destroyedAfter) Destroy(gameObject);
});
}
/// <summary>
/// Makes starting this sound possible again,
/// if it was set to only play once.
/// </summary>
public void ResetOneShot()
{
if (!AudioSource.isPlaying)
{
WasOneShotTriggered = false;
}
}
public void SwitchAudioEffect(AudioEffectBroadCastEventArgs args)
{
if (args.AffectedParent != transform.parent)
{
return;
}
switch (args.Effect)
{
case AudioEffects.LowPass:
SwitchLowPassFilter(args.Activate);
break;
}
}
public void SwitchLowPassFilter(bool activate)
{
if (TryGetComponent(out AudioLowPassFilter filter))
{
filter.enabled = activate;
}
}
void OnDestroy()
{
AudioManager.G.AudioEffectBroadcasted -= SwitchAudioEffect;
}
}