I have absolutely no idea what is going on. I made a script for getting the Player’s options in the options menu and it simply refuses to load the options correctly. It only loads the Resolution correctly and sets everything else to what appears to be 0. I can’t find a single mistake in my code.
Here is the breakdown of each portion of the code:
Awake method, sets the ResolutionDropdown with all resolutions available and sets the default options.
void Awake()
{
if (ResolutionDropdown != null)
{
ResolutionArray = Screen.resolutions.Select(resolution => new Resolution { width = resolution.width, height = resolution.height }).Distinct().ToArray();
ResolutionDropdown.ClearOptions();
int CurrentResolutionIndex = 0;
List<string> DropdownOptions = new List<string>();
for (int i = 0; i < ResolutionArray.Length; i++)
{
string Option = ResolutionArray [i].width + " x " + ResolutionArray [i].height;
DropdownOptions.Add(Option);
if (ResolutionArray [i].width == Screen.width && ResolutionArray [i].height == Screen.height)
{
CurrentResolutionIndex = i;
}
}
ResolutionDropdown.AddOptions(DropdownOptions);
ResolutionDropdown.value = CurrentResolutionIndex;
ResolutionDropdown.RefreshShownValue();
}
if (GraphicsQualityDropdown != null)
{
for (int i = 0; i < GraphicsQualityArray.Length; i++)
{
GraphicsQualityArray [i] = GraphicsQualityDropdown.options[i].text;
}
}
SetDefaultOptions();
LoadOptions();
SaveOptions();
}
SetDefaultOptions() creates a file named defaultoptions.json that should be accessed in case the game can’t find the actual options.json file.
public void SetDefaultOptions()
{
OptionsScript.Resolution = 0;
OptionsScript.Fullscreen = false;
OptionsScript.Volume = -40f;
OptionsScript.GraphicsQuality = 0;
//Save Options to a .json file//
string DefaultOptionsJSON = JsonUtility.ToJson(OptionsScript);
File.WriteAllText(Application.dataPath + "/defaultoptions.json", DefaultOptionsJSON);
if (!File.Exists(Application.dataPath + "/options.json"))
{
File.WriteAllText(Application.dataPath + "/options.json", DefaultOptionsJSON);
}
}
As the name suggests, LoadOptions() loads all options from file (options.json), which is updated everytime the player changes one of the main options (resolution, whether the game is fullscreen or not, audio volume, and the graphical quality, respectively).
public void LoadOptions()
{
//Load Options from a .json file//
if (File.Exists(Application.dataPath + "/options.json"))
{
string OptionsJSON = File.ReadAllText(Application.dataPath + "/options.json");
JsonUtility.FromJsonOverwrite(OptionsJSON, OptionsScript);
SetResolution(OptionsScript.Resolution);
SetFullscreen(OptionsScript.Fullscreen);
SetVolume(OptionsScript.Volume);
SetGraphicsQuality(OptionsScript.GraphicsQuality);
}
else
{
ResetAllOptions();
}
}
SaveOptions() saves the options everytime the player changes them in options.json, so next time the game is opened it can open that file to know the options the player has chosen previously.
public void SaveOptions()
{
//Save Options to a .json file//
string OptionsJSON = JsonUtility.ToJson(OptionsScript);
File.WriteAllText(Application.dataPath + "/options.json", OptionsJSON);
}
In case anything goes wrong, or the player simply wants all options to be set to default values, the ResetAllOptions() should come to rescue and load the options from defaultoptions.json instead of options.json. This did not happen in the error mentioned, though it shouldn’t happen in the first place.
public void ResetAllOptions()
{
//Load Options from a .json file//
if (File.Exists(Application.dataPath + "/defaultoptions.json"))
{
string DefaultOptionsJSON = File.ReadAllText(Application.dataPath + "/defaultoptions.json");
JsonUtility.FromJsonOverwrite(DefaultOptionsJSON, OptionsScript);
SetResolution(OptionsScript.Resolution);
SetFullscreen(OptionsScript.Fullscreen);
SetVolume(OptionsScript.Volume);
SetGraphicsQuality(OptionsScript.GraphicsQuality);
}
else
{
SetDefaultOptions();
}
SaveOptions();
}
These methods set the main options the player can choose from and are set in the options menu with input from dropdowns, buttons, sliders, etc. Every time one of them is changed, it immediately saves the new values to the options.json file with SaveOptions(). They seem to be working correctly.
public void SetResolution (int ResolutionIndex)
{
Resolution AppliedResolution = ResolutionArray[ResolutionIndex];
Screen.SetResolution(AppliedResolution.width, AppliedResolution.height, Screen.fullScreen);
if (ResolutionText != null)
{
ResolutionText.text = "Resolution: " + ResolutionArray [ResolutionIndex].width + " x " + ResolutionArray [ResolutionIndex].height;
}
OptionsScript.Resolution = ResolutionIndex;
SaveOptions();
}
public void SetFullscreen (bool Fullscreen)
{
Screen.fullScreen = Fullscreen;
OptionsScript.Fullscreen = Fullscreen;
SaveOptions();
}
public void SetVolume (float Volume)
{
Mixer.SetFloat("MasterVolume", Volume);
if (VolumeSlider != null)
{
if (VolumeText != null)
{
VolumeText.text = "Volume: " + VolumeSlider.normalizedValue * 100f + "%";
}
}
OptionsScript.Volume = Volume;
SaveOptions();
}
public void SetGraphicsQuality (int Quality)
{
QualitySettings.SetQualityLevel(Quality);
if (GraphicsQualityText != null)
{
GraphicsQualityText.text = "Graphics quality: " + GraphicsQualityArray [Quality];
}
OptionsScript.GraphicsQuality = Quality;
SaveOptions();
}
From what I could analyse, the culprit seems to be LoadOptions() as it seems to not read the file completely, instead only reading the first “resolution” value and ignoring all rest. I checked the options.json itself and it does change correctly when I change the options in the menu. There is nothing in code that seems to be wrong though and I have no clue why this method is not working, it seems Unity hates me.
Here is the full code in case it’s needed:
using System.IO;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Audio;
public class OptionsManager : MonoBehaviour
{
public AudioMixer Mixer;
public Slider VolumeSlider;
public Text VolumeText;
public Resolution[] ResolutionArray;
public Dropdown ResolutionDropdown;
public Text ResolutionText;
public string [] GraphicsQualityArray;
public Dropdown GraphicsQualityDropdown;
public Text GraphicsQualityText;
public Options OptionsScript;
void Awake()
{
if (ResolutionDropdown != null)
{
ResolutionArray = Screen.resolutions.Select(resolution => new Resolution { width = resolution.width, height = resolution.height }).Distinct().ToArray();
ResolutionDropdown.ClearOptions();
int CurrentResolutionIndex = 0;
List<string> DropdownOptions = new List<string>();
for (int i = 0; i < ResolutionArray.Length; i++)
{
string Option = ResolutionArray [i].width + " x " + ResolutionArray [i].height;
DropdownOptions.Add(Option);
if (ResolutionArray [i].width == Screen.width && ResolutionArray [i].height == Screen.height)
{
CurrentResolutionIndex = i;
}
}
ResolutionDropdown.AddOptions(DropdownOptions);
ResolutionDropdown.value = CurrentResolutionIndex;
ResolutionDropdown.RefreshShownValue();
}
if (GraphicsQualityDropdown != null)
{
for (int i = 0; i < GraphicsQualityArray.Length; i++)
{
GraphicsQualityArray [i] = GraphicsQualityDropdown.options[i].text;
}
}
SetDefaultOptions();
LoadOptions();
SaveOptions();
}
public void SetResolution (int ResolutionIndex)
{
Resolution AppliedResolution = ResolutionArray[ResolutionIndex];
Screen.SetResolution(AppliedResolution.width, AppliedResolution.height, Screen.fullScreen);
if (ResolutionText != null)
{
ResolutionText.text = "Resolution: " + ResolutionArray [ResolutionIndex].width + " x " + ResolutionArray [ResolutionIndex].height;
}
OptionsScript.Resolution = ResolutionIndex;
SaveOptions();
}
public void SetFullscreen (bool Fullscreen)
{
Screen.fullScreen = Fullscreen;
OptionsScript.Fullscreen = Fullscreen;
SaveOptions();
}
public void SetVolume (float Volume)
{
Mixer.SetFloat("MasterVolume", Volume);
if (VolumeSlider != null)
{
if (VolumeText != null)
{
VolumeText.text = "Volume: " + VolumeSlider.normalizedValue * 100f + "%";
}
}
OptionsScript.Volume = Volume;
SaveOptions();
}
public void SetGraphicsQuality (int Quality)
{
QualitySettings.SetQualityLevel(Quality);
if (GraphicsQualityText != null)
{
GraphicsQualityText.text = "Graphics quality: " + GraphicsQualityArray [Quality];
}
OptionsScript.GraphicsQuality = Quality;
SaveOptions();
}
public void ResetAllOptions()
{
//Load Options from a .json file//
if (File.Exists(Application.dataPath + "/defaultoptions.json"))
{
string DefaultOptionsJSON = File.ReadAllText(Application.dataPath + "/defaultoptions.json");
JsonUtility.FromJsonOverwrite(DefaultOptionsJSON, OptionsScript);
SetResolution(OptionsScript.Resolution);
SetFullscreen(OptionsScript.Fullscreen);
SetVolume(OptionsScript.Volume);
SetGraphicsQuality(OptionsScript.GraphicsQuality);
}
else
{
SetDefaultOptions();
}
SaveOptions();
}
public void SetDefaultOptions()
{
OptionsScript.Resolution = 0;
OptionsScript.Fullscreen = false;
OptionsScript.Volume = -40f;
OptionsScript.GraphicsQuality = 0;
//Save Options to a .json file//
string DefaultOptionsJSON = JsonUtility.ToJson(OptionsScript);
File.WriteAllText(Application.dataPath + "/defaultoptions.json", DefaultOptionsJSON);
if (!File.Exists(Application.dataPath + "/options.json"))
{
File.WriteAllText(Application.dataPath + "/options.json", DefaultOptionsJSON);
}
}
public void LoadOptions()
{
//Load Options from a .json file//
if (File.Exists(Application.dataPath + "/options.json"))
{
string OptionsJSON = File.ReadAllText(Application.dataPath + "/options.json");
JsonUtility.FromJsonOverwrite(OptionsJSON, OptionsScript);
SetResolution(OptionsScript.Resolution);
SetFullscreen(OptionsScript.Fullscreen);
SetVolume(OptionsScript.Volume);
SetGraphicsQuality(OptionsScript.GraphicsQuality);
}
else
{
ResetAllOptions();
}
}
public void SaveOptions()
{
//Save Options to a .json file//
string OptionsJSON = JsonUtility.ToJson(OptionsScript);
File.WriteAllText(Application.dataPath + "/options.json", OptionsJSON);
}
}