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;
}
}
}