468 lines
13 KiB
C#
468 lines
13 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Invector.vCamera;
|
|
using Invector.vCharacterController;
|
|
using PixelCrushers;
|
|
using UnityEngine;
|
|
using UnityEngine.Audio;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace Beyond
|
|
{
|
|
[RequireComponent(typeof(AudioSource))]
|
|
public class MusicManager : Saver
|
|
{
|
|
// Start is called before the first frame update
|
|
public AudioMixer m_audioMixer;
|
|
|
|
[Range(0.05f, 1f)]
|
|
public float m_targetVolume;
|
|
|
|
public float m_blendTime = 1f;
|
|
public float m_restTime = 10f;
|
|
private float m_time = -1f;
|
|
|
|
public enum State
|
|
{ NONE, EXPLORE, COMBAT, CUSTOM, DIALOG };
|
|
|
|
public State m_state = State.NONE;
|
|
private State m_prevState = State.NONE;
|
|
public AudioClip[] m_ExploreClips;
|
|
public AudioClip[] m_CombatClips;
|
|
public AudioClip[] m_DialogueClips;
|
|
public AudioSource m_musicSource;
|
|
|
|
[Tooltip("If music index < 0, then random index is used")]
|
|
public int m_MusicIndex = -1;
|
|
|
|
private static MusicManager s_instance;
|
|
private AudioClip m_currentClip;
|
|
private AudioClip m_previousClip;
|
|
private bool m_blendSounds = false;
|
|
public bool shouldPlayRandomClipsFrolList = false;
|
|
|
|
public bool isLocked = false;
|
|
|
|
[Serializable]
|
|
public class SaveData
|
|
{
|
|
public State state;
|
|
public int musicIndex;
|
|
}
|
|
|
|
public static MusicManager instance
|
|
{
|
|
get { return s_instance; }
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
m_musicSource.volume = 0;
|
|
if (s_instance == null)
|
|
{
|
|
s_instance = this;
|
|
m_musicSource = GetComponent<AudioSource>();
|
|
m_musicSource.loop = false;
|
|
UnmuteMusic();
|
|
// m_musicSource.volume = m_targetVolume;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("There are two music managers!");
|
|
DestroyImmediate(gameObject);
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
SetState(m_state);
|
|
GameStateManager.Instance.m_OnStateChanged.AddListener((GameStateManager.State s) =>
|
|
{
|
|
if (s == GameStateManager.State.COMBAT)
|
|
{
|
|
SetState(State.COMBAT);
|
|
}
|
|
else if (s == GameStateManager.State.NORMAL && m_prevState != State.COMBAT)
|
|
{
|
|
SetState(m_prevState);
|
|
}
|
|
});
|
|
}
|
|
|
|
private DayNightSettings dayNightSettings;
|
|
|
|
public void SetState(State state)
|
|
{
|
|
if (isLocked)
|
|
{
|
|
return;
|
|
}
|
|
m_prevState = m_state;
|
|
AudioClip[] clips = null; ;
|
|
switch (state)
|
|
{
|
|
case State.NONE:
|
|
break;
|
|
|
|
case State.EXPLORE:
|
|
clips = m_ExploreClips;
|
|
break;
|
|
|
|
case State.COMBAT:
|
|
clips = m_CombatClips;
|
|
break;
|
|
|
|
case State.DIALOG:
|
|
clips = m_DialogueClips;
|
|
break;
|
|
|
|
case State.CUSTOM:
|
|
break;
|
|
}
|
|
m_state = state;
|
|
|
|
if (clips != null && clips.Length > 0)
|
|
{
|
|
//get random combat index and return to music that played before on its end
|
|
if (state == State.COMBAT)
|
|
{
|
|
int combatIndex = Random.Range(0, clips.Length);
|
|
PlayClip(clips[combatIndex]);
|
|
return;
|
|
}
|
|
if (m_MusicIndex < 0)
|
|
{
|
|
m_MusicIndex = Random.Range(0, clips.Length);
|
|
}
|
|
m_MusicIndex = m_MusicIndex < clips.Length ? m_MusicIndex : clips.Length - 1;
|
|
PlayClip(clips[m_MusicIndex]);
|
|
}
|
|
else
|
|
{
|
|
Stop();
|
|
}
|
|
}
|
|
|
|
public void PlayDialogue()
|
|
{
|
|
PlayDialogue(-1);
|
|
}
|
|
|
|
public void PlayDialogue(int idx)
|
|
{
|
|
m_MusicIndex = idx;
|
|
SetState(State.DIALOG);
|
|
}
|
|
|
|
public void PlayExploration()
|
|
{
|
|
PlayExploration(-1);
|
|
}
|
|
|
|
public void PlayExploration(int idx)
|
|
{
|
|
m_MusicIndex = idx;
|
|
SetState(State.EXPLORE);
|
|
}
|
|
|
|
public void PlayCombat()
|
|
{
|
|
PlayCombat(-1);
|
|
}
|
|
|
|
public void PlayCombat(int idx)
|
|
{
|
|
if (isLocked)
|
|
{
|
|
return;
|
|
}
|
|
m_MusicIndex = idx;
|
|
SetState(State.COMBAT);
|
|
}
|
|
|
|
public void SetPreviousState()
|
|
{
|
|
SetState(m_prevState);
|
|
}
|
|
|
|
public void StopDialogue()
|
|
{
|
|
SetState(m_prevState);
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
m_musicSource.Stop();
|
|
}
|
|
|
|
/*
|
|
public void OnCombat()
|
|
{
|
|
OnCombat(0);
|
|
}
|
|
public void OnCombat(int idx)
|
|
{
|
|
if (m_combatCtr <= 0)
|
|
{
|
|
m_MusicIndex = idx;
|
|
SetState(State.COMBAT);
|
|
}
|
|
m_combatCtr++;
|
|
}
|
|
|
|
public void OnCombatEnd()
|
|
{
|
|
m_combatCtr--;
|
|
if (m_combatCtr == 0)
|
|
{
|
|
SetState(m_prevState);
|
|
}
|
|
}
|
|
*/
|
|
|
|
private IEnumerator PlayCoroutine(AudioClip clip)
|
|
{
|
|
m_previousClip = m_currentClip;
|
|
float volRate = m_targetVolume / m_blendTime;
|
|
while (m_musicSource.isPlaying)
|
|
{
|
|
m_musicSource.volume -= volRate * Time.deltaTime;
|
|
if (m_musicSource.volume <= 0f)
|
|
{
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
m_musicSource.clip = clip;
|
|
m_currentClip = clip;
|
|
m_musicSource.volume = 0f;
|
|
m_musicSource.Play();
|
|
m_time = 0f;
|
|
while (m_musicSource.volume < m_targetVolume)
|
|
{
|
|
m_musicSource.volume += volRate * Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
m_musicSource.volume = m_targetVolume;
|
|
//m_musicSource.PlayDelayed(0f);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
private void PlayClip(AudioClip clip)
|
|
{
|
|
//is previous clip playing
|
|
StopAllCoroutines();
|
|
StartCoroutine(PlayCoroutine(clip));
|
|
}
|
|
|
|
private float m_savedTargetVolume = 0.5f;
|
|
|
|
/// <summary>
|
|
/// for cutscenes with music in them
|
|
/// </summary>
|
|
public void MuteMusic()
|
|
{
|
|
// m_savedTargetVolume = m_targetVolume;
|
|
// m_targetVolume = 0f;
|
|
StopAllCoroutines();
|
|
StartCoroutine(DimMusic());
|
|
}
|
|
|
|
private IEnumerator DimMusic()
|
|
{
|
|
while (m_musicSource.isPlaying)
|
|
{
|
|
m_musicSource.volume -= Time.deltaTime;
|
|
if (m_musicSource.volume <= 0f)
|
|
{
|
|
enabled = false;
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
public void UnmuteMusic()
|
|
{
|
|
enabled = true;
|
|
StopAllCoroutines();
|
|
StartCoroutine(TurnOnMusic());
|
|
}
|
|
|
|
private IEnumerator TurnOnMusic()
|
|
{
|
|
m_musicSource.Play();
|
|
while (m_musicSource.volume <= m_targetVolume)
|
|
{
|
|
m_musicSource.volume += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// used for night scenery, so entering zones doesnt change current soundtrack
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
public void PlayLockedMusic(int index)
|
|
{
|
|
isLocked = false;
|
|
m_MusicIndex = index;
|
|
SetState(State.EXPLORE);
|
|
isLocked = true;
|
|
}
|
|
|
|
public void PlayUnlockedExploration(int index)
|
|
{
|
|
isLocked = false;
|
|
m_MusicIndex = index;
|
|
SetState(State.EXPLORE);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
// GameManager.instance.gameTime.m_DayNightEvent.AddListener(OnDayToNight);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
// GameManager.instance.gameTime.m_DayNightEvent.RemoveListener(OnDayToNight);
|
|
}
|
|
|
|
public override string RecordData()
|
|
{
|
|
SaveData saveData = new SaveData();
|
|
saveData.musicIndex = m_MusicIndex;
|
|
saveData.state = m_state;
|
|
return SaveSystem.Serialize(saveData);
|
|
}
|
|
|
|
public override void ApplyData(string s)
|
|
{
|
|
SaveData sd = SaveSystem.Deserialize<SaveData>(s);
|
|
if (sd != null)
|
|
{
|
|
switch (sd.state)
|
|
{
|
|
case State.COMBAT:
|
|
PlayCombat(sd.musicIndex);
|
|
break;
|
|
case State.CUSTOM:
|
|
break;
|
|
case State.DIALOG:
|
|
PlayDialogue(sd.musicIndex);
|
|
break;
|
|
case State.EXPLORE:
|
|
PlayExploration(sd.musicIndex);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private IEnumerator BlendVolume(bool day)
|
|
{
|
|
/*
|
|
m_time = 0f;
|
|
if (day)
|
|
{
|
|
m_daySounds.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
m_nightSounds.SetActive(true);
|
|
}
|
|
while (m_time < m_blendTime)
|
|
{
|
|
float a = m_time / (m_blendTime);
|
|
float volA = Mathf.Lerp(m_targetVolume, -80f, a);
|
|
float volB = Mathf.Lerp(-80f, m_targetVolume, a);
|
|
if (day)
|
|
{
|
|
m_dayVolume = volB;
|
|
m_nightVolume = volA;
|
|
}
|
|
else
|
|
{
|
|
m_dayVolume = volA;
|
|
m_nightVolume = volB;
|
|
}
|
|
|
|
m_audioMixer.SetFloat("DayVolume", m_dayVolume);
|
|
m_audioMixer.SetFloat("NightVolume", m_nightVolume);
|
|
m_audioMixer.SetFloat("DayMusicVolume", m_dayVolume);
|
|
m_audioMixer.SetFloat("NightMusicVolume", m_nightVolume);
|
|
m_time += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
if (day)
|
|
{
|
|
m_nightSounds.SetActive(false);
|
|
m_nightMusicSource.enabled = false;
|
|
}
|
|
else
|
|
{
|
|
m_daySounds.SetActive(false);
|
|
m_dayMusicSource.enabled = false;
|
|
}
|
|
*/
|
|
yield return null;
|
|
}
|
|
|
|
private bool CheckIfShouldPlayNext()
|
|
{
|
|
if (m_musicSource.isPlaying)
|
|
return false;
|
|
if (m_time < m_restTime)
|
|
{
|
|
m_time += Time.deltaTime;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
public void Update()
|
|
{
|
|
switch (m_state)
|
|
{
|
|
case State.EXPLORE:
|
|
if (CheckIfShouldPlayNext())
|
|
{
|
|
TryToChangeMusicIndex();
|
|
PlayExploration(m_MusicIndex);
|
|
}
|
|
break;
|
|
|
|
case State.NONE:
|
|
break;
|
|
|
|
case State.COMBAT:
|
|
if (CheckIfShouldPlayNext())
|
|
{
|
|
PlayCombat(m_MusicIndex);
|
|
}
|
|
break;
|
|
|
|
case State.CUSTOM:
|
|
break;
|
|
|
|
case State.DIALOG:
|
|
if (CheckIfShouldPlayNext())
|
|
{
|
|
PlayDialogue(m_MusicIndex);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void TryToChangeMusicIndex()
|
|
{
|
|
if (shouldPlayRandomClipsFrolList)
|
|
{
|
|
m_MusicIndex = Random.Range(0, m_ExploreClips.Length);
|
|
}
|
|
}
|
|
}
|
|
} |