|
|
|
@@ -0,0 +1,524 @@
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using DG.Tweening;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
|
|
|
|
|
public class AudioManager : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
[Header("Sources")]
|
|
|
|
|
public AudioSource musicSource;
|
|
|
|
|
public AudioSource uiSfxSource;
|
|
|
|
|
public AudioSource gameSfxSource;
|
|
|
|
|
|
|
|
|
|
public AudioSource crowdSfxSourceA;
|
|
|
|
|
public AudioSource crowdSfxSourceB;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Music")]
|
|
|
|
|
public AudioDirectory audioDirectory;
|
|
|
|
|
[SerializeField] float musicFadeDuration = 1f;
|
|
|
|
|
|
|
|
|
|
[Header("Crowd bed")]
|
|
|
|
|
[SerializeField] float crowdFadeDuration = 1f;
|
|
|
|
|
[SerializeField] float maxCrowdVolume = 1f;
|
|
|
|
|
|
|
|
|
|
public static AudioManager instance;
|
|
|
|
|
|
|
|
|
|
float _maxMusicVolume;
|
|
|
|
|
bool _inGame;
|
|
|
|
|
CrowdNoiseType _currentCrowdNoiseType;
|
|
|
|
|
bool _crowdPrimaryIsA = true;
|
|
|
|
|
bool _crowdBedInitialized;
|
|
|
|
|
Coroutine _introRoutine;
|
|
|
|
|
Coroutine _goalSfxSequenceRoutine;
|
|
|
|
|
|
|
|
|
|
void Awake()
|
|
|
|
|
{
|
|
|
|
|
if (instance != null)
|
|
|
|
|
{
|
|
|
|
|
Destroy(gameObject);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instance = this;
|
|
|
|
|
DontDestroyOnLoad(gameObject);
|
|
|
|
|
_maxMusicVolume = musicSource != null ? musicSource.volume : 1f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnEnable()
|
|
|
|
|
{
|
|
|
|
|
SceneManager.sceneLoaded += OnSceneLoaded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnDisable()
|
|
|
|
|
{
|
|
|
|
|
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Start()
|
|
|
|
|
{
|
|
|
|
|
var scene = SceneManager.GetActiveScene();
|
|
|
|
|
if (scene.IsValid())
|
|
|
|
|
ApplyMusicForScene(scene.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
|
|
|
|
{
|
|
|
|
|
if (!scene.IsValid())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ApplyMusicForScene(scene.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ApplyMusicForScene(string sceneName)
|
|
|
|
|
{
|
|
|
|
|
if (audioDirectory == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool comingFromGame = _inGame;
|
|
|
|
|
|
|
|
|
|
if (sceneName == audioDirectory.gameSceneName)
|
|
|
|
|
{
|
|
|
|
|
_inGame = true;
|
|
|
|
|
EnableCrowdSourcesForGame();
|
|
|
|
|
SetCrowdNoiseType(CrowdNoiseType.GameStart);
|
|
|
|
|
if (musicSource != null)
|
|
|
|
|
FadeOutMusic();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_inGame = false;
|
|
|
|
|
FadeOutAndDisableCrowdSources();
|
|
|
|
|
|
|
|
|
|
if (musicSource == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (sceneName == audioDirectory.menuSceneName)
|
|
|
|
|
{
|
|
|
|
|
if (comingFromGame)
|
|
|
|
|
{
|
|
|
|
|
StopIntroRoutine();
|
|
|
|
|
FadeInMenuMusic();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
HandleMenuSceneMusicWhileIntroMayStillPlay();
|
|
|
|
|
}
|
|
|
|
|
else if (sceneName == audioDirectory.introSceneName)
|
|
|
|
|
{
|
|
|
|
|
StartIntroMusic();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StartIntroMusic()
|
|
|
|
|
{
|
|
|
|
|
if (audioDirectory.introMusic == null)
|
|
|
|
|
{
|
|
|
|
|
EnsureMenuMusic();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (musicSource.clip == audioDirectory.introMusic && musicSource.isPlaying)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
StopIntroRoutine();
|
|
|
|
|
DOTween.Kill(musicSource);
|
|
|
|
|
musicSource.Stop();
|
|
|
|
|
musicSource.clip = audioDirectory.introMusic;
|
|
|
|
|
musicSource.loop = false;
|
|
|
|
|
musicSource.volume = _maxMusicVolume;
|
|
|
|
|
musicSource.Play();
|
|
|
|
|
_introRoutine = StartCoroutine(IntroThenMenuWhenDone());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IEnumerator IntroThenMenuWhenDone()
|
|
|
|
|
{
|
|
|
|
|
yield return new WaitWhile(() => musicSource != null && musicSource.isPlaying && musicSource.clip == audioDirectory.introMusic);
|
|
|
|
|
|
|
|
|
|
_introRoutine = null;
|
|
|
|
|
if (musicSource == null || instance == null)
|
|
|
|
|
yield break;
|
|
|
|
|
|
|
|
|
|
if (SceneManager.GetActiveScene().name == audioDirectory.gameSceneName)
|
|
|
|
|
yield break;
|
|
|
|
|
|
|
|
|
|
PlayMenuTrack(_maxMusicVolume);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleMenuSceneMusicWhileIntroMayStillPlay()
|
|
|
|
|
{
|
|
|
|
|
if (IsIntroStillPlaying())
|
|
|
|
|
{
|
|
|
|
|
if (_introRoutine == null)
|
|
|
|
|
_introRoutine = StartCoroutine(IntroThenMenuWhenDone());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IsMenuMusicActiveAtFullVolume())
|
|
|
|
|
EnsureMenuMusic();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsIntroStillPlaying()
|
|
|
|
|
{
|
|
|
|
|
return audioDirectory.introMusic != null && musicSource.clip == audioDirectory.introMusic && musicSource.isPlaying;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsMenuMusicActiveAtFullVolume()
|
|
|
|
|
{
|
|
|
|
|
return audioDirectory.menuMusic != null && musicSource.clip == audioDirectory.menuMusic && musicSource.isPlaying
|
|
|
|
|
&& Mathf.Approximately(musicSource.volume, _maxMusicVolume);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EnsureMenuMusic()
|
|
|
|
|
{
|
|
|
|
|
if (audioDirectory.menuMusic == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
DOTween.Kill(musicSource);
|
|
|
|
|
if (musicSource.clip == audioDirectory.menuMusic && musicSource.isPlaying && Mathf.Approximately(musicSource.volume, _maxMusicVolume))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
PlayMenuTrack(_maxMusicVolume);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PlayMenuTrack(float volume)
|
|
|
|
|
{
|
|
|
|
|
if (audioDirectory.menuMusic == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
musicSource.Stop();
|
|
|
|
|
musicSource.clip = audioDirectory.menuMusic;
|
|
|
|
|
musicSource.loop = true;
|
|
|
|
|
musicSource.volume = volume;
|
|
|
|
|
musicSource.Play();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FadeOutMusic()
|
|
|
|
|
{
|
|
|
|
|
StopIntroRoutine();
|
|
|
|
|
DOTween.Kill(musicSource);
|
|
|
|
|
musicSource.DOFade(0f, musicFadeDuration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FadeInMenuMusic()
|
|
|
|
|
{
|
|
|
|
|
if (audioDirectory.menuMusic == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
StopIntroRoutine();
|
|
|
|
|
DOTween.Kill(musicSource);
|
|
|
|
|
musicSource.Stop();
|
|
|
|
|
musicSource.clip = audioDirectory.menuMusic;
|
|
|
|
|
musicSource.loop = true;
|
|
|
|
|
musicSource.volume = 0f;
|
|
|
|
|
musicSource.Play();
|
|
|
|
|
musicSource.DOFade(_maxMusicVolume, musicFadeDuration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StopIntroRoutine()
|
|
|
|
|
{
|
|
|
|
|
if (_introRoutine != null)
|
|
|
|
|
{
|
|
|
|
|
StopCoroutine(_introRoutine);
|
|
|
|
|
_introRoutine = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region SFX
|
|
|
|
|
|
|
|
|
|
public void PlayWallHit(float vol=1){
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.wallHits[Random.Range(0, audioDirectory.wallHits.Length)], vol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayBallHit(float vol=1){
|
|
|
|
|
if (audioDirectory.ballHits != null && audioDirectory.ballHits.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.ballHits[Random.Range(0, audioDirectory.ballHits.Length)],vol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayPuckHit(float vol=1){
|
|
|
|
|
if (audioDirectory.puckHits != null && audioDirectory.puckHits.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.puckHits[Random.Range(0, audioDirectory.puckHits.Length)],vol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayBallHitNet(){
|
|
|
|
|
if (audioDirectory.ballHitNet != null && audioDirectory.ballHitNet.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.ballHitNet[Random.Range(0, audioDirectory.ballHitNet.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayGoalScoredSfxSequence()
|
|
|
|
|
{
|
|
|
|
|
if (gameSfxSource == null || audioDirectory == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_goalSfxSequenceRoutine != null)
|
|
|
|
|
StopCoroutine(_goalSfxSequenceRoutine);
|
|
|
|
|
|
|
|
|
|
_goalSfxSequenceRoutine = StartCoroutine(GoalScoredSfxSequenceRoutine());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IEnumerator GoalScoredSfxSequenceRoutine()
|
|
|
|
|
{
|
|
|
|
|
CrowdNoiseType typeBefore = _currentCrowdNoiseType;
|
|
|
|
|
AudioManager.instance.SetCrowdNoiseType(CrowdNoiseType.Cheer);
|
|
|
|
|
AudioClip net = PickRandomClip(audioDirectory.ballHitNet);
|
|
|
|
|
if (net != null)
|
|
|
|
|
{
|
|
|
|
|
gameSfxSource.PlayOneShot(net);
|
|
|
|
|
yield return new WaitForSeconds(net.length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AudioClip whistle = PickRandomClip(audioDirectory.refereeWhistle);
|
|
|
|
|
if (whistle != null)
|
|
|
|
|
{
|
|
|
|
|
gameSfxSource.PlayOneShot(whistle);
|
|
|
|
|
yield return new WaitForSeconds(whistle.length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AudioClip goal = PickRandomClip(audioDirectory.refereeGoal);
|
|
|
|
|
if (goal != null)
|
|
|
|
|
{
|
|
|
|
|
gameSfxSource.PlayOneShot(goal);
|
|
|
|
|
yield return new WaitForSeconds(goal.length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_goalSfxSequenceRoutine = null;
|
|
|
|
|
|
|
|
|
|
AudioManager.instance.SetCrowdNoiseType(typeBefore);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static AudioClip PickRandomClip(AudioClip[] clips)
|
|
|
|
|
{
|
|
|
|
|
if (clips == null || clips.Length == 0)
|
|
|
|
|
return null;
|
|
|
|
|
return clips[Random.Range(0, clips.Length)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayTimerBeep(){
|
|
|
|
|
if (audioDirectory.timerBeep != null && audioDirectory.timerBeep.Length > 0)
|
|
|
|
|
uiSfxSource.PlayOneShot(audioDirectory.timerBeep[Random.Range(0, audioDirectory.timerBeep.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayMatchMakingBeep(){
|
|
|
|
|
if (audioDirectory.matchMakingBeep != null && audioDirectory.matchMakingBeep.Length > 0)
|
|
|
|
|
uiSfxSource.PlayOneShot(audioDirectory.matchMakingBeep[Random.Range(0, audioDirectory.matchMakingBeep.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayMatchFound(){
|
|
|
|
|
if (audioDirectory.matchFound != null && audioDirectory.matchFound.Length > 0)
|
|
|
|
|
uiSfxSource.PlayOneShot(audioDirectory.matchFound[Random.Range(0, audioDirectory.matchFound.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayRefereeGoal(){
|
|
|
|
|
if (audioDirectory.refereeGoal != null && audioDirectory.refereeGoal.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.refereeGoal[Random.Range(0, audioDirectory.refereeGoal.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayRefereeWhistle(){
|
|
|
|
|
if (audioDirectory.refereeWhistle != null && audioDirectory.refereeWhistle.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.refereeWhistle[Random.Range(0, audioDirectory.refereeWhistle.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayCrowdAmbientNoise(){
|
|
|
|
|
if (audioDirectory.crowdAmbientNoise != null && audioDirectory.crowdAmbientNoise.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.crowdAmbientNoise[Random.Range(0, audioDirectory.crowdAmbientNoise.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayCrowdAmbientNoiseNearGoal(){
|
|
|
|
|
if (audioDirectory.crowdAmbientNoiseNearGoal != null && audioDirectory.crowdAmbientNoiseNearGoal.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.crowdAmbientNoiseNearGoal[Random.Range(0, audioDirectory.crowdAmbientNoiseNearGoal.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayCrowdCheering(){
|
|
|
|
|
if (audioDirectory.crowdCheering != null && audioDirectory.crowdCheering.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.crowdCheering[Random.Range(0, audioDirectory.crowdCheering.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PlayCrowdNoiseMatchStart(){
|
|
|
|
|
if (audioDirectory.crowdNoiseMatchStart != null && audioDirectory.crowdNoiseMatchStart.Length > 0)
|
|
|
|
|
gameSfxSource.PlayOneShot(audioDirectory.crowdNoiseMatchStart[Random.Range(0, audioDirectory.crowdNoiseMatchStart.Length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetIsBallNearGoal(bool nearGoal)
|
|
|
|
|
{
|
|
|
|
|
if (!_inGame)
|
|
|
|
|
return;
|
|
|
|
|
if (_currentCrowdNoiseType == CrowdNoiseType.Cheer || _currentCrowdNoiseType == CrowdNoiseType.GameStart)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
SetCrowdNoiseType(nearGoal ? CrowdNoiseType.NearGoal : CrowdNoiseType.Normal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetCrowdNoiseType(CrowdNoiseType type) => SetCrowdNoiseType(type, crowdFadeDuration);
|
|
|
|
|
|
|
|
|
|
public void SetCrowdNoiseType(CrowdNoiseType type, float fadeDuration)
|
|
|
|
|
{
|
|
|
|
|
if (audioDirectory == null || crowdSfxSourceA == null || crowdSfxSourceB == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (_crowdBedInitialized && _currentCrowdNoiseType == type)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
float dur = fadeDuration >= 0f ? fadeDuration : crowdFadeDuration;
|
|
|
|
|
|
|
|
|
|
AudioClip[] clips = GetCrowdClipsForType(audioDirectory, type);
|
|
|
|
|
if (clips == null || clips.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
FadeOutCrowdBed(dur);
|
|
|
|
|
_currentCrowdNoiseType = type;
|
|
|
|
|
_crowdBedInitialized = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AudioClip clip = clips[Random.Range(0, clips.Length)];
|
|
|
|
|
if (clip == null)
|
|
|
|
|
{
|
|
|
|
|
FadeOutCrowdBed(dur);
|
|
|
|
|
_currentCrowdNoiseType = type;
|
|
|
|
|
_crowdBedInitialized = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AudioSource outgoing = _crowdPrimaryIsA ? crowdSfxSourceA : crowdSfxSourceB;
|
|
|
|
|
AudioSource incoming = _crowdPrimaryIsA ? crowdSfxSourceB : crowdSfxSourceA;
|
|
|
|
|
|
|
|
|
|
DOTween.Kill(outgoing);
|
|
|
|
|
DOTween.Kill(incoming);
|
|
|
|
|
|
|
|
|
|
incoming.clip = clip;
|
|
|
|
|
incoming.loop = true;
|
|
|
|
|
incoming.volume = 0f;
|
|
|
|
|
incoming.Play();
|
|
|
|
|
|
|
|
|
|
outgoing.DOFade(0f, dur).OnComplete(() =>
|
|
|
|
|
{
|
|
|
|
|
outgoing.Stop();
|
|
|
|
|
outgoing.clip = null;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
incoming.DOFade(maxCrowdVolume, dur);
|
|
|
|
|
|
|
|
|
|
_crowdPrimaryIsA = !_crowdPrimaryIsA;
|
|
|
|
|
_currentCrowdNoiseType = type;
|
|
|
|
|
_crowdBedInitialized = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static AudioClip[] GetCrowdClipsForType(AudioDirectory dir, CrowdNoiseType type)
|
|
|
|
|
{
|
|
|
|
|
if (dir == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case CrowdNoiseType.GameStart:
|
|
|
|
|
return dir.crowdNoiseMatchStart;
|
|
|
|
|
case CrowdNoiseType.Normal:
|
|
|
|
|
return dir.crowdAmbientNoise;
|
|
|
|
|
case CrowdNoiseType.NearGoal:
|
|
|
|
|
return dir.crowdAmbientNoiseNearGoal;
|
|
|
|
|
case CrowdNoiseType.Cheer:
|
|
|
|
|
return dir.crowdCheering;
|
|
|
|
|
default:
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EnableCrowdSourcesForGame()
|
|
|
|
|
{
|
|
|
|
|
if (crowdSfxSourceA != null)
|
|
|
|
|
crowdSfxSourceA.enabled = true;
|
|
|
|
|
if (crowdSfxSourceB != null)
|
|
|
|
|
crowdSfxSourceB.enabled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FadeOutAndDisableCrowdSources()
|
|
|
|
|
{
|
|
|
|
|
DOTween.Kill(crowdSfxSourceA);
|
|
|
|
|
DOTween.Kill(crowdSfxSourceB);
|
|
|
|
|
|
|
|
|
|
int pending = 0;
|
|
|
|
|
if (crowdSfxSourceA != null)
|
|
|
|
|
pending++;
|
|
|
|
|
if (crowdSfxSourceB != null)
|
|
|
|
|
pending++;
|
|
|
|
|
if (pending == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
void FinishOne()
|
|
|
|
|
{
|
|
|
|
|
pending--;
|
|
|
|
|
if (pending > 0)
|
|
|
|
|
return;
|
|
|
|
|
if (crowdSfxSourceA != null)
|
|
|
|
|
crowdSfxSourceA.enabled = false;
|
|
|
|
|
if (crowdSfxSourceB != null)
|
|
|
|
|
crowdSfxSourceB.enabled = false;
|
|
|
|
|
_crowdBedInitialized = false;
|
|
|
|
|
_crowdPrimaryIsA = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FadeCrowdSourceOutOrImmediate(crowdSfxSourceA, crowdFadeDuration, FinishOne);
|
|
|
|
|
FadeCrowdSourceOutOrImmediate(crowdSfxSourceB, crowdFadeDuration, FinishOne);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FadeOutCrowdBed(float dur)
|
|
|
|
|
{
|
|
|
|
|
DOTween.Kill(crowdSfxSourceA);
|
|
|
|
|
DOTween.Kill(crowdSfxSourceB);
|
|
|
|
|
FadeCrowdSourceOut(crowdSfxSourceA, dur);
|
|
|
|
|
FadeCrowdSourceOut(crowdSfxSourceB, dur);
|
|
|
|
|
_crowdPrimaryIsA = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FadeCrowdSourceOutOrImmediate(AudioSource source, float dur, System.Action onComplete)
|
|
|
|
|
{
|
|
|
|
|
if (source == null)
|
|
|
|
|
{
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!source.enabled || (!source.isPlaying && Mathf.Approximately(source.volume, 0f)))
|
|
|
|
|
{
|
|
|
|
|
source.Stop();
|
|
|
|
|
source.clip = null;
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
source.DOFade(0f, dur).OnComplete(() =>
|
|
|
|
|
{
|
|
|
|
|
source.Stop();
|
|
|
|
|
source.clip = null;
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FadeCrowdSourceOut(AudioSource source, float dur)
|
|
|
|
|
{
|
|
|
|
|
if (source == null)
|
|
|
|
|
return;
|
|
|
|
|
if (!source.isPlaying)
|
|
|
|
|
{
|
|
|
|
|
source.clip = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
source.DOFade(0f, dur).OnComplete(() =>
|
|
|
|
|
{
|
|
|
|
|
source.Stop();
|
|
|
|
|
source.clip = null;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public enum CrowdNoiseType{
|
|
|
|
|
GameStart,
|
|
|
|
|
Normal,
|
|
|
|
|
NearGoal,
|
|
|
|
|
Cheer
|
|
|
|
|
}
|