Options Manager
Adding New Options
Locate the Game Options asset in the Scriptables folder.

Select the Game Options asset and click the Open Options Builder button. This will launch the Options Builder window, allowing you to edit existing options or add new ones.

To add new sections or options, click the plus icon beside the Options Profile name or the Section name.

After adding an option to the section, you must define the following values: Name, Title, and Prefab.
Name serves as the key used in the configuration file or as an identifier for the option observer.
Title is the display name of the option shown in the UI.
Prefab is the object instantiated when the options are built.

Once you've finished modifying the options, be sure to save the asset by clicking the Save Asset button.
Navigate to the Options Manager component within the GAMEMANAGER object and click Refresh Options. This will update and display any newly added sections or options under Option Links.

When new sections are added or a section transform is not assigned, you’ll need to manually update the options UI by creating a new layout group similar to the existing ones. After that, assign a transform where the options for that section will be instantiated.
Finally, click Build Options to automatically remove the old option references and generate new ones based on the current Options Asset.
Observing Options
There are three ways to observe your newly created options:
Use the
ObserveOption()
method directly within your component to monitor the option value.Utilize the CustomOptionObservers component to create and attach a custom observer module.
Employ the OptionObserver component to invoke a specified reflected type.
ObserverOption Method
Here is the code that observes the option directly (the value must be converted to the option type):
using UnityEngine;
namespace UHFPS.Runtime
{
public class TestObserver : MonoBehaviour
{
public bool BoolValue;
private void Start()
{
OptionsManager.ObserveOption("some_option", (value) => BoolValue = (bool)value);
}
}
}
CustomOptionObservers Method
In some circumstances, you will need to write a custom options observer that does not belong to any script, such as the Audio Listener class. In that case, you can write your own OptionObserverType.
using System;
using UnityEngine;
namespace UHFPS.Runtime
{
[Serializable]
public class OptionListenerVolume : OptionObserverType
{
public override string Name => "Audio Listener Volume";
public override void OptionUpdate(object value)
{
if (value == null)
return;
AudioListener.volume = (float)value;
}
}
}
After writing a custom OptionObserverType, you can add the CustomOptionObservers component to the desired location and add your newly created option to the list of option observers. The Observe Option Name must be the same as the option name in the Options Builder.

OptionObserver Method
In certain situations, you may simply want to observe an option that reflects its value onto a field, property, or method. For this, the OptionObserver component is ideal. For example, if you only want to display the FPS Counter when the show_fps
option is set to true
, you can create a custom method that accepts a bool
parameter and use it with the OptionObserver.

Creating New Options
Create a new class that will inherit from the
OptionModule
class.
Override
OnApplyOption()
so we can define what happens after the settings are confirmed.
public override void OnApplyOption()
{
int value = (int)Value;
bool converted = value != 0;
if (Behaviour.IsChanged)
{
// do something when the setting changes
// e.g. apply the setting
}
// store the value in SerializableData, which is then serialized into the config file.
Options.SerializableData[Name] = new(converted);
}
In this example, we'll define a simple boolean setting:
You can use the
Value
parameter to quickly access the current value set through the UI.The data type of the
Value
parameter depends on the associated Option Behaviour component. For instance, the OptionsRadio behaviour returns an integer type. Be careful to correctly convert theValue
into the appropriate type.You can use
Behaviour.IsChanged
to verify if the option was changed through the UI.Finally, make sure to store the
Value
intoSerializableData
, using the option'sName
as the key.
Override
OnLoadOption(bool fromFile)
to define what happens when the setting is loaded.
public override void OnLoadOption(bool fromFile)
{
bool optionValue = DefaultValue;
if (fromFile && CheckOption(JTokenType.Boolean, out bool value))
optionValue = value;
// do something after loading the value
// e.g. apply loaded setting
Behaviour.SetOptionValue(optionValue);
}
Override
OnBuildOption(OptionBehaviour behavior)
to define how the setting will be constructed.
public override void OnBuildOption(OptionBehaviour behaviour)
{
behaviour.SetOptionData(new StorableCollection()
{
{ "options", new GString[] { OffName, OnName } },
{ "defaultValue", DefaultValue ? 1 : 0 }
});
}
In some cases, you may also need to override the
OnBuildOptionRuntime()
method, which allows you to populate option states dynamically when the game starts.In this example, we used it to populate the option states with available screen resolutions, ensuring the settings reflect the current environment at runtime.
public override void OnBuildOptionRuntime()
{
string[] resolutions = Options.Resolutions.Select(x => $"{x.width}x{x.height}").ToArray();
GString[] gStrings = resolutions.Select(x => new GString($"{x}")).ToArray();
Behaviour.SetOptionData(new StorableCollection() { { "options", gStrings } });
}
Creating New OptionBehaviour
Create a new class that will inherit from the
OptionBehaviour
class.
public override void SetOptionValue(object value)
{
int radio = Convert.ToInt32(value);
SetOption(radio);
IsChanged = false;
}
public override object GetOptionValue()
{
return RadioIndex;
}
public override void SetOptionData(StorableCollection data)
{
if(data.TryGetValue("options", out GString[] options))
Options = options.Select(x => new GString(x)).ToArray();
if (data.TryGetValue("defaultValue", out int value))
RadioIndex = value;
}
public void SetOption(int index)
{
RadioIndex = index;
IsChanged = true;
}
Newly created OptionBehaviours can be added to the Options Asset, which makes them available for selection within the Options Builder.

Last updated