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; } /// /// Start playing the sound source. /// /// Should the sound loop /// Play sound only once until reset public void PlayAudio(bool playLooping, float randomPitchRange = 0f, bool isOneShot = false) { if (AudioSource == null || IsUpdating || AudioSource.isPlaying || WasOneShotTriggered) { return; } if (isOneShot) { WasOneShotTriggered = true; } AudioSource.enabled = true; AudioSource.loop = playLooping; if (randomPitchRange != 0) { AudioSource.pitch = UnityEngine.Random.Range(initialPitch - randomPitchRange, initialPitch + randomPitchRange); } AudioSource.Play(); } public void StopAudio() { if (AudioSource == null || IsUpdating) { return; } if (AudioSource.isPlaying) { AudioSource.Stop(); // TODO: Reset audio properties? } } public void DestroyAudio() { Destroy(gameObject); } /// /// Updates the pitch of the audio clip. /// /// -1 to 1 times the max pitch range /// of this sound. 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); } /// /// Fades the volume of the audio source to 0 in the given interval. /// /// Time for fade out /// Destroy the object after fade out? public void FadeOutAudio(float duration = 1, bool destroyedAfter = false) { if (IsUpdating || AudioSource.IsDestroyed()) { 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); }); } /// /// Makes starting this sound possible again, /// if it was set to only play once. /// 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; } }