首次提交

This commit is contained in:
Bob.Song
2026-03-05 18:07:55 +08:00
commit e125bb869e
4534 changed files with 563920 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 78eea6e8bb5e9b749b24a4245f0fbec7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 29d171e52a3428a45adc655aa7470e5d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
{
"name": "Ilumisoft.GraphicsControl.BuiltIn",
"rootNamespace": "",
"references": [
"GUID:7f595fd175e67274183d17fac15b74c9",
"GUID:d60799ab2a985554ea1a39cd38695018"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"POST_PROCESSING_BUILT_IN"
],
"versionDefines": [
{
"name": "com.unity.postprocessing",
"expression": "1.0.0",
"define": "POST_PROCESSING_BUILT_IN"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: bd0ede699487c6c479fb7b3301ef8884
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
namespace Ilumisoft.GraphicsControl.Rendering
{
[RequireComponent(typeof(PostProcessVolume))]
public class PostProcessSettingsApplierBuiltIn : GraphicSettingsApplier
{
PostProcessVolume PostProcessVolume { get; set; }
GraphicSettingsManager GraphicSettingsManager { get; set; }
private void Awake()
{
GraphicSettingsManager = FindObjectOfType<GraphicSettingsManager>();
PostProcessVolume = GetComponent<PostProcessVolume>();
}
void Start()
{
ApplySettings();
}
public override void ApplySettings()
{
ApplySetting<BloomSetting, Bloom>();
ApplySetting<GrainSetting, Grain>();
ApplySetting<MotionBlurSetting, MotionBlur>();
ApplySetting<AmbientOcclusionSetting, AmbientOcclusion>();
ApplySetting<ChromaticAberrationSetting, ChromaticAberration>();
}
void ApplySetting<TGraphicSetting, TPostProcessEffect>()
where TGraphicSetting : ToggleGraphicSetting
where TPostProcessEffect : PostProcessEffectSettings
{
// Settings cannot be applied when no profile has been set
if (PostProcessVolume.profile == null)
{
return;
}
// Try to get the effect and the settings and enable/disable effect depending on the settings
if (PostProcessVolume.profile.TryGetSettings<TPostProcessEffect>(out var effect) &&
GraphicSettingsManager.TryGet<TGraphicSetting>(out var setting))
{
effect.enabled.value = setting.IsEnabled();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c95cae303388304418e930a12566ccc1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 511d86b6354e6d6408dff5c757484b7f, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
using System.Collections;
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
/// <summary>
/// Applies global <see cref="GraphicSetting"/>'s like the resolution, vsync and general quality settings (if they have been added to the <see cref="GraphicSettingsManager"/>.
/// </summary>
[DisallowMultipleComponent]
[AddComponentMenu("Graphics Control/Global Settings Applier")]
public class GlobalSettingsApplier : GraphicSettingsApplier
{
public override void ApplySettings()
{
ApplyScreenSettings();
ApplyQuality();
ApplyVSync();
}
void ApplyScreenSettings()
{
// Get the current resolution and fullscreen mode
var resolution = Screen.currentResolution;
var fullScreenMode = Screen.fullScreenMode;
// Get the selected resolution setting
if (TryGetSetting<ResolutionSetting>(out var resolutionSetting))
{
resolution = resolutionSetting.GetSelectedOption();
}
// Get the selected fullscreen mode setting
if (TryGetSetting<FullScreenModeSetting>(out var fullScreenModeSetting))
{
fullScreenMode = fullScreenModeSetting.GetSelectedOption();
}
// If any of the settings is available apply resolution/fullScreenMode (if neither ResolutionSetting or FullScreenModeSetting is available, no update is required)
if (resolutionSetting != null || fullScreenModeSetting != null)
{
Screen.SetResolution(resolution.width, resolution.height, fullScreenMode);
}
}
void ApplyVSync()
{
if (TryGetSetting<VSyncSetting>(out var setting))
{
bool isEnabled = setting.GetSelectedOption();
QualitySettings.vSyncCount = isEnabled ? 1 : 0;
}
}
void ApplyQuality()
{
if (TryGetSetting<QualitySetting>(out var setting))
{
int qualityLevel = setting.GetSelectedOption();
QualitySettings.SetQualityLevel(qualityLevel);
}
}
bool TryGetSetting<T>(out T setting) where T : GraphicSetting
{
return GraphicSettingsManager.Instance.TryGet(out setting);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 954b3a7630ee6b84680bd1ae3c6b9393
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 511d86b6354e6d6408dff5c757484b7f, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5a1ee97a15c825e4a88d95ed3b1939ae
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
{
"name": "Ilumisoft.GraphicsControl.URP",
"rootNamespace": "",
"references": [
"Ilumisoft.GraphicsControl",
"Unity.RenderPipelines.Core.Runtime",
"Unity.RenderPipelines.Universal.Runtime"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"POST_PROCESSING_URP"
],
"versionDefines": [
{
"name": "com.unity.render-pipelines.universal",
"expression": "1.0.0",
"define": "POST_PROCESSING_URP"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 43db925e0ab44994eb47f5daa359ecae
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Ilumisoft.GraphicsControl.Rendering.Universal
{
[RequireComponent(typeof(Volume))]
public class PostProcessSettingsApplierURP : GraphicSettingsApplier
{
Volume PostProcessVolume { get; set; }
GraphicSettingsManager GraphicSettingsManager { get; set; }
private void Awake()
{
GraphicSettingsManager = FindObjectOfType<GraphicSettingsManager>();
PostProcessVolume = GetComponent<Volume>();
}
void Start()
{
ApplySettings();
}
public override void ApplySettings()
{
ApplySetting<BloomSetting, Bloom>();
ApplySetting<GrainSetting, FilmGrain>();
ApplySetting<MotionBlurSetting, MotionBlur>();
ApplySetting<ChromaticAberrationSetting, ChromaticAberration>();
}
void ApplySetting<TGraphicSetting, TPostProcessEffect>()
where TGraphicSetting : ToggleGraphicSetting
where TPostProcessEffect : VolumeComponent
{
// Settings cannot be applied when no profile has been set
if (PostProcessVolume.profile == null)
{
return;
}
// Try to get the effect and the settings and enable/disable effect depending on the settings
if (PostProcessVolume.profile.TryGet<TPostProcessEffect>(out var effect) &&
GraphicSettingsManager.TryGet<TGraphicSetting>(out var setting))
{
effect.active = setting.IsEnabled();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad76d02bedb82f341b59136a9c970d17
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 511d86b6354e6d6408dff5c757484b7f, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bb015b73c5432c74bb8c7a98910b5687
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,39 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[CreateAssetMenu(menuName = "Gaphics Control/Configuration", fileName = "Configuration")]
public class Configuration : ScriptableObject
{
public const string ConfigurationPath = "Ilumisoft/Graphics Control/Configuration";
[Header("Prefabs")]
public GameObject GraphicSettingsManager;
[Tooltip("Automatically creates a persistent instance of the Graphic Settings Manager at startup when enabled")]
public bool AutoCreate = true;
public GameObject GraphicSettingsPanel;
public static Configuration Find()
{
var result = Resources.Load<Configuration>(ConfigurationPath);
return result;
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void Initialize()
{
var configuration = Find();
// Automatically create the Graphic Settings Manager at startup
if(configuration.AutoCreate && configuration.GraphicSettingsManager !=null)
{
var instance = Instantiate(configuration.GraphicSettingsManager);
instance.name = configuration.GraphicSettingsManager.name;
DontDestroyOnLoad(instance);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 295992f08e41b134b92787aaf7435315
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[RequireComponent(typeof(GraphicSettingsManager))]
public abstract class GraphicSetting : MonoBehaviour, IGraphicSetting
{
protected GraphicSettingsStorage GraphicSettingsStorage { get; set; }
protected virtual void Awake()
{
GraphicSettingsStorage = GetComponent<GraphicSettingsStorage>();
}
public abstract void Initialize();
public abstract string GetSettingName();
public abstract void LoadSetting();
public abstract void SaveSetting();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7d941ca13646b6047959b3ecbb732da2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
/// <summary>
/// Abstract base class for all <see cref="GraphicSettingsApplier"/>'s.
/// </summary>
public abstract class GraphicSettingsApplier : MonoBehaviour
{
protected virtual void OnEnable()
{
if (GraphicSettingsManager.Instance != null)
{
GraphicSettingsManager.Instance.Register(this);
}
}
protected virtual void OnDisable()
{
if (GraphicSettingsManager.Instance != null)
{
GraphicSettingsManager.Instance.Unregister(this);
}
}
public abstract void ApplySettings();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 664d217953f234541af976eb1ea845c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
namespace Ilumisoft.GraphicsControl
{
public abstract class GraphicSettingsManager : SingletonBehaviour<GraphicSettingsManager>
{
protected List<GraphicSettingsApplier> GraphicSettingsAppliers { get; set; } = new();
public abstract List<GraphicSetting> GetGraphicSettings();
public abstract T Get<T>() where T : GraphicSetting;
public abstract bool TryGet<T>(out T graphicSetting) where T : GraphicSetting;
public abstract void LoadSettings();
public abstract void SaveSettings();
public abstract void ApplySettings();
public void Register(GraphicSettingsApplier graphicSettingsApplier)
{
if(graphicSettingsApplier != null && !GraphicSettingsAppliers.Contains(graphicSettingsApplier))
{
GraphicSettingsAppliers.Add(graphicSettingsApplier);
}
}
public void Unregister(GraphicSettingsApplier graphicSettingsApplier)
{
GraphicSettingsAppliers.Remove(graphicSettingsApplier);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09959d570680f234e97182aa1882ecaa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
public abstract class GraphicSettingsStorage : MonoBehaviour
{
public abstract bool GetBool(string key, bool defaultValue);
public abstract float GetFloat(string key, float defaultValue);
public abstract int GetInt(string key, int defaultValue);
public abstract string GetString(string key, string defaultValue);
public abstract void SetBool(string key, bool value);
public abstract void SetFloat(string key, float value);
public abstract void SetInt(string key, int value);
public abstract void SetString(string key, string value);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 786eafc0a79685247be430eff085729a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
namespace Ilumisoft.GraphicsControl
{
public interface IGraphicSetting
{
void Initialize();
string GetSettingName();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 57b76debcf750ed4fa5e4ceb1258f03d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace Ilumisoft.GraphicsControl
{
public interface IMultiOptionGraphicSetting
{
List<string> GetOptionNames();
int GetIndex();
void SetIndex(int index);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3b02f234e94a07438f1760e688082fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
namespace Ilumisoft.GraphicsControl
{
public abstract class MultiOptionGraphicSetting<T> : GraphicSetting, IMultiOptionGraphicSetting
{
/// <summary>
/// Option table holding all available options for the graphic setting (e.g. all available resolutions for the resolution setting)
/// </summary>
protected OptionTable<T> OptionTable = new();
/// <summary>
/// The index of the selected option (e.g. the selected resolution)
/// </summary>
int selectedIndex;
/// <summary>
/// Adds a new option to the option table
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
protected void AddOption(string name, T value)
{
OptionTable.Add(name, value);
}
/// <summary>
/// Gets the names of all available options
/// </summary>
/// <returns></returns>
public List<string> GetOptionNames()
{
return OptionTable.GetNames();
}
/// <summary>
/// Sets the selected index
/// </summary>
/// <param name="index"></param>
public void SetIndex(int index)
{
this.selectedIndex = index;
}
/// <summary>
/// Gets the index of the selected option
/// </summary>
/// <returns></returns>
public int GetIndex()
{
return selectedIndex;
}
/// <summary>
/// Selects the given option. If the option is not available, the defaultIndex will be used to pick an option from the option table
/// </summary>
/// <param name="value"></param>
/// <param name="defaultIndex"></param>
protected void SelectOption(T value, int defaultIndex = 0)
{
if (TryGetIndex(value, out var index))
{
SetIndex(index);
}
else
{
SetIndex(defaultIndex);
}
}
/// <summary>
/// Selects the option that fulfills the given predicate. If no option applies, the defaultIndex will be used to pick an option from the option table
/// </summary>
/// <param name="predicate"></param>
/// <param name="defaultIndex"></param>
protected void SelectOption(Predicate<T> predicate, int defaultIndex = 0)
{
if(TryGetIndex(predicate, out var index))
{
SetIndex(index);
}
else
{
SetIndex(defaultIndex);
}
}
/// <summary>
/// Tries to get the index of the given option
/// </summary>
/// <param name="option"></param>
/// <param name="index"></param>
/// <returns></returns>
protected bool TryGetIndex(T option, out int index)
{
return TryGetIndex(entry => entry.Equals(option), out index);
}
/// <summary>
/// Tries to get the first index that fulfills the given predicate
/// </summary>
/// <param name="predicate"></param>
/// <param name="index"></param>
/// <returns></returns>
protected bool TryGetIndex(Predicate<T> predicate, out int index)
{
index = -1;
var entries = OptionTable.GetValues();
for (int i = 0; i < entries.Count; i++)
{
if (predicate(entries[i]))
{
index = i;
return true;
}
}
return false;
}
/// <summary>
/// Gets the currently selected option
/// </summary>
/// <returns></returns>
public T GetSelectedOption() => OptionTable.GetValue(selectedIndex);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 58469bbd4c3c3cb4fa41792392bf2ca4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Linq;
namespace Ilumisoft.GraphicsControl
{
public class OptionTable<T>
{
public struct OptionEntry
{
public string Name;
public T Value;
public OptionEntry(string name, T value)
{
Name = name;
Value = value;
}
}
List<OptionEntry> entries = new();
public void Add(string name, T value)
{
entries.Add(new OptionEntry(name, value));
}
public List<string> GetNames() => entries.Select(x=>x.Name).ToList();
public List<T> GetValues() => entries.Select(x => x.Value).ToList();
public T GetValue(int index) => entries[index].Value;
public string GetName(int index) => entries[index].Name;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bad7acddd156c9a4f88746f9c6bd4eb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
public abstract class SingletonBehaviour<T> : MonoBehaviour where T : SingletonBehaviour<T>
{
protected static T instance = null;
/// <summary>
/// Gets the active instance of the singleton
/// </summary>
public static T Instance => instance;
/// <summary>
/// Creates the instance of the singleton
/// </summary>
protected virtual void Awake()
{
//Dont allow multiple instances of a singleton
if (instance != null)
{
Debug.LogError(string.Format("Multiple instances of {0} are not allowed", typeof(T)));
Destroy(this);
return;
}
instance = (T)this;
}
/// <summary>
/// Resets the static instance when the object gets destroyed.
/// This is necessary because static fields are not resolved by the garbage collector.
/// </summary>
protected virtual void OnDestroy()
{
if (instance == this)
{
instance = null;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a83b4774cf3525943838f3b397160952
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
/// <summary>
/// Toggle Graphic Settings can either be on or off.
/// This for example used for Bloom, Motion Blur or Grain Post Processing effects.
/// </summary>
public abstract class ToggleGraphicSetting : MultiOptionGraphicSetting<bool>
{
[Tooltip("Whether the option should be enabled by default or not")]
public bool IsEnabledByDefault = true;
public override void Initialize()
{
// Toggle graphic settings can be eitehr on or off
AddOption("Off", false);
AddOption("On", true);
SelectOption(IsEnabledByDefault);
}
/// <summary>
/// Returns true if the setting is on, false otherwise
/// </summary>
/// <returns></returns>
public bool IsEnabled() => GetSelectedOption();
/// <summary>
/// Loads the stored settings
/// </summary>
public override void LoadSetting()
{
bool value = GraphicSettingsStorage.GetBool(GetSettingName(), IsEnabled());
SelectOption(value);
}
/// <summary>
/// Saves the selected option
/// </summary>
public override void SaveSetting()
{
GraphicSettingsStorage.SetBool(GetSettingName(), IsEnabled());
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a77a8124e4600dc46a0fa337984bfb25
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,100 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[DisallowMultipleComponent()]
[DefaultExecutionOrder(-1)]
public class DefaultGraphicSettingsManager : GraphicSettingsManager
{
List<GraphicSetting> settings = new();
public override List<GraphicSetting> GetGraphicSettings() => settings;
public override T Get<T>()
{
foreach (var setting in settings)
{
if (setting is T targetSetting)
{
return targetSetting;
}
}
return default;
}
public override bool TryGet<T>(out T graphicSetting)
{
foreach (var setting in settings)
{
if (setting is T targetSetting)
{
graphicSetting = targetSetting;
return true;
}
}
graphicSetting = default;
return false;
}
protected override void Awake()
{
base.Awake();
settings = GetComponents<GraphicSetting>().ToList();
}
private void Start()
{
foreach (var setting in settings)
{
setting.Initialize();
}
LoadSettings();
ApplySettings();
}
public override void LoadSettings()
{
foreach (var setting in settings)
{
if (setting is GraphicSetting storeable)
{
storeable.LoadSetting();
}
}
}
public override void SaveSettings()
{
foreach (var setting in settings)
{
if (setting is GraphicSetting storeable)
{
storeable.SaveSetting();
}
}
}
public override void ApplySettings()
{
foreach (var settingApplier in GraphicSettingsAppliers)
{
settingApplier.ApplySettings();
}
}
private void Reset()
{
if(!TryGetComponent<GraphicSettingsStorage>(out _))
{
gameObject.AddComponent<DefaultGraphicSettingsStorage>();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d746c2c65da7e444cbdffb049efbcd08
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: e7051facbc4e30c4d9a591e094d964c6, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
/// <summary>
/// Default settings storage using PlayerPrefs. You can write your own storage class by extending the <see cref="GraphicSettingsStorage"/>
/// </summary>
[DisallowMultipleComponent()]
public class DefaultGraphicSettingsStorage : GraphicSettingsStorage
{
public override void SetFloat(string key, float value) => PlayerPrefs.SetFloat(key, value);
public override void SetInt(string key, int value) => PlayerPrefs.SetInt(key, value);
public override void SetString(string key, string value) => PlayerPrefs.SetString(key, value);
public override void SetBool(string key, bool value) => PlayerPrefs.SetInt(key, value ? 1 : 0);
public override float GetFloat(string key, float defaultValue) => PlayerPrefs.GetFloat(key, defaultValue);
public override int GetInt(string key, int defaultValue) => PlayerPrefs.GetInt(key, defaultValue);
public override string GetString(string key, string defaultValue) => PlayerPrefs.GetString(key, defaultValue);
public override bool GetBool(string key, bool defaultValue)
{
int value = PlayerPrefs.GetInt(key, defaultValue ? 1 : 0);
return value != 0;
}
private void OnDisable()
{
PlayerPrefs.Save();
}
private void OnApplicationFocus(bool focus)
{
if(!focus)
{
PlayerPrefs.Save();
}
}
private void OnApplicationPause(bool pause)
{
PlayerPrefs.Save();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dd455d9a41581ae4d9e05ce3218d7ae7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7dad77b6f99af7c449e384b57c7b7519, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 66920749c7de7374c85a26cdaa220366
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using UnityEditor;
namespace Ilumisoft.GraphicsControl.Editor
{
[CustomEditor(typeof(GraphicSetting), true)]
public class GraphicSettingEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUI.BeginChangeCheck();
DrawPropertiesExcluding(serializedObject, "m_Script");
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f87684af450126c44896e4b52fbd408e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using UnityEditor;
using UnityEngine;
namespace Ilumisoft.GraphicsControl.Editor
{
class GraphicsCotnrolSettingsProvider
{
[SettingsProvider]
public static SettingsProvider CreateStartupProfileConfigurationProvider() => CreateProvider("Project/Graphics Control", Configuration.Find());
static SettingsProvider CreateProvider(string settingsWindowPath, Object asset)
{
var provider = AssetSettingsProvider.CreateProviderFromObject(settingsWindowPath, asset);
provider.keywords = SettingsProvider.GetSearchKeywordsFromSerializedObject(new SerializedObject(asset));
return provider;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7039f079b3dfc6b45b850a93d88857a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
{
"name": "Ilumisoft.GraphicsControl.Editor",
"rootNamespace": "",
"references": [
"GUID:7f595fd175e67274183d17fac15b74c9"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e85b0f2ab2cb4fd4396d9ce383d836d9
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using UnityEditor;
using UnityEngine;
namespace Ilumisoft.GraphicsControl.Editor
{
public static class MenuItems
{
// Add a menu item to create custom GameObjects.
// Priority 1 ensures it is grouped with the other menu items of the same kind
// and propagated to the hierarchy dropdown and hierarchy context menus.
[MenuItem("GameObject/UI/Graphic Settings Panel", false, 10)]
static void CreateCustomGameObject(MenuCommand menuCommand)
{
Configuration configuration = Configuration.Find();
if(configuration.GraphicSettingsPanel == null)
{
Debug.LogWarning("Could not create Graphic Settings Panel, because no prefab has been assigned in the project settings.");
return;
}
// Create a custom game object
GameObject go = PrefabUtility.InstantiatePrefab(configuration.GraphicSettingsPanel) as GameObject;// new GameObject("Graphic Settings Panel");
go.name = "Graphic Settings Panel";
// Ensure it gets reparented if this was a context click (otherwise does nothing)
GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
// Register the creation in the undo system
Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
Selection.activeObject = go;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a00eef7e69de0bd46a508e735bcde211
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
{
"name": "Ilumisoft.GraphicsControl",
"rootNamespace": "",
"references": [
"GUID:6055be8ebefd69e48b49212b09b47b2f"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7f595fd175e67274183d17fac15b74c9
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bd6c5fe9f2f5a5e4694c7d6100933e77
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[System.Serializable, System.Flags]
public enum FullScreenModeOptions
{
ExclusiveFullScreen = 1,
FullScreenWindow = 2,
MaximizedWindow = 4,
Windowed = 8,
Everything = 0b1111
}
[DisallowMultipleComponent]
[AddComponentMenu("Graphics Control/Settings/Full Screen Mode Setting")]
public class FullScreenModeSetting : MultiOptionGraphicSetting<FullScreenMode>
{
[SerializeField]
FullScreenModeOptions EnabledOptions = FullScreenModeOptions.Everything;
public FullScreenMode DefaultOption = FullScreenMode.ExclusiveFullScreen;
public override void Initialize()
{
AddOptionIfEnabled(FullScreenMode.Windowed);
AddOptionIfEnabled(FullScreenMode.FullScreenWindow);
AddOptionIfEnabled(FullScreenMode.MaximizedWindow);
AddOptionIfEnabled(FullScreenMode.ExclusiveFullScreen);
// Always add the default option if not already added
if(!IsEnabled(DefaultOption))
{
AddOption(GetDisplayName(DefaultOption), DefaultOption);
}
SelectOption(DefaultOption);
}
bool IsEnabled(FullScreenMode fullScreenMode)
{
return fullScreenMode switch
{
FullScreenMode.ExclusiveFullScreen => EnabledOptions.HasFlag(FullScreenModeOptions.ExclusiveFullScreen),
FullScreenMode.FullScreenWindow => EnabledOptions.HasFlag(FullScreenModeOptions.FullScreenWindow),
FullScreenMode.MaximizedWindow => EnabledOptions.HasFlag(FullScreenModeOptions.MaximizedWindow),
FullScreenMode.Windowed => EnabledOptions.HasFlag(FullScreenModeOptions.Windowed),
_ => false,
};
}
/// <summary>
/// Adds the given option to the option table if it has been set in the EnabledOptions
/// </summary>
/// <param name="value"></param>
/// <param name="option"></param>
void AddOptionIfEnabled(FullScreenMode option)
{
if (IsEnabled(option))
{
AddOption(GetDisplayName(option), option);
}
}
/// <summary>
/// Gets the display name the given <see cref="FullScreenMode"/>
/// </summary>
/// <param name="fullScreenMode"></param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
string GetDisplayName(FullScreenMode fullScreenMode) => fullScreenMode switch
{
FullScreenMode.ExclusiveFullScreen => "Exclusive Fullscreen",
FullScreenMode.FullScreenWindow => "Full Screen Window",
FullScreenMode.MaximizedWindow => "Maximized Window",
FullScreenMode.Windowed => "Window",
_ => throw new System.NotImplementedException(),
};
public override string GetSettingName() => "Full Screen Mode";
public override void SaveSetting()
{
GraphicSettingsStorage.SetInt("Full Screen Mode", (int)GetSelectedOption());
}
public override void LoadSetting()
{
int value = GraphicSettingsStorage.GetInt("Full Screen Mode", (int)DefaultOption);
SelectOption((FullScreenMode)value);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43e4b0176d7b9c8458e46f9587b50868
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e9ec92119fc6ebe458677efe991f486b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[AddComponentMenu("Graphics Control/Settings/Ambient Occlusion Setting")]
[DisallowMultipleComponent()]
public class AmbientOcclusionSetting : ToggleGraphicSetting
{
public override string GetSettingName() => "Ambient Occlusion";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: faecca85295be1440be1629220477394
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[AddComponentMenu("Graphics Control/Settings/Bloom Setting")]
[DisallowMultipleComponent()]
public class BloomSetting : ToggleGraphicSetting
{
public override string GetSettingName() => "Bloom";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d77ee60ff507582488de1b21409b4ffd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[AddComponentMenu("Graphics Control/Settings/Chromatic Aberration Setting")]
[DisallowMultipleComponent()]
public class ChromaticAberrationSetting : ToggleGraphicSetting
{
public override string GetSettingName() => "Chromatic Aberration";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 06578898b8ae5ba408a50bdc92f95b6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[AddComponentMenu("Graphics Control/Settings/Grain Setting")]
[DisallowMultipleComponent()]
public class GrainSetting : ToggleGraphicSetting
{
public override string GetSettingName() => "Grain";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a34ac59a2b342ac4d95043f9d43cd773
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[AddComponentMenu("Graphics Control/Settings/Motion Blur Setting")]
[DisallowMultipleComponent()]
public class MotionBlurSetting : ToggleGraphicSetting
{
public override string GetSettingName() => "Motion Blur";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab1af6deb663e5047800769e92315fb1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[DisallowMultipleComponent]
[AddComponentMenu("Graphics Control/Settings/Quality Setting")]
public class QualitySetting : MultiOptionGraphicSetting<int>
{
public override void Initialize()
{
var names = QualitySettings.names;
for (int i = 0; i < names.Length; i++)
{
AddOption(names[i], i);
}
SetIndex(QualitySettings.GetQualityLevel());
}
public override string GetSettingName() => "Quality";
public override void SaveSetting()
{
GraphicSettingsStorage.SetInt(key: GetSettingName(), value: GetIndex());
}
public override void LoadSetting()
{
// The key of the setting
string key = GetSettingName();
// Default value used as a fallback option
int defaultValue = QualitySettings.GetQualityLevel();
// Get the stored value
int storedValue = GraphicSettingsStorage.GetInt(key, defaultValue);
// Apply the stored value
SetIndex(storedValue);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0db9cdd8379cfca4b8d2230daaacfd5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[DisallowMultipleComponent]
[AddComponentMenu("Graphics Control/Settings/Resolution Setting")]
public class ResolutionSetting : MultiOptionGraphicSetting<Resolution>
{
public override void Initialize()
{
var supportedResolutions = Screen.resolutions;
foreach (var resolution in supportedResolutions)
{
AddOption($"{resolution.width}x{resolution.height}", resolution);
}
SelectOption(r => AreEqual(r, Screen.currentResolution), defaultIndex: 0);
}
public override string GetSettingName() => "Resolution";
public override void SaveSetting()
{
GraphicSettingsStorage.SetInt("Resolution_Width", GetSelectedOption().width);
GraphicSettingsStorage.SetInt("Resolution_Height", GetSelectedOption().height);
}
public override void LoadSetting()
{
var currentResolution = Screen.currentResolution;
Resolution resolution = new()
{
width = GraphicSettingsStorage.GetInt("Resolution_Width", currentResolution.width),
height = GraphicSettingsStorage.GetInt("Resolution_Height", currentResolution.height)
};
SelectOption(r => AreEqual(r, resolution), defaultIndex: 0);
}
bool AreEqual(Resolution a, Resolution b)
{
return a.width == b.width && a.height == b.height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 438c606e3c3e3b440bbc978d859f759b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Ilumisoft.GraphicsControl
{
[DisallowMultipleComponent]
[AddComponentMenu("Graphics Control/Settings/VSync Setting")]
public class VSyncSetting : ToggleGraphicSetting
{
public override string GetSettingName() => "VSync";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f677a30b5f601d4aac04bd65aeb366a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 688fa00e4a40a034eacc71c7a11ff9d0, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d641d93a2afc3454cb4a61f18a43067a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
using UnityEngine;
using UnityEngine.UI;
namespace Ilumisoft.GraphicsControl.UI
{
[RequireComponent(typeof(Button))]
public class ApplySettingsButton : MonoBehaviour
{
Button Button { get; set; }
private void Awake()
{
Button = GetComponent<Button>();
Button.onClick.AddListener(OnClick);
}
private void OnClick()
{
GraphicSettingsManager.Instance.ApplySettings();
GraphicSettingsManager.Instance.SaveSettings();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 17e9f2e223bd22a4fabb136cd3f16ba9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Ilumisoft.GraphicsControl.UI
{
/// <summary>
/// <see cref="UnityEngine.UI.ScrollRect"/> does not automatically scroll up or down when using the keyboard or gamepad.
/// This class automatically handles scrolling, by scrolling towards the selected element of a <see cref="UnityEngine.UI.ScrollRect"/> when selection changes.
/// </summary>
[RequireComponent(typeof(ScrollRect))]
[DefaultExecutionOrder(1)]
public class AutoScrollHandler : MonoBehaviour
{
/// <summary>
/// The currently selected game object
/// </summary>
GameObject selected = null;
/// <summary>
/// The previously selected game object
/// </summary>
GameObject previousSelected = null;
[SerializeField]
[Tooltip("Scroll speed when changing selection")]
float scrollSpeed = 5.0f;
/// <summary>
/// Reference to the controlled <see cref="UnityEngine.UI.ScrollRect"/> component
/// </summary>
ScrollRect ScrollRect { get; set; }
private void Awake()
{
ScrollRect = GetComponent<ScrollRect>();
}
private void Start()
{
selected = EventSystem.current.currentSelectedGameObject;
previousSelected = selected;
// Auto focus the first element
ScrollRect.verticalScrollbar.value = 1;
}
void Update()
{
selected = EventSystem.current.currentSelectedGameObject;
// Check whether the selection has changed
if (selected != previousSelected)
{
previousSelected = selected;
if (selected != null)
{
OnSelectionChanged();
}
}
}
/// <summary>
/// Scroll towards the selected element when the selection has changed
/// </summary>
void OnSelectionChanged()
{
if (TryGetIndex(selected, out var index))
{
StopAllCoroutines();
StartCoroutine(ScrollTowards(index));
}
}
/// <summary>
/// Tries to get the index of the given element in the content
/// </summary>
/// <param name="element"></param>
/// <param name="index"></param>
/// <returns></returns>
bool TryGetIndex(GameObject element, out int index)
{
index = 0;
foreach (Transform child in ScrollRect.content)
{
if (element == child.gameObject)
{
return true;
}
index++;
}
return false;
}
/// <summary>
/// Scrolls towards the content element with the given index
/// </summary>
/// <param name="targetIndex"></param>
/// <returns></returns>
IEnumerator ScrollTowards(int targetIndex)
{
var scrollbar = ScrollRect.verticalScrollbar;
float target = 1 - targetIndex / (float)(ScrollRect.content.childCount - 1);
while (Mathf.Abs(scrollbar.value - target) > 0.01f)
{
scrollbar.value = Mathf.MoveTowards(scrollbar.value, target, scrollSpeed * Time.deltaTime);
yield return null;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 458c41eab5f10bb45926d21f44fa218d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,140 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace Ilumisoft.GraphicsControl.UI
{
/// <summary>
/// Default implementation of the <see cref="MultiOptionSelector"/>.
/// </summary>
[RequireComponent(typeof(AudioSource))]
public class DefaultMultiOptionSelector : MultiOptionSelector, IMoveHandler
{
[Header("Text")]
[SerializeField]
TMPro.TextMeshProUGUI labelText;
[SerializeField]
TMPro.TextMeshProUGUI valueText;
[Header("Audio")]
[SerializeField]
AudioClip selectionChangedSFX;
[SerializeField]
AudioClip verticalMovementSFX;
[Header("Settings")]
[Tooltip("When enabled, the selector will loop through the options when reaching the limits.")]
[SerializeField]
bool loop = true;
/// <summary>
/// The index of the current selection
/// </summary>
int currentIndex = 0;
/// <summary>
/// A list of all possible values
/// </summary>
List<string> Values;
/// <summary>
/// Event being invoked when the index has been changed
/// </summary>
UnityAction<int> OnSelectionChanged { get; set; }
/// <summary>
/// Reference to the Audio Source Component
/// </summary>
AudioSource AudioSource { get; set; }
private void Awake()
{
AudioSource = GetComponent<AudioSource>();
}
public override void Initialize(string label, List<string> values, int index, UnityAction<int> onSelectionChanged)
{
OnSelectionChanged += onSelectionChanged;
labelText.text = label;
Values = values;
currentIndex = index;
UpdateValueText();
}
public void OnMove(AxisEventData eventData)
{
Move(eventData.moveVector);
}
/// <summary>
/// Selects the next option
/// </summary>
public void SelectNextOption() => Move(Vector2.right);
/// <summary>
/// Selects the previous Option
/// </summary>
public void SelectPreviousOption() => Move(Vector2.left);
private void Move(Vector2 direction)
{
int previousIndex = currentIndex;
// Increase the index when moving to the right
if (direction.x > 0)
{
currentIndex++;
if (currentIndex >= Values.Count)
{
currentIndex = loop ? 0 : Values.Count - 1;
}
}
// Decrease the index when moving to the left
if (direction.x < 0)
{
currentIndex--;
if (currentIndex < 0)
{
currentIndex = loop ? Values.Count - 1 : 0;
}
}
if (direction.y != 0)
{
if (AudioSource != null && verticalMovementSFX != null)
{
PlayAudioFeedback(verticalMovementSFX);
}
}
// Check whether the index has changed
if (previousIndex != currentIndex)
{
OnSelectionChanged?.Invoke(currentIndex);
UpdateValueText();
PlayAudioFeedback(selectionChangedSFX);
}
}
void UpdateValueText()
{
valueText.text = Values[currentIndex];
}
void PlayAudioFeedback(AudioClip audioClip)
{
if (AudioSource != null && audioClip != null)
{
AudioSource.PlayOneShot(audioClip);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 552bbb859029b3642848169db0e28eab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Ilumisoft.GraphicsControl.UI
{
public class GraphicSettingsPanel : MonoBehaviour
{
[SerializeField]
[Tooltip("The parent object all UI selectors will be added to. This would be for example the content GameObject of a ScrollView")]
Transform container;
[SerializeField]
MultiOptionSelector MultiOptionSelectorPrefab;
/// <summary>
/// Reference to the Graphic Settings Manager
/// </summary>
GraphicSettingsManager GraphicSettingsManager { get; set; }
private void Awake()
{
GraphicSettingsManager = FindObjectOfType<GraphicSettingsManager>();
}
private void Start()
{
// Get all graphic settings
var settings = GraphicSettingsManager.GetGraphicSettings();
// List holding all selectors
List<GameObject> selectors = new();
// Create the appropriate selector UI elements for each setting
foreach (var setting in settings)
{
if (setting is IMultiOptionGraphicSetting multiOptionSettings)
{
var multiOptionSelector = Instantiate(MultiOptionSelectorPrefab, container);
multiOptionSelector.Initialize(setting.GetSettingName(), multiOptionSettings.GetOptionNames(), multiOptionSettings.GetIndex(), multiOptionSettings.SetIndex);
selectors.Add(multiOptionSelector.gameObject);
}
}
// Automatically select the first element
if (selectors.Count > 0)
{
EventSystem.current.SetSelectedGameObject(selectors[0]);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3074d3c0feba9fc4f84a74849ac39d65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: cde92c4be2e51894bb915456c3d44460, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
{
"name": "Ilumisoft.GraphicsControl.UI",
"rootNamespace": "",
"references": [
"GUID:7f595fd175e67274183d17fac15b74c9",
"GUID:6055be8ebefd69e48b49212b09b47b2f"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0f167fb3726278c4481b9f96f60458bd
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Ilumisoft.GraphicsControl.UI
{
public abstract class MultiOptionSelector : MonoBehaviour
{
public abstract void Initialize(string label, List<string> values, int index, UnityAction<int> onSelectionChanged);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e948756a0947b2d478b0285f4ab1d359
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace Ilumisoft.GraphicsControl.UI
{
public class PointerDownHandler : MonoBehaviour, IPointerDownHandler
{
public UnityEvent OnClick = new();
public void OnPointerDown(PointerEventData eventData)
{
OnClick.Invoke();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f1b5a37363ca0c468220aeff6833044
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: