using System; using Core.Utilities; using UnityEngine; using UnityEngine.Audio; namespace Core.Data { /// /// Base game manager /// public abstract class GameManagerBase : PersistentSingleton where TDataStore : GameDataStoreBase, new() where TGameManager : GameManagerBase { /// /// File name of saved game /// const string k_SavedGameFile = "save"; /// /// Reference to audio mixer for volume changing /// public AudioMixer gameMixer; /// /// Master volume parameter on the mixer /// public string masterVolumeParameter; /// /// SFX volume parameter on the mixer /// public string sfxVolumeParameter; /// /// Music volume parameter on the mixer /// public string musicVolumeParameter; /// /// The serialization implementation for persistence /// protected JsonSaver m_DataSaver; /// /// The object used for persistence /// protected TDataStore m_DataStore; /// /// Retrieve volumes from data store /// public virtual void GetVolumes(out float master, out float sfx, out float music) { master = m_DataStore.masterVolume; sfx = m_DataStore.sfxVolume; music = m_DataStore.musicVolume; } /// /// Set and persist game volumes /// public virtual void SetVolumes(float master, float sfx, float music, bool save) { // Early out if no mixer set if (gameMixer == null) { return; } // Transform 0-1 into logarithmic -80-0 if (masterVolumeParameter != null) { gameMixer.SetFloat(masterVolumeParameter, LogarithmicDbTransform(Mathf.Clamp01(master))); } if (sfxVolumeParameter != null) { gameMixer.SetFloat(sfxVolumeParameter, LogarithmicDbTransform(Mathf.Clamp01(sfx))); } if (musicVolumeParameter != null) { gameMixer.SetFloat(musicVolumeParameter, LogarithmicDbTransform(Mathf.Clamp01(music))); } if (save) { // Apply to save data too m_DataStore.masterVolume = master; m_DataStore.sfxVolume = sfx; m_DataStore.musicVolume = music; SaveData(); } } /// /// Load data /// protected override void Awake() { base.Awake(); LoadData(); } /// /// Initialize volumes. We cannot change mixer params on awake /// protected virtual void Start() { SetVolumes(m_DataStore.masterVolume, m_DataStore.sfxVolume, m_DataStore.musicVolume, false); } /// /// Set up persistence /// protected void LoadData() { // If it is in Unity Editor use the standard JSON (human readable for debugging) otherwise encrypt it for deployed version #if UNITY_EDITOR m_DataSaver = new JsonSaver(k_SavedGameFile); #else m_DataSaver = new EncryptedJsonSaver(k_SavedGameFile); #endif try { if (!m_DataSaver.Load(out m_DataStore)) { m_DataStore = new TDataStore(); SaveData(); } } catch (Exception) { Debug.Log("Failed to load data, resetting"); m_DataStore = new TDataStore(); SaveData(); } } /// /// Saves the gamme /// protected virtual void SaveData() { m_DataSaver.Save(m_DataStore); } /// /// Transform volume from linear to logarithmic /// protected static float LogarithmicDbTransform(float volume) { volume = (Mathf.Log(89 * volume + 1) / Mathf.Log(90)) * 80; return volume - 80; } } }