HKI Core
SettingsSystem.cs
Go to the documentation of this file.
1 using UnityEngine;
2 using UnityEngine.Audio;
3 using System.IO;
4 using System.Xml;
5 using System.Collections.Generic;
6 using HKI.Core.Loc;
7 using HKI.Core.Init;
8 using HKI.Core.Variables;
9 
10 namespace HKI.Core.Settings
11 {
32  [System.Serializable]
33  public class SettingsSystem : Container, IInit
34  {
35  // Private variables
36  bool isEditor = false;
37  bool changeFunctionCallbacksLinked = false;
38 
39  string configFilePath = "";
40 
41  [SerializeField] string ConfigFilename = "config.config";
42  [SerializeField] string EditorPath = "";
43  string runtimePath = "";
44 
45  [SerializeField] bool WarningsEnabled = true;
46 
47  [SerializeField] bool UseTargetFrameRate = true;
48 
49  [SerializeField] IntegerWidthHeight Resolution = null;
50  [SerializeField] Boolean Fullscreen = null;
51  [SerializeField] Integer RefreshRate = null;
52  [SerializeField] String Quality = null;
53  [SerializeField] FrameRateAndVSyncMode FRAVSM = null;
54  [SerializeField] AntiAliasingMode AAM = null;
55  [SerializeField] Language TextLanguage = null;
56  [SerializeField] Language AudioLanguage = null;
57  [SerializeField] FloatMinMax MasterVolume = null;
58  [SerializeField] FloatMinMax MusicVolume = null;
59  [SerializeField] FloatMinMax AmbientVolume = null;
60  [SerializeField] FloatMinMax FxVolume = null;
61  [SerializeField] FloatMinMax UiFxVolume = null;
62  [SerializeField] FloatMinMax VoicesVolume = null;
63 
64  [SerializeField] AudioMixer AudioMixer = null;
65 
66  // Init function
70  public void Init()
71  {
72  isEditor = Application.isEditor;
73 
74  runtimePath = Application.persistentDataPath + "/";
75 
76  if (isEditor)
77  configFilePath = EditorPath + ConfigFilename;
78  else
79  configFilePath = runtimePath + ConfigFilename;
80 
81  if(isEditor && !Application.isPlaying)
82  return;
83 
84  LinkStandardSettingsToOnChangeFunctions();
85 
86  if(isEditor)
87  ActivateAllSettings();
88  else
89  {
90  if(!Load())
91  CreateConfigFile();
92  }
93  }
94 
95  // OnDisable function
96  void OnDisable()
97  {
98  if(changeFunctionCallbacksLinked)
99  UnLinkStandardSettingsFromOnChangeFunctions();
100  }
101 
102  // Interface functions
106  public void Save()
107  {
108  XmlDocument document = new XmlDocument();
109 
110  XmlNode rootNode = document.CreateElement("Config");
111  document.AppendChild(rootNode);
112  Save(rootNode);
113  document.Save(configFilePath);
114  }
115 
116  // Helper functions
121  {
122  Resolution = GetVar<IntegerWidthHeight>("Resolution");
123  Fullscreen = GetVar<Boolean>("Fullscreen");
124  RefreshRate = GetVar<Integer>("Refresh Rate");
125  Quality = GetVar<String>("Quality");
126  FRAVSM = GetVar<FrameRateAndVSyncMode>("FRAVSM");
127  AAM = GetVar<AntiAliasingMode>("AAM");
128  TextLanguage = GetVar<Language>("Text Language");
129  AudioLanguage = GetVar<Language>("Audio Language");
130  MasterVolume = GetVar<FloatMinMax>("Master Volume");
131  MusicVolume = GetVar<FloatMinMax>("Music Volume");
132  AmbientVolume = GetVar<FloatMinMax>("Ambient Volume");
133  FxVolume = GetVar<FloatMinMax>("Fx Volume");
134  UiFxVolume = GetVar<FloatMinMax>("Ui Fx Volume");
135  VoicesVolume = GetVar<FloatMinMax>("Voices Volume");
136  }
137 
144  T GetVar<T>(string variableName) where T : HKIVar
145  {
146  HKIVar variable = GetHKIVarByName(variableName);
147 
148  if(variable == null)
149  {
150  Debug.LogError("Couldn't find a >" + variableName + "< of type >" + typeof(T).Name + "< variable as child of the settings system!");
151  return null;
152  }
153 
154  return (T)variable;
155  }
156 
161  bool Load()
162  {
163  if(isEditor)
164  return false;
165 
166  if(!File.Exists(configFilePath))
167  return false;
168 
169 
170  XmlDocument document = new XmlDocument();
171 
172  document.Load(configFilePath);
173  XmlNode configNode = document.SelectSingleNode("//Config/" + name.Replace(" ", ""));
174  if(configNode == null)
175  {
176  Debug.LogError("Config file is corupted!");
177  return false;
178  }
179 
180  Load(configNode);
181 
182  ActivateAllSettings();
183 
184  return true;
185  }
186 
191  {
192  Save();
193  ActivateAllSettings();
194  }
195 
200  {
201  ChangeResolution();
202  ChangeQuality();
203  ChangeFrameRateAndVSyncMode();
204  ChangeAudio();
205  }
206 
211  {
212  // Resolution
213  if(Resolution != null)
214  {
215  if (isEditor)
216  Resolution.OnValueChanged += () => { LogInfoForNotSetableInEditor(Resolution); };
217  else
218  Resolution.OnValueChanged += ChangeResolution;
219  }
220  else if(WarningsEnabled)
221  Debug.LogWarning("There is no linked >Resolution< variable of type >IntegerWidthHeight< in this settings system!");
222 
223  // Fullscreen
224  if(Fullscreen != null)
225  {
226  if (isEditor)
227  Fullscreen.OnValueChanged += () => { LogInfoForNotSetableInEditor(Fullscreen); };
228  else
229  Fullscreen.OnValueChanged += ChangeResolution;
230  }
231  else if(WarningsEnabled)
232  Debug.LogError("There is no linked >Fullscreen< variable of type >Boolean< in this settings system!");
233 
234  // Refresh rate
235  if(UseTargetFrameRate && RefreshRate != null)
236  {
237  if (isEditor)
238  RefreshRate.OnValueChanged += () => { LogInfoForNotSetableInEditor(RefreshRate); };
239  else
240  RefreshRate.OnValueChanged += ChangeResolution;
241  }
242  else if(UseTargetFrameRate && WarningsEnabled)
243  Debug.LogError("There is no linked >RefreshRate< variable of type >Integer< in this settings system!");
244 
245  // Quality
246  if(Quality != null)
247  Quality.OnValueChanged += ChangeQuality;
248  else if(WarningsEnabled)
249  Debug.LogError("There is no linked >Quality< variable of type >String< in this settings system!");
250 
251  // FRAVSM
252  if(FRAVSM != null)
253  FRAVSM.OnValueChanged += ChangeFrameRateAndVSyncMode;
254  else if(WarningsEnabled)
255  Debug.LogError("There is no linked >FRAVSM< variable of type >FrameRateAndVSyncMode< in this settings system!");
256 
257  // AAM
258  // Done by camera script
259 
260  // Master Volume
261  if (MasterVolume != null)
262  MasterVolume.OnValueChanged += ChangeAudio;
263  else if(WarningsEnabled)
264  Debug.LogError("There is no linked >MasterVolume< variable of type >FloatMinMax< in this settings system!");
265 
266  // Music Volume
267  if(MusicVolume != null)
268  MusicVolume.OnValueChanged += ChangeAudio;
269  else if(WarningsEnabled)
270  Debug.LogError("There is no linked >MusicVolume< variable of type >FloatMinMax< in this settings system!");
271 
272  // Ambient Volume
273  if(AmbientVolume != null)
274  AmbientVolume.OnValueChanged += ChangeAudio;
275  else if(WarningsEnabled)
276  Debug.LogError("There is no linked >AmbientVolume< variable of type >FloatMinMax< in this settings system!");
277 
278  // Fx Volume
279  if(FxVolume != null)
280  FxVolume.OnValueChanged += ChangeAudio;
281  else if(WarningsEnabled)
282  Debug.LogError("There is no linked >FxVolume< variable of type >FloatMinMax< in this settings system!");
283 
284  // Ui Fx Volume
285  if(UiFxVolume != null)
286  UiFxVolume.OnValueChanged += ChangeAudio;
287  else if(WarningsEnabled)
288  Debug.LogError("There is no linked >UiFxVolume< variable of type >FloatMinMax< in this settings system!");
289 
290  // Voices Volume
291  if(VoicesVolume != null)
292  VoicesVolume.OnValueChanged += ChangeAudio;
293  else if(WarningsEnabled)
294  Debug.LogError("There is no linked >VoicesVolume< variable of type >FloatMinMax< in this settings system!");
295 
296  changeFunctionCallbacksLinked = true;
297  }
298 
303  {
304  // Resolution
305  if(Resolution != null)
306  {
307  if (isEditor)
308  Resolution.OnValueChanged -= () => { LogInfoForNotSetableInEditor(Resolution); };
309  else
310  Resolution.OnValueChanged -= ChangeResolution;
311  }
312 
313  // Fullscreen
314  if(Fullscreen != null)
315  {
316  if (isEditor)
317  Fullscreen.OnValueChanged -= () => { LogInfoForNotSetableInEditor(Fullscreen); };
318  else
319  Fullscreen.OnValueChanged -= ChangeResolution;
320  }
321 
322  // Refresh rate
323  if(UseTargetFrameRate && RefreshRate != null)
324  {
325  if (isEditor)
326  RefreshRate.OnValueChanged -= () => { LogInfoForNotSetableInEditor(RefreshRate); };
327  else
328  RefreshRate.OnValueChanged -= ChangeResolution;
329  }
330 
331  // Quality
332  if(Quality != null)
333  Quality.OnValueChanged -= ChangeQuality;
334 
335  // FRAVSM
336  if(FRAVSM != null)
337  FRAVSM.OnValueChanged -= ChangeFrameRateAndVSyncMode;
338 
339  // AAM
340  // Done by camera script
341 
342  // Master Volume
343  if (MasterVolume != null)
344  MasterVolume.OnValueChanged -= ChangeAudio;
345 
346  // Music Volume
347  if(MusicVolume != null)
348  MusicVolume.OnValueChanged -= ChangeAudio;
349 
350  // Ambient Volume
351  if (AmbientVolume != null)
352  AmbientVolume.OnValueChanged -= ChangeAudio;
353 
354  // Fx Volume
355  if(FxVolume != null)
356  FxVolume.OnValueChanged -= ChangeAudio;
357 
358  // Ui Fx Volume
359  if(UiFxVolume != null)
360  UiFxVolume.OnValueChanged -= ChangeAudio;
361 
362  // Voices Volume
363  if(VoicesVolume != null)
364  VoicesVolume.OnValueChanged -= ChangeAudio;
365 
366  changeFunctionCallbacksLinked = false;
367  }
368 
370  {
371  Debug.Log("Can't set this setting (" + variable.name + ") in the editor (only in a runtime build): " + variable.ToString());
372  }
373 
374  // Set function
379  {
380  if(Resolution == null || Fullscreen == null || isEditor)
381  return;
382 
383  if(UseTargetFrameRate && RefreshRate != null)
384  Screen.SetResolution(Resolution.Value.Width, Resolution.Value.Height, Fullscreen.Value, RefreshRate.Value);
385  else
386  Screen.SetResolution(Resolution.Value.Width, Resolution.Value.Height, Fullscreen.Value);
387  }
388 
393  {
394  int qualityIndex = 0;
395 
396  string[] qualityNames = QualitySettings.names;
397  for(int i = 0; i < qualityNames.Length; i++)
398  {
399  if(qualityNames[i] == Quality.Value)
400  {
401  qualityIndex = i;
402  break;
403  }
404  }
405 
406  QualitySettings.SetQualityLevel(qualityIndex);
407  }
408 
413  {
414  switch(FRAVSM.Value)
415  {
416  case FrameRateAndVSyncModes.VSyncOffTFDefault: ChangeFrameRateAndVSyncMode(-1, 0); break;
417 
418  case FrameRateAndVSyncModes.VSyncOffTF30: ChangeFrameRateAndVSyncMode(30, 0); break;
419 
420  case FrameRateAndVSyncModes.VSyncOffTF45: ChangeFrameRateAndVSyncMode(45, 0); break;
421 
422  case FrameRateAndVSyncModes.VSyncOffTF60: ChangeFrameRateAndVSyncMode(60, 0); break;
423 
424  case FrameRateAndVSyncModes.VSyncOffTF90: ChangeFrameRateAndVSyncMode(90, 0); break;
425 
426  case FrameRateAndVSyncModes.VSyncOffTF120: ChangeFrameRateAndVSyncMode(120, 0); break;
427 
428  case FrameRateAndVSyncModes.VSyncOffTF144: ChangeFrameRateAndVSyncMode(144, 0); break;
429 
430  case FrameRateAndVSyncModes.VsyncOnDefault: ChangeFrameRateAndVSyncMode(-1, 1); break;
431 
432  case FrameRateAndVSyncModes.VsyncOnHalfMFR: ChangeFrameRateAndVSyncMode(-1, 2); break;
433 
434  case FrameRateAndVSyncModes.VsyncOnThirdMFR: ChangeFrameRateAndVSyncMode(-1, 3); break;
435 
436  case FrameRateAndVSyncModes.VsyncOnQuaterMFR: ChangeFrameRateAndVSyncMode(-1, 4); break;
437 
438  default:
439  ChangeFrameRateAndVSyncMode(-1, 1);
440  break;
441  }
442  }
443 
447  void ChangeFrameRateAndVSyncMode(int fr, int vsync)
448  {
449  Application.targetFrameRate = fr;
450  QualitySettings.vSyncCount = vsync;
451  }
452 
456  void ChangeAudio()
457  {
458  if(AudioMixer == null)
459  return;
460 
461  if (MasterVolume != null)
462  AudioMixer.SetFloat("SetMasterVolume", MasterVolume.Value);
463 
464  if(MusicVolume != null)
465  AudioMixer.SetFloat("SetMusicVolume", MusicVolume.Value);
466 
467  if (AmbientVolume != null)
468  AudioMixer.SetFloat("SetAmbientVolume", AmbientVolume.Value);
469 
470  if(FxVolume != null)
471  AudioMixer.SetFloat("SetFxVolume", FxVolume.Value);
472 
473  if(UiFxVolume != null)
474  AudioMixer.SetFloat("SetUiFxVolume", UiFxVolume.Value);
475 
476  if(VoicesVolume != null)
477  AudioMixer.SetFloat("SetVoicesVolume", VoicesVolume.Value);
478  }
479  }
480 }
This interface allows the initialization of anything by the Initialzer.
Definition: IInit.cs:8
void ChangeResolution()
This function will set the resolution.
Special Variable enables the use of the AntiAliasingModes data type as a variable of the settings sys...
This system loades, saves and stores settings. In addition to that it sets settings in the engine for...
void CreateConfigFile()
This function will create the config file. This could be the case on the first time the game starts a...
void ChangeFrameRateAndVSyncMode()
This function will analyse the FrameRateAndVSyncMode value and set the frame rate and vsync according...
bool Load()
This function loads the saved settings from a XML file and tries to activate them.
void ActivateAllSettings()
This function activates all settings.
void Save()
Saves all settings (custom settings that are given to this system too) into a XML file...
This abstract class of a ScriptableObject is provides child classes with on value changed callback ca...
Definition: HKIVar.cs:12
Special Variable enables the use of the FrameRateAndVSyncModes data type as a variable of the setting...
void GetReferences()
This helper function gets all references to Unity standard settings. For a list look into the class d...
This container is itself a HKIVar but it purpose is to hold other HKIVars together at one place...
Definition: Container.cs:12
void ChangeFrameRateAndVSyncMode(int fr, int vsync)
This function will set the frame rate and vsync.
Special Variable enables the use of the SystemLanguage data type as a variable of the settings system...
Definition: Language.cs:13
Implementation of a boolean value as a HKIVar via HKIVarGeneric.
Definition: Boolean.cs:16
void ChangeAudio()
This function will set all audio volume settings.
void LogInfoForNotSetableInEditor(HKIVar variable)
void LinkStandardSettingsToOnChangeFunctions()
This function links the change functions to the standard settings variables.
Implementation of a integer value as a HKIVar via HKIVarGeneric.
Definition: Integer.cs:16
void UnLinkStandardSettingsFromOnChangeFunctions()
This will unlink the change functions from standard settings variables.
void Init()
The init function will load and tries to activate all settings. Some settings can&#39;t be set in the edi...
Implementation of a string value as a HKIVar via HKIVarGeneric.
Definition: String.cs:16
void ChangeQuality()
This function will set the quality.
FrameRateAndVSyncModes
All possible settings for frame rate and VSync.
Implementation of a IntegerWidthHeight value as a HKIVar via HKIVarGeneric.
Implementation of a min max float value as a HKIVar via HKIVarGenericMinMax.
Definition: FloatMinMax.cs:16