├── .GitHubResources └── Banner.png ├── .gitignore ├── Editor.meta ├── Editor ├── AssetUtility.cs ├── AssetUtility.cs.meta ├── DefaultValueDrawer.cs ├── DefaultValueDrawer.cs.meta ├── ReferenceFixUtility.cs ├── ReferenceFixUtility.cs.meta ├── Resources.meta ├── Resources │ ├── Icon Asset.png │ ├── Icon Asset.png.meta │ ├── Icon GUI.png │ ├── Icon GUI.png.meta │ ├── Icon Group.png │ └── Icon Group.png.meta ├── SettingBaseEditor.cs ├── SettingBaseEditor.cs.meta ├── SettingBasePropertyDrawer.cs ├── SettingBasePropertyDrawer.cs.meta ├── SettingReferenceDrawer.cs ├── SettingReferenceDrawer.cs.meta ├── SettingsEditorWindow.cs ├── SettingsEditorWindow.cs.meta ├── Zenvin.Settings.Editor.asmdef └── Zenvin.Settings.Editor.asmdef.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── Framework.meta ├── Framework │ ├── AssemblyAttributes.cs │ ├── AssemblyAttributes.cs.meta │ ├── Base.meta │ ├── Base │ │ ├── ComposedFrameworkObject.cs │ │ ├── ComposedFrameworkObject.cs.meta │ │ ├── FrameworkObject.cs │ │ ├── FrameworkObject.cs.meta │ │ ├── NamedFrameworkObject.cs │ │ ├── NamedFrameworkObject.cs.meta │ │ ├── VisualHierarchyObject.cs │ │ └── VisualHierarchyObject.cs.meta │ ├── Components.meta │ ├── Components │ │ ├── ComponentCollection.cs │ │ ├── ComponentCollection.cs.meta │ │ ├── FrameworkComponent.cs │ │ ├── FrameworkComponent.cs.meta │ │ ├── ISettingEventReceiver.cs │ │ ├── ISettingEventReceiver.cs.meta │ │ ├── SettingComponent.cs │ │ ├── SettingComponent.cs.meta │ │ ├── TypedFrameworkComponent.cs │ │ ├── TypedFrameworkComponent.cs.meta │ │ ├── ValueChangingArgs.cs │ │ └── ValueChangingArgs.cs.meta │ ├── DefaultValueAttribute.cs │ ├── DefaultValueAttribute.cs.meta │ ├── DynamicSettingReference.cs │ ├── DynamicSettingReference.cs.meta │ ├── Presets.meta │ ├── Presets │ │ ├── IEvaluatablePresetTarget.cs │ │ ├── IEvaluatablePresetTarget.cs.meta │ │ ├── IPresetTarget.cs │ │ ├── IPresetTarget.cs.meta │ │ ├── PresetSettingsGroup.cs │ │ └── PresetSettingsGroup.cs.meta │ ├── Serialization.meta │ ├── Serialization │ │ ├── Binary.meta │ │ ├── Binary │ │ │ ├── BinaryFileSerializer.cs │ │ │ ├── BinaryFileSerializer.cs.meta │ │ │ ├── BinarySerializer.cs │ │ │ ├── BinarySerializer.cs.meta │ │ │ ├── SerializationUtility.cs │ │ │ ├── SerializationUtility.cs.meta │ │ │ ├── ValuePacket.Read.cs │ │ │ ├── ValuePacket.Read.cs.meta │ │ │ ├── ValuePacket.Write.cs │ │ │ ├── ValuePacket.Write.cs.meta │ │ │ ├── ValuePacket.cs │ │ │ └── ValuePacket.cs.meta │ │ ├── IAsyncSerializer.cs │ │ ├── IAsyncSerializer.cs.meta │ │ ├── IAsyncSerializerCallbackReceiver.cs │ │ ├── IAsyncSerializerCallbackReceiver.cs.meta │ │ ├── ISerializable.cs │ │ ├── ISerializable.cs.meta │ │ ├── ISerializer.cs │ │ ├── ISerializer.cs.meta │ │ ├── ISerializerCallbackReceiver.cs │ │ ├── ISerializerCallbackReceiver.cs.meta │ │ ├── JSON.meta │ │ └── JSON │ │ │ ├── JsonFileSerializer.cs │ │ │ ├── JsonFileSerializer.cs.meta │ │ │ ├── JsonSerializer.cs │ │ │ └── JsonSerializer.cs.meta │ ├── SettingBase.cs │ ├── SettingBase.cs.meta │ ├── SettingReference.cs │ ├── SettingReference.cs.meta │ ├── SettingVisibility.cs │ ├── SettingVisibility.cs.meta │ ├── Settings.meta │ ├── Settings │ │ ├── BoolSetting.cs │ │ ├── BoolSetting.cs.meta │ │ ├── FloatSetting.cs │ │ ├── FloatSetting.cs.meta │ │ ├── IntSetting.cs │ │ ├── IntSetting.cs.meta │ │ ├── StringSetting.cs │ │ ├── StringSetting.cs.meta │ │ ├── ValueArraySetting.cs │ │ └── ValueArraySetting.cs.meta │ ├── SettingsAsset.Async.cs │ ├── SettingsAsset.Async.cs.meta │ ├── SettingsAsset.Editor.cs │ ├── SettingsAsset.Editor.cs.meta │ ├── SettingsAsset.cs │ ├── SettingsAsset.cs.meta │ ├── SettingsGroup.cs │ ├── SettingsGroup.cs.meta │ ├── Zenvin.Settings.Framework.asmdef │ └── Zenvin.Settings.Framework.asmdef.meta ├── Loading.meta ├── Loading │ ├── IGroupFactory.cs │ ├── IGroupFactory.cs.meta │ ├── IGroupIconLoader.cs │ ├── IGroupIconLoader.cs.meta │ ├── ISettingFactory.cs │ ├── ISettingFactory.cs.meta │ ├── PrimitiveFactories.cs │ ├── PrimitiveFactories.cs.meta │ ├── RuntimeLoaderHelpers.cs │ ├── RuntimeLoaderHelpers.cs.meta │ ├── RuntimeSettingLoader.cs │ ├── RuntimeSettingLoader.cs.meta │ ├── SettingLoaderOptions.cs │ ├── SettingLoaderOptions.cs.meta │ ├── SettingsImportData.cs │ ├── SettingsImportData.cs.meta │ ├── Zenvin.Settings.Loading.asmdef │ └── Zenvin.Settings.Loading.asmdef.meta ├── StringValuePair.cs ├── StringValuePair.cs.meta ├── UI.meta ├── UI │ ├── AssignedSettingControl.cs │ ├── AssignedSettingControl.cs.meta │ ├── SettingControl.cs │ ├── SettingControl.cs.meta │ ├── SettingControlCollection.cs │ ├── SettingControlCollection.cs.meta │ ├── Zenvin.Settings.UI.asmdef │ └── Zenvin.Settings.UI.asmdef.meta ├── UpdateValueMode.cs ├── UpdateValueMode.cs.meta ├── Utility.meta ├── Utility │ ├── EnumUtility.cs │ ├── EnumUtility.cs.meta │ ├── HasDeviatingDefaultValueAttribute.cs │ ├── HasDeviatingDefaultValueAttribute.cs.meta │ ├── Zenvin.Settings.Utility.asmdef │ └── Zenvin.Settings.Utility.asmdef.meta ├── Zenvin.Settings.asmdef └── Zenvin.Settings.asmdef.meta ├── Samples~ ├── Components.meta ├── Components │ ├── BubbleUpChangeEvents.cs │ ├── BubbleUpChangeEvents.cs.meta │ ├── ConditionalVisibility.cs │ └── ConditionalVisibility.cs.meta ├── Keybind Setting.meta ├── Keybind Setting │ ├── Assets.meta │ ├── Assets │ │ ├── Icons8.meta │ │ ├── Icons8 │ │ │ ├── CREDITS.txt │ │ │ ├── CREDITS.txt.meta │ │ │ ├── Restart.png │ │ │ └── Restart.png.meta │ │ ├── Rebind Operation Settings.asset │ │ └── Rebind Operation Settings.asset.meta │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── Keybind Control.prefab │ │ ├── Keybind Control.prefab.meta │ │ ├── Keybind Popup.prefab │ │ └── Keybind Popup.prefab.meta │ ├── Scripts.meta │ └── Scripts │ │ ├── Editor.meta │ │ ├── Editor │ │ ├── InputActionBindingPropertyDrawer.cs │ │ └── InputActionBindingPropertyDrawer.cs.meta │ │ ├── Runtime.meta │ │ └── Runtime │ │ ├── InputActionBinding.cs │ │ ├── InputActionBinding.cs.meta │ │ ├── KeybindControl.cs │ │ ├── KeybindControl.cs.meta │ │ ├── KeybindControlBase.cs │ │ ├── KeybindControlBase.cs.meta │ │ ├── KeybindPopup.cs │ │ ├── KeybindPopup.cs.meta │ │ ├── KeybindPopupBase.cs │ │ ├── KeybindPopupBase.cs.meta │ │ ├── KeybindSetting.cs │ │ ├── KeybindSetting.cs.meta │ │ ├── KeybindUtility.cs │ │ ├── KeybindUtility.cs.meta │ │ ├── Keybinding.cs │ │ ├── Keybinding.cs.meta │ │ ├── RebindOperationSettings.cs │ │ └── RebindOperationSettings.cs.meta ├── Localization Setting.meta ├── Localization Setting │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── Localization Control.prefab │ │ └── Localization Control.prefab.meta │ ├── Scripts.meta │ └── Scripts │ │ ├── Editor.meta │ │ ├── Editor │ │ ├── LocaleSelectorPropertyDrawer.cs │ │ └── LocaleSelectorPropertyDrawer.cs.meta │ │ ├── LocaleSelectorAttribute.cs │ │ ├── LocaleSelectorAttribute.cs.meta │ │ ├── LocalizationControl.cs │ │ ├── LocalizationControl.cs.meta │ │ ├── LocalizationControlFactory.cs │ │ ├── LocalizationControlFactory.cs.meta │ │ ├── LocalizationSetting.cs │ │ ├── LocalizationSetting.cs.meta │ │ ├── LocalizedControlBase.cs │ │ └── LocalizedControlBase.cs.meta ├── Settings Menu.meta ├── Settings Menu │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── Dropdown Control.prefab │ │ ├── Dropdown Control.prefab.meta │ │ ├── Header.prefab │ │ ├── Header.prefab.meta │ │ ├── Slider Control.prefab │ │ ├── Slider Control.prefab.meta │ │ ├── Tab Button.prefab │ │ ├── Tab Button.prefab.meta │ │ ├── Tab Content.prefab │ │ ├── Tab Content.prefab.meta │ │ ├── Toggle Control.prefab │ │ └── Toggle Control.prefab.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── Controls.meta │ │ ├── Controls │ │ │ ├── DropdownControl.cs │ │ │ ├── DropdownControl.cs.meta │ │ │ ├── SliderControl.cs │ │ │ ├── SliderControl.cs.meta │ │ │ ├── ToggleControl.cs │ │ │ └── ToggleControl.cs.meta │ │ ├── DropdownSettingFactory.cs │ │ ├── DropdownSettingFactory.cs.meta │ │ ├── Settings.meta │ │ ├── Settings │ │ │ ├── DropdownSetting.cs │ │ │ ├── DropdownSetting.cs.meta │ │ │ ├── SliderSetting.cs │ │ │ └── SliderSetting.cs.meta │ │ ├── SettingsInitializer.cs │ │ ├── SettingsInitializer.cs.meta │ │ ├── SettingsMenu.cs │ │ ├── SettingsMenu.cs.meta │ │ ├── SliderSettingFactory.cs │ │ ├── SliderSettingFactory.cs.meta │ │ ├── TabButton.cs │ │ ├── TabButton.cs.meta │ │ ├── TabView.cs │ │ └── TabView.cs.meta │ ├── Settings Menu Demo.unity │ └── Settings Menu Demo.unity.meta ├── Volume Setting FMOD.meta ├── Volume Setting FMOD │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── Volume Control.prefab │ │ └── Volume Control.prefab.meta │ ├── Scripts.meta │ └── Scripts │ │ ├── Runtime.meta │ │ └── Runtime │ │ ├── VolumeControlFMOD.cs │ │ ├── VolumeControlFMOD.cs.meta │ │ ├── VolumeSettingFMOD.cs │ │ └── VolumeSettingFMOD.cs.meta ├── Volume Setting.meta └── Volume Setting │ ├── Prefabs.meta │ ├── Prefabs │ ├── Volume Control.prefab │ └── Volume Control.prefab.meta │ ├── Scripts.meta │ └── Scripts │ ├── Editor.meta │ ├── Editor │ ├── MixerVariablePropertyDrawer.cs │ └── MixerVariablePropertyDrawer.cs.meta │ ├── Runtime.meta │ └── Runtime │ ├── MixerVariable.cs │ ├── MixerVariable.cs.meta │ ├── VolumeControl.cs │ ├── VolumeControl.cs.meta │ ├── VolumeSetting.cs │ └── VolumeSetting.cs.meta ├── package.json └── package.json.meta /.GitHubResources/Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenvin-dev/UnitySettingsFramework/2da01eae0d47c96950d517b9e720965f5b444657/.GitHubResources/Banner.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | 13 | # Asset meta data should only be ignored when the corresponding asset is also ignored 14 | !/[Aa]ssets/**/*.meta 15 | 16 | # Uncomment this line if you wish to ignore the asset store tools plugin 17 | # /[Aa]ssets/AssetStoreTools* 18 | 19 | # Autogenerated Jetbrains Rider plugin 20 | [Aa]ssets/Plugins/Editor/JetBrains* 21 | 22 | # Visual Studio cache directory 23 | .vs/ 24 | 25 | # Gradle cache directory 26 | .gradle/ 27 | 28 | # Autogenerated VS/MD/Consulo solution and project files 29 | ExportedObj/ 30 | .consulo/ 31 | *.csproj 32 | *.unityproj 33 | *.sln 34 | *.suo 35 | *.tmp 36 | *.user 37 | *.userprefs 38 | *.pidb 39 | *.booproj 40 | *.svd 41 | *.pdb 42 | *.mdb 43 | *.opendb 44 | *.VC.db 45 | 46 | # Unity3D generated meta files 47 | *.pidb.meta 48 | *.pdb.meta 49 | *.mdb.meta 50 | 51 | # Unity3D generated file on crash reports 52 | sysinfo.txt 53 | 54 | # Builds 55 | *.apk 56 | *.unitypackage 57 | 58 | # Crashlytics generated file 59 | crashlytics-build.properties 60 | 61 | # Samples folder 62 | [Ss]amples/* 63 | [Ss]amples.meta 64 | 65 | # Robocopy jobs 66 | *.rcj 67 | *.bat 68 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bfd7289ea6a2fe344a5c14c3469768b7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/AssetUtility.cs: -------------------------------------------------------------------------------- 1 | using Object = UnityEngine.Object; 2 | 3 | using UnityEngine; 4 | using UnityEditor; 5 | using System; 6 | 7 | namespace Zenvin.Settings.Framework { 8 | internal static class AssetUtility { 9 | 10 | public static T CreateAsPartOf (Object asset, Action onBeforeAdd = null, bool noUndo = false) where T : ScriptableObject { 11 | if (asset == null || typeof (T).IsAbstract) { 12 | return null; 13 | } 14 | 15 | T instance = ScriptableObject.CreateInstance (); 16 | 17 | onBeforeAdd?.Invoke (instance); 18 | 19 | if (!noUndo) { 20 | Undo.RecordObject (asset, "Add sub-asset"); 21 | } 22 | AddObjectToAssetAndRefresh (asset, instance); 23 | 24 | return instance; 25 | } 26 | 27 | public static T CreateAsPartOf (Object asset, Type assetType, Action onBeforeAdd = null, bool noUndo = false) where T : ScriptableObject { 28 | if (asset == null || assetType.IsAbstract) { 29 | return null; 30 | } 31 | 32 | T instance = ScriptableObject.CreateInstance (assetType) as T; 33 | if (instance == null) { 34 | return null; 35 | } 36 | 37 | onBeforeAdd?.Invoke (instance); 38 | 39 | if (!noUndo) 40 | Undo.RecordObject (asset, "Add sub-asset"); 41 | 42 | AddObjectToAssetAndRefresh (asset, instance); 43 | 44 | return instance; 45 | } 46 | 47 | public static T ConditionalCreateAsPartOf (Object asset, Type assetType, Func condition, Action onBeforeAdd = null, string undoText = null) 48 | where T : ScriptableObject { 49 | 50 | if (asset == null || assetType.IsAbstract || condition == null) { 51 | return null; 52 | } 53 | 54 | var instance = ScriptableObject.CreateInstance (assetType) as T; 55 | if (instance == null) { 56 | return null; 57 | } 58 | 59 | if (!condition.Invoke (instance)) { 60 | DestroyReliable (instance); 61 | return null; 62 | } 63 | 64 | if (undoText != null) 65 | Undo.RecordObject (asset, undoText); 66 | 67 | onBeforeAdd?.Invoke (instance); 68 | AddObjectToAssetAndRefresh (asset, instance); 69 | return instance; 70 | } 71 | 72 | public static void DestroyReliable (Object instance) { 73 | if (instance == null) 74 | return; 75 | 76 | if (Application.isPlaying) { 77 | Object.Destroy (instance); 78 | } else { 79 | Object.DestroyImmediate (instance); 80 | } 81 | } 82 | 83 | private static void AddObjectToAssetAndRefresh (Object asset, T instance) where T : ScriptableObject { 84 | AssetDatabase.AddObjectToAsset (instance, asset); 85 | EditorUtility.SetDirty (asset); 86 | AssetDatabase.SaveAssets (); 87 | AssetDatabase.Refresh (); 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /Editor/AssetUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 89fc14175f4142f489eeb2fa98e0e9d9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/DefaultValueDrawer.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using UnityEditor; 3 | using UnityEngine; 4 | using Zenvin.Settings.Utility; 5 | 6 | namespace Zenvin.Settings.Framework { 7 | [CustomPropertyDrawer (typeof (DefaultValueAttribute))] 8 | public class DefaultValueDrawer : PropertyDrawer { 9 | 10 | public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { 11 | if (GetIsValueVisible (property)) { 12 | EditorGUI.PropertyField (position, property, label); 13 | } 14 | } 15 | 16 | public override float GetPropertyHeight (SerializedProperty property, GUIContent label) { 17 | return GetIsValueVisible (property) ? base.GetPropertyHeight (property, label) : 0f; 18 | } 19 | 20 | private bool GetIsValueVisible (SerializedProperty prop) { 21 | if (prop.serializedObject.targetObject == null) { 22 | return false; 23 | } 24 | return prop.serializedObject.targetObject.GetType ()?.GetCustomAttribute (true) == null; 25 | } 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /Editor/DefaultValueDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a72d8f4a3f961a40b3365c3ebfbcfbc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/ReferenceFixUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5979157fa5f39054a9f9b18d0a8efab0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e141695a474d6f046b4014234e80bf7f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Resources/Icon Asset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenvin-dev/UnitySettingsFramework/2da01eae0d47c96950d517b9e720965f5b444657/Editor/Resources/Icon Asset.png -------------------------------------------------------------------------------- /Editor/Resources/Icon Asset.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9f551793f2b0e9438f322e5db19f7a3 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 1 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 0 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | spriteSheet: 91 | serializedVersion: 2 92 | sprites: [] 93 | outline: [] 94 | physicsShape: [] 95 | bones: [] 96 | spriteID: 97 | internalID: 0 98 | vertices: [] 99 | indices: 100 | edges: [] 101 | weights: [] 102 | secondaryTextures: [] 103 | spritePackingTag: 104 | pSDRemoveMatte: 0 105 | pSDShowRemoveMatteOption: 0 106 | userData: 107 | assetBundleName: 108 | assetBundleVariant: 109 | -------------------------------------------------------------------------------- /Editor/Resources/Icon GUI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenvin-dev/UnitySettingsFramework/2da01eae0d47c96950d517b9e720965f5b444657/Editor/Resources/Icon GUI.png -------------------------------------------------------------------------------- /Editor/Resources/Icon GUI.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4417fde6f31e4b144bf2d3780d563c13 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 2 36 | aniso: 1 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 0 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | spriteSheet: 91 | serializedVersion: 2 92 | sprites: [] 93 | outline: [] 94 | physicsShape: [] 95 | bones: [] 96 | spriteID: 97 | internalID: 0 98 | vertices: [] 99 | indices: 100 | edges: [] 101 | weights: [] 102 | secondaryTextures: [] 103 | spritePackingTag: 104 | pSDRemoveMatte: 0 105 | pSDShowRemoveMatteOption: 0 106 | userData: 107 | assetBundleName: 108 | assetBundleVariant: 109 | -------------------------------------------------------------------------------- /Editor/Resources/Icon Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenvin-dev/UnitySettingsFramework/2da01eae0d47c96950d517b9e720965f5b444657/Editor/Resources/Icon Group.png -------------------------------------------------------------------------------- /Editor/Resources/Icon Group.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6cb457ca55184bf49996a30300d6f068 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 1 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 0 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | spriteSheet: 91 | serializedVersion: 2 92 | sprites: [] 93 | outline: [] 94 | physicsShape: [] 95 | bones: [] 96 | spriteID: 97 | internalID: 0 98 | vertices: [] 99 | indices: 100 | edges: [] 101 | weights: [] 102 | secondaryTextures: [] 103 | spritePackingTag: 104 | pSDRemoveMatte: 0 105 | pSDShowRemoveMatteOption: 0 106 | userData: 107 | assetBundleName: 108 | assetBundleVariant: 109 | -------------------------------------------------------------------------------- /Editor/SettingBaseEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | namespace Zenvin.Settings.Framework { 4 | [CustomEditor (typeof (SettingBase), true, isFallback = true)] 5 | public class SettingBaseEditor : Editor { 6 | //public override void OnInspectorGUI () { 7 | 8 | //} 9 | } 10 | } -------------------------------------------------------------------------------- /Editor/SettingBaseEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27c4f94692777014999fe6c31a50986f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - settingsAssetIcon: {fileID: 2800000, guid: c9f551793f2b0e9438f322e5db19f7a3, type: 3} 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Editor/SettingBasePropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59ad1f2f6384889419124a1b98ae0b44 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SettingReferenceDrawer.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace Zenvin.Settings { 6 | [CustomPropertyDrawer (typeof (SettingReference<>))] 7 | public class SettingReferenceDrawer : PropertyDrawer { 8 | 9 | public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { 10 | 11 | using (new EditorGUI.DisabledGroupScope (Application.isPlaying)) { 12 | position.height = EditorGUIUtility.singleLineHeight; 13 | position = EditorGUI.PrefixLabel (position, label); 14 | EditorGUI.PropertyField (position, property.FindPropertyRelative ("settingObj"), GUIContent.none); 15 | } 16 | 17 | const float width = 60f; 18 | position.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 19 | 20 | Rect labelRect = new Rect (position); 21 | labelRect.width = width; 22 | EditorGUI.LabelField (labelRect, "Fallback"); 23 | 24 | position.width -= width; 25 | position.x += width; 26 | EditorGUI.PropertyField (position, property.FindPropertyRelative ("fallbackValue"), GUIContent.none); 27 | 28 | position.x += position.width; 29 | position.width = width; 30 | } 31 | 32 | public override float GetPropertyHeight (SerializedProperty property, GUIContent label) { 33 | return EditorGUIUtility.singleLineHeight * 2f + EditorGUIUtility.standardVerticalSpacing; 34 | } 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /Editor/SettingReferenceDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02a56d8e8673b5b4bbfaef2d4b32f5e9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SettingsEditorWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b2d2836331b4e34c80ca8411a2bb42a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - m_ViewDataDictionary: {instanceID: 0} 8 | - windowIcon: {fileID: 2800000, guid: 4417fde6f31e4b144bf2d3780d563c13, type: 3} 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Editor/Zenvin.Settings.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Zenvin.Settings.Editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:ac552a92ec43d4447b72a745b1ec5db0", 6 | "GUID:b19a3560d2f7536459ead567ec685fb0", 7 | "GUID:e4427921c419fbe45ab53ffae928789c", 8 | "GUID:43e07366a3b322442ab7e131ca368d69" 9 | ], 10 | "includePlatforms": [ 11 | "Editor" 12 | ], 13 | "excludePlatforms": [], 14 | "allowUnsafeCode": false, 15 | "overrideReferences": false, 16 | "precompiledReferences": [], 17 | "autoReferenced": true, 18 | "defineConstraints": [], 19 | "versionDefines": [], 20 | "noEngineReferences": false 21 | } -------------------------------------------------------------------------------- /Editor/Zenvin.Settings.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a1e94cca1c98f9a479f1dd3f1df25bee 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Zenvin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5075cfe53592544b9492a0a072b304e 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0fb1d5e5f47ab2a4ab32a590ef0fc37c 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8cac17582426e8947940d97d7ec60023 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9318e33db0edc894a8a79655b8d8204a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo ("Zenvin.Settings.Editor")] 4 | [assembly: InternalsVisibleTo ("Zenvin.Settings.Loading")] -------------------------------------------------------------------------------- /Runtime/Framework/AssemblyAttributes.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a16234fda364ad4590dfb19fbcd76f9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Base.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02975bc21deb36c4d8b8225d836e7f33 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/ComposedFrameworkObject.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using Zenvin.Settings.Framework.Components; 4 | 5 | namespace Zenvin.Settings.Framework { 6 | public abstract class ComposedFrameworkObject : VisualHierarchyObject { 7 | 8 | [SerializeField, HideInInspector] private protected ComponentCollection components = new ComponentCollection (); 9 | 10 | 11 | public bool TryGetComponent (out T component) { 12 | component = default; 13 | 14 | if (components == null) 15 | return false; 16 | 17 | for (int i = 0; i < components.Count; i++) { 18 | if (components[i] is T typedComponent) { 19 | component = typedComponent; 20 | return true; 21 | } 22 | } 23 | return false; 24 | } 25 | 26 | public T GetComponent () { 27 | return TryGetComponent (out T component) ? component : default; 28 | } 29 | 30 | public IEnumerable GetComponents () { 31 | for (int i = 0; i < components.Count; i++) { 32 | if (components[i] is T typedComponent) { 33 | yield return typedComponent; 34 | } 35 | } 36 | } 37 | 38 | 39 | internal bool TryAddComponentNoContainerCheck (FrameworkComponent component) { 40 | return components.Add (this, component, false); 41 | } 42 | 43 | internal bool TryAddComponent (FrameworkComponent component) { 44 | return components.Add (this, component, true); 45 | } 46 | 47 | internal bool RemoveComponent (FrameworkComponent component) { 48 | return components.Remove (this, component); 49 | } 50 | 51 | internal IEnumerator RemoveAllComponentsInteractive () { 52 | while (components.Count > 0) { 53 | var index = components.Count - 1; 54 | if (components.RemoveAt (this, index, out var comp)) { 55 | yield return comp; 56 | } 57 | } 58 | } 59 | 60 | internal void InitializeComponents () { 61 | for (int i = 0; i < components.Count; i++) { 62 | if (components[i] != null) { 63 | components[i].OnInitialize (); 64 | } 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/ComposedFrameworkObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 22b1472650a228b47bc46fdb9a2ff892 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/FrameworkObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Zenvin.Settings.Framework { 5 | /// 6 | /// Base class for various s inside the Settings Framework. 7 | /// 8 | public abstract class FrameworkObject : ScriptableObject { 9 | 10 | [NonSerialized] private bool wasInitialized; 11 | [SerializeField, HideInInspector] private string guid = null; 12 | [SerializeField, HideInInspector] private bool external = false; 13 | 14 | 15 | /// Unique ID of the object. 16 | public string GUID { 17 | get => guid; 18 | internal set => guid = value; 19 | } 20 | 21 | /// Whether the object was imported during runtime. 22 | public bool External { 23 | get => external; 24 | internal set => external = value; 25 | } 26 | 27 | /// Whether the object has already been initialized. 28 | public bool Initialized { 29 | get => wasInitialized; 30 | private protected set => wasInitialized = value; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/FrameworkObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e7b6df9104bf9884993e465052f7b51d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/NamedFrameworkObject.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Zenvin.Settings.Framework { 4 | /// 5 | /// An class extending the to include human-readable labels. 6 | /// 7 | public abstract class NamedFrameworkObject : FrameworkObject { 8 | 9 | [SerializeField, HideInInspector] private string label = string.Empty; 10 | [SerializeField, HideInInspector] private string labelLocalizationKey = string.Empty; 11 | 12 | [SerializeField, HideInInspector] private string description = string.Empty; 13 | [SerializeField, HideInInspector] private string descriptionLocalizationKey = string.Empty; 14 | 15 | 16 | /// The name assigned to the object. 17 | public string Name { 18 | get => label; 19 | internal set => label = value; 20 | } 21 | 22 | /// And arbitrary value that can be used to localize the object's . 23 | public string NameLocalizationKey { 24 | get => labelLocalizationKey; 25 | internal set => labelLocalizationKey = value; 26 | } 27 | 28 | /// A description of the object. 29 | public string Description { 30 | get => description; 31 | internal set => description = value; 32 | } 33 | 34 | /// And arbitrary value that can be used to localize the object's . 35 | public string DescriptionLocalizationKey { 36 | get => descriptionLocalizationKey; 37 | internal set => descriptionLocalizationKey = value; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/NamedFrameworkObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b143645e05fb064ab767b18be9372c3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/VisualHierarchyObject.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Framework { 2 | /// 3 | /// A class extending to contain visibility information that can be used when displaying the object(s) in a hierarchy. 4 | /// 5 | public abstract class VisualHierarchyObject : NamedFrameworkObject { 6 | /// 7 | /// Delegate type for the event. 8 | /// 9 | public delegate void VisibilityChangedEvt (); 10 | 11 | /// 12 | /// Invoked whenever changes. 13 | /// 14 | public event VisibilityChangedEvt VisibilityChanged; 15 | 16 | private SettingVisibility currentVisibility = SettingVisibility.Visible; 17 | 18 | 19 | /// 20 | /// The current visible state of the object. 21 | /// 22 | public SettingVisibility Visibility { 23 | get => currentVisibility; 24 | set => SetVisibility (value); 25 | } 26 | 27 | 28 | /// 29 | /// Sets the object's visible state. 30 | /// 31 | public void SetVisibility (SettingVisibility visibility) { 32 | SetVisibility (visibility, true); 33 | } 34 | 35 | /// 36 | /// Sets the object's visible state without raising any events. Should only be used for initialization. 37 | /// 38 | public void SetVisibilityWithoutNotify (SettingVisibility visibility) { 39 | if (visibility == currentVisibility) { 40 | return; 41 | } 42 | currentVisibility = visibility; 43 | } 44 | 45 | /// 46 | /// If implemented in an inheriting type, should return the object's visibility. 47 | /// 48 | /// The object's visibility, taking all parent objects into consideration. 49 | public abstract SettingVisibility GetVisibilityInHierarchy (); 50 | 51 | 52 | internal void SetVisibility (SettingVisibility visibility, bool propagateMethod) { 53 | if (visibility == currentVisibility) { 54 | return; 55 | } 56 | currentVisibility = visibility; 57 | if (propagateMethod) { 58 | OnSetVisibilityInternal (visibility); 59 | } 60 | VisibilityChanged?.Invoke (); 61 | } 62 | 63 | private protected virtual void OnSetVisibilityInternal (SettingVisibility visibility) { } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Runtime/Framework/Base/VisualHierarchyObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9792adfa1f06324584b2ee4f486557d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Components.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f4765f9c68912b4194f8245ca62cb41 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/ComponentCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Zenvin.Settings.Framework.Components { 6 | [Serializable] 7 | public class ComponentCollection { 8 | [SerializeField] private List components; 9 | 10 | 11 | public int Count => components?.Count ?? 0; 12 | internal FrameworkComponent this[int index] => components == null || index < 0 || index >= Count ? null : components[index]; 13 | 14 | 15 | internal bool Add (ComposedFrameworkObject container, FrameworkComponent component, bool checkContainer) { 16 | if (component == null || container == null) 17 | return false; 18 | if (checkContainer && component.BaseContainer != null) 19 | return component.BaseContainer == container; 20 | if (components != null && components.Contains (component)) 21 | return true; 22 | if (!component.IsValidContainer (container)) 23 | return false; 24 | 25 | components ??= new List (); 26 | components.Add (component); 27 | component.BaseContainer = container; 28 | return true; 29 | } 30 | 31 | internal bool Remove (ComposedFrameworkObject container, FrameworkComponent component) { 32 | if (component == null || container == null) 33 | return false; 34 | if (components == null || components.Count == 0) 35 | return false; 36 | if (component.BaseContainer != null && component.BaseContainer != container) 37 | return false; 38 | if (!components.Remove (component)) 39 | return false; 40 | 41 | component.BaseContainer = container; 42 | return true; 43 | } 44 | 45 | internal bool RemoveAt (ComposedFrameworkObject container, int index, out FrameworkComponent removed) { 46 | removed = null; 47 | if (container == null) 48 | return false; 49 | if (index < 0 || index >= components.Count) 50 | return false; 51 | 52 | removed = components[index]; 53 | if (removed.BaseContainer != null && removed.BaseContainer != container) 54 | return false; 55 | 56 | components.RemoveAt (index); 57 | removed.BaseContainer = container; 58 | return true; 59 | } 60 | 61 | internal void OnValueChanging (SettingBase setting, SettingBase.ValueChangeMode mode) { 62 | if (components == null || components.Count == 0 || setting == null) 63 | return; 64 | 65 | for (int i = 0; i < components.Count; i++) { 66 | if (components[i] is ISettingEventReceiver receiver) { 67 | receiver.OnValueChanging (setting, mode); 68 | } 69 | } 70 | } 71 | 72 | internal bool OnValueChanging (ValueChangingArgs args) { 73 | if (components == null || components.Count == 0) 74 | return false; 75 | 76 | var receiverPresent = false; 77 | for (int i = 0; i < components.Count; i++) { 78 | if (components[i] is ISettingEventReceiver receiver) { 79 | receiver.OnValueChanging (args); 80 | receiverPresent = true; 81 | } 82 | } 83 | return receiverPresent; 84 | } 85 | 86 | internal void OnValueChanged (SettingBase setting, SettingBase.ValueChangeMode mode) { 87 | if (components == null || components.Count == 0 || setting == null) 88 | return; 89 | 90 | for (int i = 0; i < components.Count; i++) { 91 | if (components[i] is ISettingEventReceiver receiver) { 92 | receiver.OnValueChanged (setting, mode); 93 | } 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/ComponentCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cac19155324c53141812614d9255fc5b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/FrameworkComponent.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Zenvin.Settings.Framework.Components { 4 | public abstract class FrameworkComponent : FrameworkObject { 5 | [SerializeField, HideInInspector] private ComposedFrameworkObject baseContainer; 6 | 7 | public ComposedFrameworkObject BaseContainer { get => baseContainer; internal set => baseContainer = value; } 8 | 9 | 10 | public virtual void OnInitialize () { } 11 | 12 | public virtual void OnCreateWithValues (StringValuePair[] values) { } 13 | 14 | 15 | internal virtual bool IsValidContainer (ComposedFrameworkObject container) { 16 | return container != null; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/FrameworkComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c1c552b9125308468cdfb1528fbb6b2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/ISettingEventReceiver.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Framework.Components { 2 | /// 3 | /// Interface for extending s that attach to s, 4 | /// in order to allow reacting to changes in the Settings' values. 5 | /// 6 | public interface ISettingEventReceiver { 7 | /// 8 | /// Called while the 's value is being changed, before the change is actually applied. 9 | /// 10 | /// 11 | /// This method will not be called, if another 12 | /// implementation on the same prevented the change. 13 | /// 14 | /// The Setting whose value is changing. 15 | /// The way the Setting is changing. 16 | void OnValueChanging(SettingBase setting, SettingBase.ValueChangeMode mode); 17 | /// 18 | /// Called after the 's value was changed. 19 | /// 20 | /// 21 | /// This method will be called after the 's own 22 | /// and . 23 | /// 24 | /// The Setting whose value was changed. 25 | /// The way the Setting was changed. 26 | void OnValueChanged(SettingBase setting, SettingBase.ValueChangeMode mode); 27 | } 28 | 29 | /// 30 | public interface ISettingEventReceiver { 31 | /// 32 | /// Called while the container 's value is changing (before the change actually affects the Setting).

33 | /// Allows preventing the change through . 34 | ///
35 | /// 36 | /// Changes can not be prevented during Initialize, Deserialize or Notify operations!

37 | /// The method will not be invoked at all during Prevent operations. 38 | ///
39 | /// Information about the and value being changed. 40 | void OnValueChanging (ValueChangingArgs args); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/ISettingEventReceiver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2a2f5347d8faa764ea70942eedd8e288 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/SettingComponent.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Framework.Components { 2 | public abstract class SettingComponent : TypedFrameworkComponent, ISettingEventReceiver where TSettingType : SettingBase { 3 | internal override bool IsValidContainer (ComposedFrameworkObject container) { 4 | return container != null && container is TSettingType; 5 | } 6 | 7 | /// 8 | public virtual void OnValueChanging (ValueChangingArgs args) { } 9 | 10 | /// 11 | public virtual void OnValueChanged (SettingBase.ValueChangeMode mode) { } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/SettingComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bed81f65d4dff7f4bb4d874b1d65c29c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/TypedFrameworkComponent.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Framework.Components { 2 | public abstract class TypedFrameworkComponent : FrameworkComponent where T : ComposedFrameworkObject { 3 | private T container; 4 | 5 | public T Container { 6 | get { 7 | if (container != null) 8 | return container; 9 | 10 | container = BaseContainer as T; 11 | return container; 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/TypedFrameworkComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83ca27b907aa6ef4394c043a5b308e58 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/ValueChangingArgs.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using static Zenvin.Settings.Framework.SettingBase.ValueChangeMode; 3 | 4 | namespace Zenvin.Settings.Framework.Components { 5 | /// 6 | /// Event arguments containing information about an impending Setting value change. 7 | /// 8 | public class ValueChangingArgs { 9 | /// The Setting whose value is changing. 10 | public readonly SettingBase Setting; 11 | /// The mode in which the Setting's value is changing. 12 | public readonly SettingBase.ValueChangeMode Mode; 13 | /// The value that the Setting would have after the change. 14 | public readonly TValue NewValue; 15 | 16 | /// 17 | /// Whether it was requested that the change not take place.

18 | /// See . 19 | ///
20 | public bool ChangePrevented { get; private set; } 21 | /// 22 | /// Whether the Setting change can actually be prevented.

23 | /// See . 24 | ///
25 | public bool CanPreventChange => Mode != Initialize && Mode != Deserialize && Mode != Notify && Mode != Prevent; 26 | 27 | 28 | private ValueChangingArgs () { } 29 | 30 | internal ValueChangingArgs (SettingBase setting, SettingBase.ValueChangeMode mode, TValue newValue) { 31 | Setting = setting; 32 | Mode = mode; 33 | NewValue = newValue; 34 | } 35 | 36 | 37 | /// 38 | /// Requests the change to be prevented.

39 | /// This will not have an effect during Initialize, Deserialize or Notify operations! 40 | ///
41 | public void PreventChange () { 42 | if (Setting == null) { 43 | return; 44 | } 45 | if (!CanPreventChange) { 46 | Debug.LogError ($"Cannot prevent Setting value change with Mode {Mode}."); 47 | return; 48 | } 49 | 50 | ChangePrevented = true; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Runtime/Framework/Components/ValueChangingArgs.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf2a15545c251a84aa4997c038639331 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/DefaultValueAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Zenvin.Settings.Framework { 5 | /// 6 | /// Attribute for marking a Setting's default value field as such, in order for its custom property drawer to work. 7 | /// 8 | [AttributeUsage (AttributeTargets.Field)] 9 | internal class DefaultValueAttribute : PropertyAttribute { } 10 | } -------------------------------------------------------------------------------- /Runtime/Framework/DefaultValueAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eb8e4bbc17ed51844a617f48cdc15171 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/DynamicSettingReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b594e275d81d7a479244d29d3e1ede9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Presets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cef3428cc21dcf5469f3f7a546db868e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/Presets/IEvaluatablePresetTarget.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Zenvin.Settings.Framework.Presets { 4 | /// 5 | /// An extension of that allows for evaluating how viable a given preset is.

6 | ///
7 | /// 8 | /// This could, for example, be useful for determining ideal graphics settings. 9 | /// 10 | /// 11 | public interface IEvaluatablePresetTarget : IPresetTarget where TPreset : ScriptableObject { 12 | /// 13 | /// If implemented, assigns a score to a given preset to determine how viable the preset is (in comparison with others of its kind). 14 | /// 15 | /// The preset to evaluate. 16 | /// The implementing Setting's score for the given preset. A preset's total score determines its ultimate viability. 17 | int EvaluatePresetViability (TPreset preset); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Runtime/Framework/Presets/IEvaluatablePresetTarget.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a8addfdb43170145b302040d630fd8c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Presets/IPresetTarget.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Zenvin.Settings.Framework.Presets { 4 | /// 5 | /// Interface to allow a apply values provided by a preset object. 6 | /// In conjunction with s, this can be used to change multiple Settings at once. 7 | /// 8 | /// The type that the preset value must have. 9 | /// 10 | /// Any can implement multiple overloads of this interface.

11 | /// Which one is used depends on the compatibility of the ordering application of the preset's values. 12 | ///
13 | public interface IPresetTarget where TPreset : ScriptableObject { 14 | void OnSetPresetValue (TPreset preset); 15 | void OnApplyPresetValue (TPreset preset); 16 | bool IsPresetActive (TPreset preset); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Runtime/Framework/Presets/IPresetTarget.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ea72f8ea63cbbe45962f90e8d070588 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Presets/PresetSettingsGroup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b0605f1a2ff84f40a8a5ffac094d508 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 09e3d576aab54d845822f0107e7e883a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b6626bf4d41cfda4e8fd4cb0fba6e915 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/BinaryFileSerializer.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Zenvin.Settings.Framework.Serialization { 4 | /// 5 | /// Extension of , which automatically writes changes to a file post serialization. 6 | /// 7 | public sealed class BinaryFileSerializer : BinarySerializer, ISerializerCallbackReceiver { 8 | 9 | public FileInfo SaveFile { get; private set; } 10 | 11 | 12 | public BinaryFileSerializer (string filePath) { 13 | SaveFile = new FileInfo (filePath); 14 | } 15 | 16 | public BinaryFileSerializer (FileInfo file) { 17 | SaveFile = file; 18 | } 19 | 20 | public bool ReadFromFile () { 21 | return ReadFromFile (SaveFile); 22 | } 23 | 24 | public bool WriteToFile () { 25 | return WriteToFile (SaveFile); 26 | } 27 | 28 | 29 | void ISerializerCallbackReceiver.FinalizeSerialization () { 30 | WriteToFile (); 31 | } 32 | 33 | void ISerializerCallbackReceiver.InitializeDeserialization () { 34 | ReadFromFile (); 35 | } 36 | 37 | void ISerializerCallbackReceiver.FinalizeDeserialization () { } 38 | 39 | void ISerializerCallbackReceiver.InitializeSerialization () { } 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/BinaryFileSerializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f712c19658a55848b3bc09ecd80ef7e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/BinarySerializer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace Zenvin.Settings.Framework.Serialization { 5 | public class BinarySerializer : ISerializer { 6 | 7 | private readonly Dictionary data = new Dictionary (); 8 | 9 | 10 | public bool ReadFromFile (FileInfo file) { 11 | if (file == null || !file.Exists) { 12 | return false; 13 | } 14 | 15 | // open save file 16 | using FileStream stream = file.OpenRead (); 17 | using BinaryReader reader = new BinaryReader (stream); 18 | 19 | // read length of saved data 20 | int count = reader.ReadInt32 (); 21 | 22 | for (int i = 0; i < count; i++) { 23 | // read guid of saved data 24 | string guid = reader.ReadString (); 25 | 26 | // read saved data 27 | byte[] binData = reader.ReadArray (); 28 | 29 | // associate data with guid 30 | data[guid] = binData; 31 | } 32 | 33 | // return filled instance 34 | return true; 35 | } 36 | 37 | public bool WriteToFile (FileInfo file) { 38 | if (file == null) { 39 | return false; 40 | } 41 | 42 | // create save file 43 | using FileStream stream = file.Create (); 44 | using BinaryWriter writer = new BinaryWriter (stream); 45 | 46 | // write length of the data 47 | writer.Write (data.Count); 48 | 49 | foreach (var kvp in data) { 50 | // write guid 51 | writer.Write (kvp.Key); 52 | 53 | // write data array 54 | writer.WriteArray (kvp.Value); 55 | } 56 | 57 | // save changes to disk 58 | stream.Flush (); 59 | return true; 60 | } 61 | 62 | 63 | IEnumerator> ISerializer.GetSerializedData () { 64 | foreach (var kvp in data) { 65 | yield return new KeyValuePair (kvp.Key, new ValuePacket (kvp.Value)); 66 | } 67 | } 68 | 69 | void ISerializer.Serialize (string guid, ValuePacket value) { 70 | data[guid] = value; 71 | } 72 | 73 | } 74 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/BinarySerializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: efe7968c93bcc10498321df9f92ad619 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/SerializationUtility.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Zenvin.Settings.Framework.Serialization { 4 | /// 5 | /// A class providing utility methods to write and read byte arrays to and from streams. 6 | /// 7 | public static class SerializationUtility { 8 | 9 | /// 10 | /// Writes a byte array to a stream by means of a given . 11 | /// 12 | /// The to write the array to. 13 | /// The byte array to write to the stream. May be . 14 | /// 15 | /// This method assumes that the is valid (i.e. it wraps an open stream that can be written to). 16 | /// 17 | public static void WriteArray (this BinaryWriter writer, byte[] array) { 18 | if (array == null) { 19 | writer.Write (0); 20 | return; 21 | } 22 | writer.Write (array.Length); 23 | for (int i = 0; i < array.Length; i++) { 24 | writer.Write (array[i]); 25 | } 26 | } 27 | 28 | /// 29 | /// Reads a byte array from a stream by means of a given . 30 | /// 31 | /// The used to read the values into the array. 32 | /// The read byte array. 33 | /// 34 | /// This method assumes that the is valid (i.e. it wraps an open stream that can be read from).

35 | /// It also assumes that the array was written by (or in the same format used by) . 36 | ///
37 | public static byte[] ReadArray (this BinaryReader reader) { 38 | int len = reader.ReadInt32 (); 39 | byte[] arr = new byte[len]; 40 | for (int i = 0; i < len; i++) { 41 | arr[i] = reader.ReadByte (); 42 | } 43 | return arr; 44 | } 45 | 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/SerializationUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f7e2f5d4e613fe4b8554ae72e52e2d7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/ValuePacket.Read.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 89071095f61efe946b3b00c280131c94 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/ValuePacket.Write.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Zenvin.Settings.Framework.Serialization { 5 | public partial class ValuePacket { 6 | 7 | public bool Write (string key, sbyte value, bool allowOverwrite = false) { 8 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 9 | } 10 | 11 | public bool Write (string key, byte value, bool allowOverwrite = false) { 12 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 13 | } 14 | 15 | public bool Write (string key, short value, bool allowOverwrite = false) { 16 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 17 | } 18 | 19 | public bool Write (string key, ushort value, bool allowOverwrite = false) { 20 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 21 | } 22 | 23 | public bool Write (string key, int value, bool allowOverwrite = false) { 24 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 25 | } 26 | 27 | public bool Write (string key, uint value, bool allowOverwrite = false) { 28 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 29 | } 30 | 31 | public bool Write (string key, long value, bool allowOverwrite = false) { 32 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 33 | } 34 | 35 | public bool Write (string key, ulong value, bool allowOverwrite = false) { 36 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 37 | } 38 | 39 | public bool Write (string key, float value, bool allowOverwrite = false) { 40 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 41 | } 42 | 43 | public bool Write (string key, double value, bool allowOverwrite = false) { 44 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 45 | } 46 | 47 | public bool Write (string key, bool value, bool allowOverwrite = false) { 48 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 49 | } 50 | 51 | public bool Write (string key, string value, Encoding encoding = null, bool allowOverwrite = false) { 52 | if (value == null) { 53 | return false; 54 | } 55 | encoding = encoding ?? Encoding.UTF8; 56 | return Write (key, encoding.GetBytes (value), allowOverwrite); 57 | } 58 | 59 | public bool Write (string key, char value, bool allowOverwrite = false) { 60 | return Write (key, BitConverter.GetBytes (value), allowOverwrite); 61 | } 62 | 63 | public bool Write (string key, byte[] value, bool allowOverwrite = false) { 64 | if (string.IsNullOrEmpty (key)) { 65 | return false; 66 | } 67 | if (value == null || value.Length == 0) { 68 | return false; 69 | } 70 | if (data.ContainsKey (key) && !allowOverwrite) { 71 | return false; 72 | } 73 | 74 | data[key] = value; 75 | return true; 76 | } 77 | 78 | } 79 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/ValuePacket.Write.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06afa8a1ef203ff49b064c5cf44e00c6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/ValuePacket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace Zenvin.Settings.Framework.Serialization { 6 | /// 7 | /// Helper class to serialize key/value pairs as byte array.

8 | /// Contains an implicit conversion to []. 9 | ///
10 | public partial class ValuePacket { 11 | 12 | private readonly Dictionary data = new Dictionary (); 13 | 14 | 15 | /// Default constructor that initializes an empty . 16 | public ValuePacket () { } 17 | 18 | /// Initializes a new with the contents of a given byte array. 19 | /// Initial data to write into the packet. 20 | /// 21 | /// Assumes that is a value that was returned by , or is in the same format. 22 | /// 23 | public ValuePacket (byte[] byteData) { 24 | FromArray (byteData); 25 | } 26 | 27 | 28 | private void FromArray (byte[] byteData) { 29 | using MemoryStream stream = new MemoryStream (byteData); 30 | using BinaryReader reader = new BinaryReader (stream); 31 | 32 | int count = reader.ReadInt32 (); 33 | for (int i = 0; i < count; i++) { 34 | string key = reader.ReadString (); 35 | byte[] value = reader.ReadArray (); 36 | data[key] = value; 37 | } 38 | } 39 | 40 | /// 41 | /// Returns the contents of the packet as a byte array. 42 | /// 43 | public byte[] ToArray () { 44 | using MemoryStream stream = new MemoryStream (); 45 | using BinaryWriter writer = new BinaryWriter(stream); 46 | 47 | writer.Write (data.Count); 48 | 49 | foreach (var val in data) { 50 | writer.Write (val.Key); 51 | writer.WriteArray (val.Value); 52 | } 53 | 54 | return stream.ToArray (); 55 | } 56 | 57 | /// 58 | ///

59 | /// The same as calling . 60 | ///
61 | public static implicit operator byte[] (ValuePacket packet) { 62 | if (packet == null) { 63 | return Array.Empty (); 64 | } 65 | return packet.ToArray (); 66 | } 67 | 68 | } 69 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/Binary/ValuePacket.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 887866a7d0fe0fc4394487dce2524dfb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/IAsyncSerializer.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_2023_1_OR_NEWER 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Zenvin.Settings.Framework.Serialization { 6 | /// 7 | /// Interface for asynchronously serializing a 's value in a generic object. 8 | /// 9 | /// The type of object that handles storing a single 's value. 10 | public interface IAsyncSerializer where T : class, new() { 11 | /// 12 | Awaitable SerializeAsync (string guid, T value); 13 | /// 14 | Awaitable>> GetSerializedDataAsync (); 15 | } 16 | } 17 | #endif 18 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/IAsyncSerializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 72a1d6e08737fea428becc74b6ae14d2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/IAsyncSerializerCallbackReceiver.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_2023_1_OR_NEWER 2 | using UnityEngine; 3 | 4 | namespace Zenvin.Settings.Framework.Serialization { 5 | /// 6 | /// Interface for hooking into the Setting serialization process.

7 | /// Meant to be attached to types that already implement . 8 | ///
9 | public interface IAsyncSerializerCallbackReceiver { 10 | /// 11 | Awaitable InitializeSerializationAsync (); 12 | /// 13 | Awaitable FinalizeSerializationAsync (); 14 | /// 15 | Awaitable InitializeDeserializationAsync (); 16 | /// 17 | Awaitable FinalizeDeserializationAsync (); 18 | } 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/IAsyncSerializerCallbackReceiver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d129ed52c6e2ea04aad4ba978b33e94d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/ISerializable.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Framework.Serialization { 2 | /// 3 | /// Interface to allow a to be serialized using a . 4 | /// 5 | /// The type as which the Setting's value will be serialized. 6 | /// 7 | /// Any can implement multiple overloads of this interface.

8 | /// Which one is used depends on the compatibility of the used for serialization of the Setting. 9 | ///
10 | public interface ISerializable where T : class, new() { 11 | /// 12 | /// Called during serialization to wrap the Setting's arbitrary value into a value that a can work with. 13 | /// 14 | /// 15 | /// An instance of the wrapper type .

16 | /// Will never be . 17 | /// 18 | void OnSerialize (T value); 19 | /// 20 | /// Called during deserialization to extract the Setting's arbitrary value from a given wrapper of type . 21 | /// 22 | /// 23 | /// An instance of the wrapper type .

24 | /// Will never be . 25 | /// 26 | void OnDeserialize (T value); 27 | } 28 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/ISerializable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c529964a2cfe0a8438a3a7160cb20bda 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/ISerializer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Zenvin.Settings.Framework.Serialization { 4 | /// 5 | /// Interface for serializing a 's value in a generic object. 6 | /// 7 | /// The type of object that handles storing a single 's value. 8 | public interface ISerializer where T : class, new() { 9 | /// 10 | /// Called once for every that should be serialized. 11 | /// 12 | /// The GUID of the that needs saving with the current call. 13 | /// The value returned by the 's implementation of . 14 | void Serialize (string guid, T value); 15 | /// 16 | /// Called during deserialization. Should return all saved GUIDs, along with the associated data. 17 | /// 18 | IEnumerator> GetSerializedData (); 19 | } 20 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/ISerializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da258159beb82db4d943d355a74655fd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/ISerializerCallbackReceiver.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Framework.Serialization { 2 | /// 3 | /// Interface for hooking into the Setting serialization process.

4 | /// Meant to be attached to types that already implement . 5 | ///
6 | public interface ISerializerCallbackReceiver { 7 | /// 8 | /// Called before any Settings are serialized. 9 | /// 10 | void InitializeSerialization (); 11 | /// 12 | /// Called after all Settings have been serialized. 13 | /// 14 | void FinalizeSerialization (); 15 | /// 16 | /// Called before any Settings are deserialized. 17 | /// 18 | void InitializeDeserialization (); 19 | /// 20 | /// Called after all Settings have been deserialized. 21 | /// 22 | void FinalizeDeserialization (); 23 | } 24 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/ISerializerCallbackReceiver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 24f5f75383747644d815753951a9a745 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/JSON.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd9a3a57955b6e74480041dd4d6b17aa 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/JSON/JsonFileSerializer.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.IO; 3 | 4 | namespace Zenvin.Settings.Framework.Serialization { 5 | /// 6 | /// Extension of , which automatically writes changes to a file post serialization. 7 | /// 8 | public sealed class JsonFileSerializer : JsonSerializer, ISerializerCallbackReceiver { 9 | 10 | public FileInfo SaveFile { get; private set; } 11 | public Formatting OutputFormatting { get; set; } = Formatting.Indented; 12 | public JsonConverter[] Converters { get; set; } 13 | 14 | 15 | public JsonFileSerializer (string filePath) { 16 | SaveFile = new FileInfo (filePath); 17 | } 18 | 19 | public JsonFileSerializer (FileInfo file) { 20 | SaveFile = file; 21 | } 22 | 23 | public bool ReadFromFile () { 24 | return ReadFromFile (SaveFile); 25 | } 26 | 27 | public bool WriteToFile () { 28 | return WriteToFile (SaveFile, OutputFormatting, Converters); 29 | } 30 | 31 | 32 | void ISerializerCallbackReceiver.FinalizeSerialization () { 33 | WriteToFile (); 34 | } 35 | 36 | void ISerializerCallbackReceiver.InitializeDeserialization () { 37 | ReadFromFile (); 38 | } 39 | 40 | void ISerializerCallbackReceiver.FinalizeDeserialization () { } 41 | 42 | void ISerializerCallbackReceiver.InitializeSerialization () { } 43 | 44 | } 45 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/JSON/JsonFileSerializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 779e8fa31cea96d41aa0acb3a1e31e90 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/JSON/JsonSerializer.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Linq; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | 6 | namespace Zenvin.Settings.Framework.Serialization { 7 | public class JsonSerializer : ISerializer { 8 | 9 | private JObject data; 10 | 11 | 12 | public JsonSerializer () { 13 | data = new JObject (); 14 | } 15 | 16 | 17 | public bool ReadFromFile (FileInfo file) { 18 | if (file == null || !file.Exists) { 19 | return false; 20 | } 21 | 22 | // prepare json reader 23 | using FileStream stream = file.OpenRead (); 24 | using StreamReader reader = new StreamReader (stream); 25 | using JsonTextReader jsonReader = new JsonTextReader (reader); 26 | 27 | // read json data 28 | JObject jData = JToken.ReadFrom (jsonReader) as JObject; 29 | data = jData; 30 | 31 | // return whether reading data was successful 32 | return data != null; 33 | } 34 | 35 | public bool WriteToFile (FileInfo file, Formatting formatting = Formatting.Indented, params JsonConverter[] converters) { 36 | if (file == null) { 37 | return false; 38 | } 39 | 40 | string json = JsonConvert.SerializeObject (data, formatting, converters); 41 | File.WriteAllText (file.FullName, json); 42 | return true; 43 | } 44 | 45 | 46 | IEnumerator> ISerializer.GetSerializedData () { 47 | foreach (var item in data) { 48 | if (item.Value is JObject jObject) { 49 | yield return new KeyValuePair (item.Key, jObject); 50 | } 51 | } 52 | } 53 | 54 | void ISerializer.Serialize (string guid, JObject value) { 55 | data[guid] = value; 56 | } 57 | 58 | 59 | public override string ToString () { 60 | return data.ToString (); 61 | } 62 | 63 | } 64 | } -------------------------------------------------------------------------------- /Runtime/Framework/Serialization/JSON/JsonSerializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b151cc45c8718f44887981410cb70cfa 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c32cb33f65e0587469b681bf11c61389 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingReference.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | namespace Zenvin.Settings.Framework { 5 | /// 6 | /// Simple class, used to provide a serialized reference to a and a fallback value in case the reference is . 7 | /// 8 | [Serializable] 9 | public class SettingReference { 10 | private SettingBase.ValueChangedEvent valueChanged; 11 | 12 | [SerializeField] private SettingBase settingObj = null; 13 | [SerializeField] private protected T fallbackValue = default; 14 | 15 | 16 | /// 17 | /// Relays the wrapped Setting's event.

18 | ///
19 | /// 20 | /// Events cannot be added when the game is not running. 21 | /// 22 | public event SettingBase.ValueChangedEvent ValueChanged { 23 | add { 24 | if (!Application.isPlaying) 25 | return; 26 | 27 | if (settingObj != null) { 28 | settingObj.ValueChanged -= ReferenceValueChangedHandler; 29 | settingObj.ValueChanged += ReferenceValueChangedHandler; 30 | } 31 | valueChanged += value; 32 | } 33 | remove { 34 | valueChanged -= value; 35 | } 36 | } 37 | 38 | /// Whether a Setting is referenced. 39 | public bool HasSetting => settingObj != null; 40 | /// The referenced Setting object. 41 | public virtual SettingBase Setting { 42 | get => settingObj; 43 | set => SetReference (value); 44 | } 45 | 46 | /// The Fallback value, that is used when no valid is referenced. 47 | public T Fallback { get => fallbackValue; set => fallbackValue = value; } 48 | /// The of the referenced Setting. if no fallback is given. 49 | public T CurrentValue => settingObj == null ? fallbackValue : settingObj.CurrentValue; 50 | /// The of the referenced Setting. if no fallback is given. 51 | public T CachedValue => settingObj == null ? fallbackValue : settingObj.CachedValue; 52 | 53 | 54 | public SettingReference () { } 55 | 56 | public SettingReference (T fallbackValue) { 57 | this.fallbackValue = fallbackValue; 58 | } 59 | 60 | 61 | private protected void SetReference (SettingBase reference) { 62 | if (reference == settingObj) 63 | return; 64 | 65 | if (settingObj != null) 66 | settingObj.ValueChanged -= ReferenceValueChangedHandler; 67 | 68 | settingObj = reference; 69 | 70 | if (settingObj != null) 71 | settingObj.ValueChanged += ReferenceValueChangedHandler; 72 | } 73 | 74 | private void ReferenceValueChangedHandler (SettingBase.ValueChangeMode mode) => valueChanged?.Invoke (mode); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d27fd61fb3c4e5343ba1e0b773fd4306 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingVisibility.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Framework { 2 | /// 3 | /// Visiblity state. Intended to be implemented by the user interface. 4 | /// 5 | public enum SettingVisibility { 6 | /// The object is visible. 7 | Visible = 0, 8 | /// The object is visible, but disabled. 9 | Disabled = 1, 10 | /// The object is not visible. 11 | Hidden = 2, 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/Framework/SettingVisibility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 748448d20ee8de24bb9b5b13ad1a6968 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Settings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53f401796f743f14995d822b91ae0aa7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Framework/Settings/BoolSetting.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using Zenvin.Settings.Framework.Serialization; 3 | 4 | namespace Zenvin.Settings.Framework { 5 | public class BoolSetting : SettingBase, ISerializable, ISerializable { 6 | 7 | protected override bool TryGetOverrideValue (StringValuePair[] values, out bool value) { 8 | var text = values[0].Value?.Trim (); 9 | 10 | if (string.IsNullOrEmpty (text)) { 11 | value = default; 12 | return false; 13 | } 14 | if (text.Equals ("true", System.StringComparison.OrdinalIgnoreCase)) { 15 | value = true; 16 | return true; 17 | } 18 | if (text.Equals ("false", System.StringComparison.OrdinalIgnoreCase)) { 19 | value = false; 20 | return true; 21 | } 22 | 23 | value = default; 24 | return false; 25 | } 26 | 27 | 28 | void ISerializable.OnDeserialize (JObject data) { 29 | if (data.TryGetValue ("value", out JToken token)) { 30 | SetValue ((bool)token); 31 | } 32 | } 33 | 34 | void ISerializable.OnDeserialize (ValuePacket value) { 35 | if (value.TryRead ("value", out bool val)) { 36 | SetValue (val); 37 | } 38 | } 39 | 40 | void ISerializable.OnSerialize (JObject data) { 41 | data.Add ("value", CurrentValue); 42 | } 43 | 44 | void ISerializable.OnSerialize (ValuePacket value) { 45 | value.Write ("value", CurrentValue); 46 | } 47 | 48 | } 49 | } -------------------------------------------------------------------------------- /Runtime/Framework/Settings/BoolSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04b662bbce522df42b775694a9820819 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Settings/FloatSetting.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using Zenvin.Settings.Framework.Serialization; 3 | 4 | namespace Zenvin.Settings.Framework { 5 | public class FloatSetting : SettingBase, ISerializable, ISerializable { 6 | 7 | protected override bool TryGetOverrideValue (StringValuePair[] values, out float value) { 8 | var text = values[0].Value?.Trim (); 9 | if (string.IsNullOrEmpty (text)) { 10 | value = default; 11 | return false; 12 | } 13 | 14 | return float.TryParse (text, out value); 15 | } 16 | 17 | 18 | void ISerializable.OnDeserialize (JObject value) { 19 | if (value.TryGetValue ("value", out JToken token)) { 20 | SetValue ((float)token); 21 | } 22 | } 23 | 24 | void ISerializable.OnDeserialize (ValuePacket value) { 25 | if (value.TryRead ("value", out float val)) { 26 | SetValue (val); 27 | } 28 | } 29 | 30 | void ISerializable.OnSerialize (JObject value) { 31 | value.Add ("value", CurrentValue); 32 | } 33 | 34 | void ISerializable.OnSerialize (ValuePacket value) { 35 | value.Write ("value", CurrentValue); 36 | } 37 | 38 | } 39 | } -------------------------------------------------------------------------------- /Runtime/Framework/Settings/FloatSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6664d1ebaca31a24b952ae687a5f6231 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Settings/IntSetting.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using Zenvin.Settings.Framework.Serialization; 3 | 4 | namespace Zenvin.Settings.Framework { 5 | public class IntSetting : SettingBase, ISerializable, ISerializable { 6 | 7 | protected override bool TryGetOverrideValue (StringValuePair[] values, out int value) { 8 | var text = values[0].Value?.Trim (); 9 | if (string.IsNullOrEmpty (text)) { 10 | value = default; 11 | return false; 12 | } 13 | 14 | return int.TryParse (text, out value); 15 | } 16 | 17 | 18 | void ISerializable.OnDeserialize (JObject value) { 19 | if (value.TryGetValue ("value", out JToken token)) { 20 | SetValue ((int)token); 21 | } 22 | } 23 | 24 | void ISerializable.OnDeserialize (ValuePacket value) { 25 | if (value.TryRead ("value", out int val)) { 26 | SetValue (val); 27 | } 28 | } 29 | 30 | void ISerializable.OnSerialize (JObject value) { 31 | value.Add ("value", CurrentValue); 32 | } 33 | 34 | void ISerializable.OnSerialize (ValuePacket value) { 35 | value.Write ("value", CurrentValue); 36 | } 37 | 38 | } 39 | } -------------------------------------------------------------------------------- /Runtime/Framework/Settings/IntSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab26885ef141d8f438361b99cd1470e4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Settings/StringSetting.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Text; 3 | using Zenvin.Settings.Framework.Serialization; 4 | 5 | namespace Zenvin.Settings.Framework { 6 | public class StringSetting : SettingBase, ISerializable, ISerializable { 7 | 8 | private Encoding StringEncoding => Encoding.UTF8; 9 | 10 | 11 | protected override bool TryGetOverrideValue (StringValuePair[] values, out string value) { 12 | value = values[0].Value; 13 | return true; 14 | } 15 | 16 | 17 | void ISerializable.OnDeserialize (JObject value) { 18 | if (value.TryGetValue ("value", out JToken token)) { 19 | SetValue ((string)token); 20 | } 21 | } 22 | 23 | void ISerializable.OnDeserialize (ValuePacket value) { 24 | if (value.TryRead ("value", out string val)) { 25 | SetValue (val); 26 | } 27 | } 28 | 29 | void ISerializable.OnSerialize (JObject value) { 30 | value.Add ("value", CurrentValue); 31 | } 32 | 33 | void ISerializable.OnSerialize (ValuePacket value) { 34 | value.Write ("value", CurrentValue, StringEncoding); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Runtime/Framework/Settings/StringSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 765c3324946dc1645a2f6e5b89b12615 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Settings/ValueArraySetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using Zenvin.Settings.Utility; 6 | 7 | namespace Zenvin.Settings.Framework { 8 | /// 9 | /// Non-generic base class for a Setting that contains an array of values.

10 | /// The Setting's actual value represents the index used to retrieve values from that array. 11 | ///
12 | [HasDeviatingDefaultValue] 13 | public abstract class ValueArraySetting : SettingBase, IEnumerable { 14 | private protected object[] values; 15 | 16 | 17 | /// 18 | /// The number of values managed by this Setting. 19 | /// 20 | public int Length => values?.Length ?? 0; 21 | 22 | /// 23 | /// Returns one of the Setting's values at a given index. 24 | /// 25 | /// 26 | public object GetValue (int index) { 27 | if (index < 0 || index >= Length) { 28 | throw new IndexOutOfRangeException (nameof (index)); 29 | } 30 | return values[index]; 31 | } 32 | 33 | /// 34 | /// Should return a formatted string that represents the Setting's value at the given index.

35 | /// Will return GetValue(index).ToString() by default (or , if GetValue(index) happens to return ). 36 | ///
37 | /// 38 | public virtual string GetValueString (int index) { 39 | var value = GetValue (index); 40 | if (value == null) { 41 | return string.Empty; 42 | } 43 | return value.ToString (); 44 | } 45 | 46 | 47 | /// 48 | /// Called during initialization. Should contain the list of values managed by this Setting. 49 | /// 50 | protected abstract object[] GetValueArray (); 51 | 52 | /// 53 | /// Stand-in for the inherited , which is sealed in .

54 | /// Will be called right after the Setting's values have been initialized. 55 | ///
56 | protected virtual void OnPostInitialize () { } 57 | 58 | 59 | /// 60 | protected sealed override void OnInitialize () { 61 | values = GetValueArray () ?? Array.Empty(); 62 | OnPostInitialize (); 63 | } 64 | 65 | /// 66 | protected override void ProcessValue (ref int value) { 67 | if (value >= values.Length) { 68 | value = values.Length - 1; 69 | } 70 | if (value < 0) { 71 | value = 0; 72 | } 73 | } 74 | 75 | 76 | IEnumerator IEnumerable.GetEnumerator () { 77 | return values.GetEnumerator (); 78 | } 79 | } 80 | 81 | /// 82 | /// Generic implementation of and base class for a Setting that contains an array of values.

83 | /// The Setting's actual value represents the index used to retrieve values from that array. 84 | ///
85 | public abstract class ValueArraySetting : ValueArraySetting, IEnumerable { 86 | 87 | [SerializeField] private T typedDefaultValue; 88 | 89 | 90 | /// The value at the index of CachedValue, cast to . 91 | public T CachedValueTyped => CachedValue < 0 || CachedValue >= values.Length ? default : (T)values[CachedValue]; 92 | /// The value at the index of CurrentValue, cast to . 93 | public T CurrentValueTyped => CurrentValue < 0 || CurrentValue >= values.Length ? default : (T)values[CurrentValue]; 94 | /// The value at the given index, cast to . 95 | /// When the index is less than 0, or greater or equal to the total number of values. 96 | public T this[int index] => index < 0 || index >= Length ? throw new IndexOutOfRangeException (nameof (index)) : (T)values[index]; 97 | 98 | 99 | /// 100 | protected override int OnSetupInitialDefaultValue () { 101 | return Array.IndexOf (values, typedDefaultValue); 102 | } 103 | 104 | 105 | IEnumerator IEnumerable.GetEnumerator () { 106 | for (int i = 0; i < Length; i++) { 107 | yield return this[i]; 108 | } 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /Runtime/Framework/Settings/ValueArraySetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be5c522188f56654fab30fa81485ea3d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingsAsset.Async.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5315994388fb35142a1097263b5c5faf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingsAsset.Editor.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | 4 | namespace Zenvin.Settings.Framework { 5 | public partial class SettingsAsset { 6 | partial void OnInitialized_Editor () { 7 | EditorApplication.playModeStateChanged -= PlayModeStateChangedHandler; 8 | EditorApplication.playModeStateChanged += PlayModeStateChangedHandler; 9 | } 10 | 11 | private void PlayModeStateChangedHandler (PlayModeStateChange change) { 12 | if (change != PlayModeStateChange.ExitingPlayMode) 13 | return; 14 | 15 | settingsDict.Clear (); 16 | groupsDict.Clear (); 17 | dirtySettings.Clear (); 18 | Initialized = false; 19 | 20 | Log ("[Editor] Reset initialization state."); 21 | } 22 | } 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingsAsset.Editor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27a1388a98e254243a8ea857785d6f86 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingsAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dec39ef7ed3889c4ba5fd7c53fbc3f81 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {fileID: 2800000, guid: c9f551793f2b0e9438f322e5db19f7a3, type: 3} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/SettingsGroup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f460c7312f6b8946a889ee18a433ed6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {fileID: 2800000, guid: 6cb457ca55184bf49996a30300d6f068, type: 3} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Framework/Zenvin.Settings.Framework.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Zenvin.Settings.Framework", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:e4427921c419fbe45ab53ffae928789c", 6 | "GUID:2407e9dba5422d242bcb0a0c026a4b2f" 7 | ], 8 | "includePlatforms": [], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": false, 12 | "precompiledReferences": [], 13 | "autoReferenced": true, 14 | "defineConstraints": [], 15 | "versionDefines": [], 16 | "noEngineReferences": false 17 | } -------------------------------------------------------------------------------- /Runtime/Framework/Zenvin.Settings.Framework.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac552a92ec43d4447b72a745b1ec5db0 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Loading.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5c20acffadd3b0a4abb93ff93ff9d3f8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Loading/IGroupFactory.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | 3 | namespace Zenvin.Settings.Loading { 4 | public interface IGroupFactory { 5 | string GetDefaultValidType (); 6 | SettingsGroup CreateGroupFromType (StringValuePair[] values); 7 | } 8 | } -------------------------------------------------------------------------------- /Runtime/Loading/IGroupFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 10f2d15ed2ade314c942319f14f50b61 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/IGroupIconLoader.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Zenvin.Settings.Loading { 4 | public interface IGroupIconLoader { 5 | Sprite LoadIconResource (string identifier); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Runtime/Loading/IGroupIconLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55ec2598f6fd1d24e8350e014c6b89f8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/ISettingFactory.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | 3 | namespace Zenvin.Settings.Loading { 4 | public interface ISettingFactory { 5 | string GetDefaultValidType (); 6 | SettingBase CreateSettingFromType (string defaultValue, StringValuePair[] values); 7 | } 8 | } -------------------------------------------------------------------------------- /Runtime/Loading/ISettingFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5e02f9bc18f6e154cbf4c0601b609f00 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/PrimitiveFactories.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | 3 | namespace Zenvin.Settings.Loading { 4 | /// 5 | /// A factory class for , , and . 6 | /// 7 | public class BoolSettingFactory : ISettingFactory { 8 | string ISettingFactory.GetDefaultValidType () { 9 | return "bool"; 10 | } 11 | 12 | SettingBase ISettingFactory.CreateSettingFromType (string defaultValue, StringValuePair[] values) { 13 | return BoolSetting.CreateInstanceWithValues (bool.TryParse (defaultValue, out bool val) && val, values); 14 | } 15 | } 16 | 17 | public class IntSettingFactory : ISettingFactory { 18 | string ISettingFactory.GetDefaultValidType () { 19 | return "int"; 20 | } 21 | 22 | SettingBase ISettingFactory.CreateSettingFromType (string defaultValue, StringValuePair[] values) { 23 | return IntSetting.CreateInstanceWithValues (int.TryParse (defaultValue, out int val) ? val : 0, values); 24 | } 25 | } 26 | 27 | public class FloatSettingFactory : ISettingFactory { 28 | string ISettingFactory.GetDefaultValidType () { 29 | return "float"; 30 | } 31 | 32 | SettingBase ISettingFactory.CreateSettingFromType (string defaultValue, StringValuePair[] values) { 33 | return FloatSetting.CreateInstanceWithValues (float.TryParse (defaultValue, out float val) ? val : 0f, values); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Runtime/Loading/PrimitiveFactories.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5842742e686dee14bb40813f06ccf12a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/RuntimeLoaderHelpers.cs: -------------------------------------------------------------------------------- 1 | using static Zenvin.Settings.Loading.RuntimeSettingLoader; 2 | using GroupFacDict = System.Collections.Generic.Dictionary; 3 | using SettingFacDict = System.Collections.Generic.Dictionary; 4 | 5 | namespace Zenvin.Settings.Loading { 6 | internal static class RuntimeLoaderHelpers { 7 | public static void PopulateFactoryDicts (TypeFactoryWrapper[] factories, SettingFacDict settingFactories, GroupFacDict groupFactories) { 8 | if (factories == null || factories.Length == 0 || settingFactories == null || groupFactories == null) { 9 | return; 10 | } 11 | 12 | foreach (var f in factories) { 13 | string fType = f.Type; 14 | 15 | switch (f.FactoryType) { 16 | case TypeFactoryWrapper.FactoryResult.Group: 17 | PopulateGroupFactoryDict (f.GroupFactory, groupFactories, fType); 18 | break; 19 | case TypeFactoryWrapper.FactoryResult.Setting: 20 | PopulateSettingFactoryDict (f.SettingFactory, settingFactories, fType); 21 | break; 22 | } 23 | } 24 | } 25 | 26 | private static void PopulateGroupFactoryDict (IGroupFactory factory, GroupFacDict groupFactories, string fType) { 27 | if (factory == null) 28 | return; 29 | 30 | if (string.IsNullOrEmpty (fType)) 31 | fType = factory.GetDefaultValidType (); 32 | 33 | if (!string.IsNullOrEmpty (fType)) 34 | groupFactories[fType] = factory; 35 | } 36 | 37 | private static void PopulateSettingFactoryDict (ISettingFactory factory, SettingFacDict settingsFactories, string fType) { 38 | if (factory == null) 39 | return; 40 | 41 | if (string.IsNullOrEmpty (fType)) 42 | fType = factory.GetDefaultValidType (); 43 | 44 | if (!string.IsNullOrEmpty (fType)) 45 | settingsFactories[fType] = factory; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Runtime/Loading/RuntimeLoaderHelpers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79cf9d11b78c1004ea79cb60fc2cea22 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/RuntimeSettingLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9eeda573becccf44ebd80fa6fe4e375d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/SettingLoaderOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e222dd7a7861ba2499494ceb016483f5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/SettingsImportData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Zenvin.Settings.Framework; 4 | 5 | namespace Zenvin.Settings.Loading { 6 | [Serializable] 7 | public class SettingsImportData { 8 | public List Groups; 9 | public List Settings; 10 | public List DefaultOverrides; 11 | } 12 | 13 | [Serializable] 14 | public abstract class ObjectDataBase { 15 | public string GUID; 16 | public string Type; 17 | 18 | public string Name; 19 | public string NameLocalizationKey; 20 | 21 | public string Description; 22 | public string DescriptionLocalizationKey; 23 | 24 | public string ParentGroupGUID; 25 | 26 | public SettingVisibility InitialVisibility; 27 | 28 | public List Values; 29 | public List Components; 30 | } 31 | 32 | [Serializable] 33 | public class GroupData : ObjectDataBase { 34 | public string IconResource; 35 | } 36 | 37 | [Serializable] 38 | public class SettingData : ObjectDataBase { 39 | public int OrderInGroup; 40 | public string DefaultValue; 41 | } 42 | 43 | [Serializable] 44 | public class OverrideData { 45 | public string GUID; 46 | public UpdateValueMode Update; 47 | public List Values; 48 | } 49 | 50 | [Serializable] 51 | public class ComponentData { 52 | public string Type; 53 | public List Values; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Runtime/Loading/SettingsImportData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c733505b4a400634da92f979467825f0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Loading/Zenvin.Settings.Loading.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Zenvin.Settings.Loading", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:ac552a92ec43d4447b72a745b1ec5db0", 6 | "GUID:2407e9dba5422d242bcb0a0c026a4b2f" 7 | ], 8 | "includePlatforms": [], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": false, 12 | "precompiledReferences": [], 13 | "autoReferenced": true, 14 | "defineConstraints": [], 15 | "versionDefines": [], 16 | "noEngineReferences": false 17 | } -------------------------------------------------------------------------------- /Runtime/Loading/Zenvin.Settings.Loading.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1f9b98b694144844b4ff64285949c7b 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/StringValuePair.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Zenvin.Settings { 4 | /// 5 | /// A class representing a single key-value-pair of two strings in a way that can be serialized by Unity. 6 | /// 7 | [Serializable] 8 | public class StringValuePair { 9 | /// And arbitrary string key. 10 | public string Key; 11 | /// And arbitrary string value. 12 | public string Value; 13 | } 14 | } -------------------------------------------------------------------------------- /Runtime/StringValuePair.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0e0378aa8e8c9f0408c580f0f8b3c73d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/UI.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e11dd7dc67a1d344877a5c9fd6979ae 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/UI/AssignedSettingControl.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | using UnityEngine; 3 | 4 | namespace Zenvin.Settings.UI { 5 | /// 6 | /// An implementation of 7 | /// that allows for manually assigning a () through the editor. 8 | /// 9 | /// The most basic type of that this control can handle. 10 | /// The type used by the handled . 11 | public abstract class AssignedSettingControl : SettingControl where TControlType : SettingBase { 12 | 13 | [Tooltip("The value of this field will be used to set up the control when it first becomes active.")] 14 | [SerializeField] private TControlType assignedSetting; 15 | [Tooltip("If enabled, the control's GameObject will be disabled, if there is no assigned setting.")] 16 | [SerializeField] private bool disableWhenMissingSetting = true; 17 | 18 | 19 | private void Start () { 20 | if (SettingRaw != null) { 21 | return; 22 | } 23 | if (assignedSetting == null) { 24 | if (disableWhenMissingSetting) { 25 | gameObject.SetActive (false); 26 | } 27 | return; 28 | } 29 | 30 | Setup (assignedSetting); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Runtime/UI/AssignedSettingControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 578c68584500a2a42badda42ae59af38 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/UI/SettingControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68d45db414c482544aef8bfae4e1b467 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/UI/SettingControlCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using System; 4 | using Zenvin.Settings.Framework; 5 | 6 | namespace Zenvin.Settings.UI { 7 | /// 8 | /// Helper class for managing references to prefabs. 9 | /// 10 | [Serializable] 11 | public class SettingControlCollection { 12 | 13 | private readonly Dictionary controlDict = new Dictionary (); 14 | 15 | [field: SerializeField] public bool AssignBaseTypes { get; private set; } = true; 16 | [SerializeField] private SettingControl[] controls; 17 | 18 | 19 | public SettingControl this[Type type] => GetControl (type); 20 | 21 | 22 | /// 23 | /// Tries to return a matching the given . 24 | /// 25 | /// The of to retrieve. 26 | /// The found , if any. 27 | /// Whether to allow recursive searches for valid controls. Slower the first time, but may yield more accurate results. Enabled by default. 28 | public bool TryGetControl (Type type, out SettingControl control, bool allowRecursion = true) { 29 | if (type == null) { 30 | control = null; 31 | return false; 32 | } 33 | InitDict (); 34 | bool success = controlDict.TryGetValue (type, out control); 35 | 36 | if (!success && allowRecursion) { 37 | Type _type = type; 38 | Type baseType = typeof (SettingBase<>); 39 | 40 | while (_type != null && (!type.IsConstructedGenericType || type.GetGenericTypeDefinition () != baseType)) { 41 | _type = _type.BaseType; 42 | if (_type is null) 43 | break; 44 | 45 | if (controlDict.TryGetValue (_type, out control)) { 46 | controlDict[type] = control; 47 | break; 48 | } 49 | } 50 | return control != null; 51 | } 52 | 53 | return success; 54 | } 55 | 56 | /// 57 | /// Tries to return a matching the given . 58 | /// 59 | /// The found , if any. 60 | public bool TryGetControl (out SettingControl control) where T : SettingBase { 61 | return TryGetControl (typeof (T), out control); 62 | } 63 | 64 | /// 65 | /// Returns either the last matching the given , or null. 66 | /// 67 | /// The of to retrieve. 68 | public SettingControl GetControl (Type type) { 69 | if (TryGetControl (type, out SettingControl control)) { 70 | return control; 71 | } 72 | return null; 73 | } 74 | 75 | /// 76 | /// Returns either the last matching the given , or null. 77 | /// 78 | public SettingControl GetControl () where T : SettingBase { 79 | if (TryGetControl (typeof (T), out SettingControl control)) { 80 | return control; 81 | } 82 | return null; 83 | } 84 | 85 | 86 | private void InitDict (bool force = false) { 87 | if (controls.Length == controlDict.Count && !force) { 88 | return; 89 | } 90 | controlDict.Clear (); 91 | foreach (var sc in controls) { 92 | if (sc != null) { 93 | controlDict[sc.ControlType] = sc; 94 | } 95 | } 96 | if (AssignBaseTypes) { 97 | SetupBaseTypeKeys (); 98 | } 99 | } 100 | 101 | private void SetupBaseTypeKeys () { 102 | Type baseType = typeof (SettingBase<>); 103 | 104 | var coll = new List (controlDict.Keys); 105 | foreach (var type in coll) { 106 | Type _type; 107 | do { 108 | _type = type.BaseType; 109 | controlDict[_type] = controlDict[type]; 110 | 111 | } while (_type != baseType && (!_type.IsConstructedGenericType || _type.GetGenericTypeDefinition () == baseType) && !controlDict.ContainsKey (_type)); 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Runtime/UI/SettingControlCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 587db26a57dfa0c43bef2accc8b01cf3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/UI/Zenvin.Settings.UI.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Zenvin.Settings.UI", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:2407e9dba5422d242bcb0a0c026a4b2f", 6 | "GUID:ac552a92ec43d4447b72a745b1ec5db0", 7 | "GUID:e4427921c419fbe45ab53ffae928789c" 8 | ], 9 | "includePlatforms": [], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Runtime/UI/Zenvin.Settings.UI.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b19a3560d2f7536459ead567ec685fb0 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/UpdateValueMode.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings { 2 | public enum UpdateValueMode { 3 | DontUpdate, 4 | SetIfDefault, 5 | ApplyIfDefault, 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Runtime/UpdateValueMode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f1f3d14c5fd9d044a0f86407c0b25a3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Utility.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47bd7a7015ef37348808f42699898700 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Utility/EnumUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Zenvin.Settings.Utility { 4 | public static class EnumUtility { 5 | 6 | public static object[] ValuesToArray () where T : struct { 7 | Type type = typeof (T); 8 | if (!type.IsEnum) { 9 | throw new Exception ($"Given type ({type.FullName}) must be an enum."); 10 | } 11 | 12 | var values = Enum.GetValues (type); 13 | object[] tempValues = new object[values.Length]; 14 | for (int i = 0; i < tempValues.Length; i++) { 15 | tempValues[i] = values.GetValue (i); 16 | } 17 | return tempValues; 18 | } 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /Runtime/Utility/EnumUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e513257755a3e7d48839070c1920aef9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Utility/HasDeviatingDefaultValueAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Zenvin.Settings.Utility { 4 | /// 5 | /// Attribute to be attached to any SettingBase class, to hide the default value from the inspector.

6 | /// This can be useful to avoid confusion, in case the Setting in question implements its own "default" value. 7 | ///
8 | [AttributeUsage (AttributeTargets.Class)] 9 | public class HasDeviatingDefaultValueAttribute : Attribute { } 10 | } -------------------------------------------------------------------------------- /Runtime/Utility/HasDeviatingDefaultValueAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 625f94e756caaae4d9bc8bf0a3fe56d1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Utility/Zenvin.Settings.Utility.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Zenvin.Settings.Utility" 3 | } 4 | -------------------------------------------------------------------------------- /Runtime/Utility/Zenvin.Settings.Utility.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e4427921c419fbe45ab53ffae928789c 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Zenvin.Settings.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Zenvin.Settings", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": false, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [], 13 | "noEngineReferences": false 14 | } -------------------------------------------------------------------------------- /Runtime/Zenvin.Settings.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2407e9dba5422d242bcb0a0c026a4b2f 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Components.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 89cd15914fcccab49933ce880aeff490 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Components/BubbleUpChangeEvents.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Zenvin.Settings.Framework; 3 | using Zenvin.Settings.Framework.Components; 4 | 5 | namespace Zenvin.Settings.Samples { 6 | public class BubbleUpChangeEvents : TypedFrameworkComponent, ISettingEventReceiver { 7 | [SerializeField] private bool bubbleUp = true; 8 | [SerializeField, Min (0)] private int skipLevels = 0; 9 | 10 | 11 | void ISettingEventReceiver.OnValueChanging (SettingBase setting, SettingBase.ValueChangeMode mode) { 12 | var target = GetTargetGroup (); 13 | if (target != null && target.TryGetComponent (out ISettingEventReceiver receiver)) { 14 | receiver.OnValueChanged (setting, mode); 15 | } 16 | } 17 | 18 | void ISettingEventReceiver.OnValueChanged (SettingBase setting, SettingBase.ValueChangeMode mode) { 19 | var target = GetTargetGroup (); 20 | if (target != null && target.TryGetComponent (out ISettingEventReceiver receiver)) { 21 | receiver.OnValueChanged (setting, mode); 22 | } 23 | } 24 | 25 | 26 | private SettingsGroup GetTargetGroup () { 27 | var skipped = 0; 28 | var target = Container; 29 | while (target != null && skipped < skipLevels) { 30 | target = target.Parent; 31 | skipped++; 32 | } 33 | 34 | return target; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Samples~/Components/BubbleUpChangeEvents.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e66d95b529ea7654399f95133ead899e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Components/ConditionalVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Zenvin.Settings.Framework; 4 | using Zenvin.Settings.Framework.Components; 5 | 6 | namespace Zenvin.Settings.Samples { 7 | public class ConditionalVisibility : FrameworkComponent { 8 | public enum TargetValue { 9 | CachedValue, 10 | CurrentValue, 11 | } 12 | 13 | [SerializeField] private SettingReference condition; 14 | [SerializeField] private TargetValue targetValue = TargetValue.CurrentValue; 15 | [SerializeField] private SettingVisibility enabledVisibility = SettingVisibility.Visible; 16 | [SerializeField] private SettingVisibility disabledVisibility = SettingVisibility.Disabled; 17 | 18 | 19 | public override void OnInitialize () { 20 | if (condition == null) 21 | return; 22 | 23 | condition.ValueChanged += ConditionValueChangedHandler; 24 | UpdateVisibility (); 25 | } 26 | 27 | public override void OnCreateWithValues (StringValuePair[] values) { 28 | if (values == null) 29 | return; 30 | 31 | for (int i = 0; i < values.Length; i++) { 32 | var value = values[i]; 33 | switch (value.Key) { 34 | case "condition": 35 | UpdateConditionFromGuid (value.Value); 36 | break; 37 | case "targetValue": 38 | Enum.TryParse (value.Value, true, out targetValue); 39 | break; 40 | case "enabledVisibility": 41 | Enum.TryParse (value.Value, true, out enabledVisibility); 42 | break; 43 | case "disabledVisibility": 44 | Enum.TryParse (value.Value, true, out disabledVisibility); 45 | break; 46 | } 47 | } 48 | } 49 | 50 | 51 | private void ConditionValueChangedHandler (SettingBase.ValueChangeMode mode) { 52 | UpdateVisibility (); 53 | } 54 | 55 | private void UpdateVisibility () { 56 | var visibility = GetGoalVisibility (); 57 | BaseContainer.SetVisibility (visibility); 58 | } 59 | 60 | private SettingVisibility GetGoalVisibility () { 61 | if (condition == null) 62 | return BaseContainer.Visibility; 63 | 64 | var state = targetValue switch { 65 | TargetValue.CachedValue => condition.CachedValue, 66 | TargetValue.CurrentValue => condition.CurrentValue, 67 | _ => true 68 | }; 69 | return state ? enabledVisibility : disabledVisibility; 70 | } 71 | 72 | 73 | private void UpdateConditionFromGuid (string guid) { 74 | if (condition != null || string.IsNullOrWhiteSpace (guid)) 75 | return; 76 | 77 | var asset = BaseContainer switch { 78 | SettingBase setting => setting.Asset, 79 | SettingsGroup group => GetRootAsset (group), 80 | _ => null 81 | }; 82 | if (asset == null) 83 | return; 84 | 85 | condition = asset.GetSettingReference (guid); 86 | } 87 | 88 | private SettingsAsset GetRootAsset (SettingsGroup group) { 89 | if (group == null) 90 | return null; 91 | 92 | var asset = group as SettingsAsset; 93 | while (asset == null && group != null) { 94 | group = group.Parent; 95 | asset = group as SettingsAsset; 96 | } 97 | return asset; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Samples~/Components/ConditionalVisibility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c30e4cc8c06ec6140ac0b1d7ef90b4f4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 18d6924e1cec1474888c413c8f834e9f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3bbb1e45a3f735947bdb065696d35ffd 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets/Icons8.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d82fa5c8c4de7ec46b2207bbafdc2e5c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets/Icons8/CREDITS.txt: -------------------------------------------------------------------------------- 1 | Restart by Icons8 https://icons8.com/icon/16877/restart -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets/Icons8/CREDITS.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b24e62365d599b147a8ddc8a1c994ad6 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets/Icons8/Restart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenvin-dev/UnitySettingsFramework/2da01eae0d47c96950d517b9e720965f5b444657/Samples~/Keybind Setting/Assets/Icons8/Restart.png -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets/Icons8/Restart.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33b4b3ab40c96c94aaad69fc3f6ef712 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 1 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 0 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 1 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 8 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | - serializedVersion: 3 91 | buildTarget: Windows Store Apps 92 | maxTextureSize: 2048 93 | resizeAlgorithm: 0 94 | textureFormat: -1 95 | textureCompression: 1 96 | compressionQuality: 50 97 | crunchedCompression: 0 98 | allowsAlphaSplitting: 0 99 | overridden: 0 100 | androidETC2FallbackOverride: 0 101 | forceMaximumCompressionQuality_BC6H_BC7: 0 102 | spriteSheet: 103 | serializedVersion: 2 104 | sprites: [] 105 | outline: [] 106 | physicsShape: [] 107 | bones: [] 108 | spriteID: 5e97eb03825dee720800000000000000 109 | internalID: 0 110 | vertices: [] 111 | indices: 112 | edges: [] 113 | weights: [] 114 | secondaryTextures: [] 115 | spritePackingTag: 116 | pSDRemoveMatte: 0 117 | pSDShowRemoveMatteOption: 0 118 | userData: 119 | assetBundleName: 120 | assetBundleVariant: 121 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets/Rebind Operation Settings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: bbaf504749d593749b8ae64ecafcdf0d, type: 3} 13 | m_Name: Rebind Operation Settings 14 | m_EditorClassIdentifier: 15 | rebindCancelSource: 2 16 | cancelActionReferences: 17 | - {fileID: 7727032971491509709, guid: 5af24a746b199d945b2aea0b3b50e409, type: 3} 18 | cancelActionBindings: 19 | - /escape 20 | - '*/{Cancel}' 21 | excludeBindings: 22 | - /position 23 | - /delta 24 | - /clickCount 25 | - /clickCount 26 | useMask: 0 27 | bindingMask: 28 | m_Name: 29 | m_Id: 30 | m_Path: 31 | m_Interactions: 32 | m_Processors: 33 | m_Groups: 34 | m_Action: 35 | m_Flags: 0 36 | suppressMatchingEvents: 1 37 | ignoreNoisyControls: 1 38 | minMagnitude: 0.5 39 | hasTimeout: 1 40 | timeout: 10 41 | generalizeControlPath: 1 42 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Assets/Rebind Operation Settings.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a3bf6fee1764b3469c8aa6c33224a66 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1302d78a04d6173489e796dd9db22293 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Prefabs/Keybind Control.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7542f7f7bd89fd44959087923f6e09c 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Prefabs/Keybind Popup.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c858cfd0105c36140a3ec177ebbc79ec 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 415b3a99b9db1e946a18bb6ab35efffc 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d797842104c8474fbbac049ec52da8e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Editor/InputActionBindingPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c6e0d24c57b1534dba6232c59f831e7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75a7d586d959ded418476ed6f4034534 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/InputActionBinding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.InputSystem; 4 | 5 | namespace Zenvin.Settings.Samples { 6 | [Serializable] 7 | public sealed class InputActionBinding { 8 | [SerializeField] private InputActionReference actionReference; 9 | [SerializeField] private string bindingId; 10 | 11 | public InputActionReference ActionReference => actionReference; 12 | public string BindingId => bindingId; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/InputActionBinding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5ffcac581800d64591417c75a97f5fa 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindControl.cs: -------------------------------------------------------------------------------- 1 | using TMPro; 2 | using UnityEngine; 3 | using Zenvin.Settings.Framework; 4 | 5 | namespace Zenvin.Settings.Samples { 6 | [AddComponentMenu ("Zenvin/Settings/UI/Keybind Control")] 7 | public class KeybindControl : KeybindControlBase { 8 | 9 | [SerializeField] private TextMeshProUGUI labelText; 10 | [SerializeField] private TextMeshProUGUI bindingText; 11 | 12 | 13 | /// 14 | protected override void OnSetup () { 15 | base.OnSetup (); 16 | 17 | if (labelText != null) { 18 | labelText.SetText (SettingRaw.Name); 19 | } 20 | UpdateBindingUI (); 21 | } 22 | 23 | /// 24 | protected override void OnSettingValueChanged (SettingBase.ValueChangeMode mode) { 25 | UpdateBindingUI (); 26 | } 27 | 28 | /// 29 | protected override void OnStartedRebind () { 30 | KeybindPopupBase.Open (this); 31 | UpdateBindingUI (); 32 | } 33 | 34 | /// 35 | protected override void OnEndedRebind (bool cancelled) { 36 | KeybindPopupBase.Close (); 37 | UpdateBindingUI (); 38 | } 39 | 40 | 41 | private void UpdateBindingUI () { 42 | if (bindingText == null) 43 | return; 44 | 45 | bindingText.SetText (Setting.GetDisplayTextForCurrentValue ()); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66bcff44cf4cf3b4994dae1f4331e7d3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindControlBase.cs: -------------------------------------------------------------------------------- 1 | using TMPro; 2 | using UnityEngine; 3 | using Zenvin.Settings.UI; 4 | using RebindOp = UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation; 5 | 6 | namespace Zenvin.Settings.Samples { 7 | public abstract class KeybindControlBase : AssignedSettingControl { 8 | 9 | private static RebindOp operation; 10 | 11 | [SerializeField] private RebindOperationSettings rebindSettings; 12 | 13 | 14 | /// 15 | /// Calls on the control's associated Setting.

16 | /// Meant for resetting individual key binds through UI. 17 | ///
18 | public void ResetSetting () { 19 | Setting.ResetValue (false); 20 | } 21 | 22 | /// 23 | /// Attempts to start rebinding the input binding assigned to the referenced . 24 | /// 25 | public void StartRebind () { 26 | // Cancel any currently running rebind operation 27 | Cleanup (); 28 | 29 | // Cancel if there is no Setting assigned to the Control 30 | if (Setting == null) { 31 | return; 32 | } 33 | 34 | // Get active rebind settings 35 | var rebindOpSettings = Setting.RebindSettings; 36 | // If there are no rebind settings set in the Setting object 37 | if (rebindOpSettings == null) { 38 | // Use the rebind settings referenced in the Control 39 | rebindOpSettings = rebindSettings; 40 | } 41 | // Cancel if no settings for rebinding are given 42 | if (rebindOpSettings == null) { 43 | Debug.LogError ($"Cannot rebind {Setting}, because RebindSettings are missing."); 44 | return; 45 | } 46 | 47 | // Create a new RebindingOperation from the rebindSettings 48 | operation = rebindOpSettings.GetOperation (Setting.ExcludeControls, Setting.GetActiveBindingMask()); 49 | // Cancel if creating the operation was not successful 50 | if (operation == null) { 51 | return; 52 | } 53 | 54 | // Set up the operation's callback handlers 55 | operation 56 | .OnApplyBinding(ApplyRebindingOperationHandler) 57 | .OnComplete (CompletedRebindingOperationHandler) 58 | .OnCancel (CancelledRebindingOperationHandler); 59 | 60 | // Start the operation to listen for input to rebind with 61 | operation.Start (); 62 | // Notify the control that rebinding started 63 | OnStartedRebind (); 64 | } 65 | 66 | 67 | /// 68 | /// Called when was called successfully. 69 | /// 70 | protected abstract void OnStartedRebind (); 71 | 72 | /// 73 | /// Called after the operation started by has ended. 74 | /// 75 | /// Whether the operation that triggered the method call was cancelled. 76 | protected abstract void OnEndedRebind (bool cancelled); 77 | 78 | 79 | private void CancelledRebindingOperationHandler (RebindOp operation) { 80 | OnEndedRebind (true); 81 | Cleanup (); 82 | } 83 | 84 | private void CompletedRebindingOperationHandler (RebindOp operation) { 85 | OnEndedRebind (false); 86 | Cleanup (); 87 | } 88 | 89 | private void ApplyRebindingOperationHandler (RebindOp operation, string path) { 90 | Setting.SetValue (path); 91 | } 92 | 93 | private void Cleanup () { 94 | if (operation == null) 95 | return; 96 | 97 | if (operation.started && !operation.completed && !operation.canceled) 98 | operation.Cancel (); 99 | 100 | operation.Dispose (); 101 | operation = null; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindControlBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f6e9665fd0f02a418b8ea949ef6a158 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindPopup.cs: -------------------------------------------------------------------------------- 1 | using TMPro; 2 | using UnityEngine; 3 | 4 | namespace Zenvin.Settings.Samples { 5 | [AddComponentMenu ("Zenvin/Settings/UI/Keybind Popup")] 6 | public class KeybindPopup : KeybindPopupBase { 7 | 8 | [SerializeField] private TextMeshProUGUI label; 9 | 10 | 11 | private void Start () { 12 | gameObject.SetActive (false); 13 | } 14 | 15 | protected override void OnOpen () { 16 | gameObject.SetActive (true); 17 | if (label != null) { 18 | label.SetText ($"Rebinding {Control.SettingRaw.Name}.\nWaiting for input..."); 19 | } 20 | } 21 | 22 | protected override void OnClose () { 23 | gameObject.SetActive (false); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindPopup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6f6e99673285eb42be15b876aa78ae7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindPopupBase.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Zenvin.Settings.Samples { 4 | [DisallowMultipleComponent] 5 | public abstract class KeybindPopupBase : MonoBehaviour { 6 | 7 | private static KeybindPopupBase popup; 8 | 9 | protected KeybindControlBase Control { get; private set; } = null; 10 | 11 | public bool IsOpen => popup != null && popup.Control != null; 12 | 13 | 14 | private void Awake () { 15 | if (popup != null && popup != this) { 16 | Destroy (gameObject); 17 | return; 18 | } 19 | popup = this; 20 | OnAwake (); 21 | } 22 | 23 | 24 | public static bool Open (KeybindControlBase control) { 25 | if (control == null) 26 | return false; 27 | if (popup == null) 28 | return false; 29 | 30 | popup.Control = control; 31 | popup.OnOpen (); 32 | return true; 33 | } 34 | 35 | public static void Close () { 36 | if (popup == null) 37 | return; 38 | if (popup.Control == null) 39 | return; 40 | 41 | popup.OnClose (); 42 | popup.Control = null; 43 | } 44 | 45 | 46 | protected virtual void OnAwake () { } 47 | 48 | protected virtual void OnOpen () { } 49 | 50 | protected virtual void OnClose () { } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindPopupBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 563f03ff88376444a874488803a4facc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c9d7ab08a01680438bcc7cd1f65eaf8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine.InputSystem; 3 | 4 | namespace Zenvin.Settings.Samples { 5 | public enum ActionPath { 6 | Original, 7 | Override, 8 | Effective, 9 | } 10 | 11 | public static class KeybindUtility { 12 | public static bool TryGetKeybinding (InputActionBinding inputAction, ActionPath path, out Keybinding binding) { 13 | binding = default; 14 | if (!inputAction.IsValid (out var bindingId)) 15 | return false; 16 | 17 | var action = inputAction.ActionReference.action; 18 | if (!action.TryGetBindingById (bindingId, out var actionBinding)) 19 | return false; 20 | 21 | var actionPath = path switch { 22 | ActionPath.Original => actionBinding.path, 23 | ActionPath.Override => actionBinding.overridePath, 24 | ActionPath.Effective => actionBinding.effectivePath, 25 | _ => null 26 | }; 27 | if (actionPath == null) 28 | return false; 29 | 30 | binding = new Keybinding { 31 | Id = bindingId.ToString(), 32 | Path = actionPath, 33 | }; 34 | return true; 35 | } 36 | 37 | public static bool IsValid (this InputActionBinding binding) { 38 | return IsValid (binding, out _); 39 | } 40 | 41 | public static bool IsValid (this InputActionBinding binding, out Guid bindingId) { 42 | if (binding == null) 43 | return false; 44 | if (binding.ActionReference == null) 45 | return false; 46 | if (binding.ActionReference.action == null) 47 | return false; 48 | if (string.IsNullOrWhiteSpace (binding.BindingId)) 49 | return false; 50 | 51 | if (!Guid.TryParse (binding.BindingId, out bindingId)) 52 | return false; 53 | 54 | return true; 55 | } 56 | 57 | public static bool TryGetBindingById (this InputAction action, Guid bindingId, out InputBinding binding) { 58 | binding = default; 59 | if (action == null) 60 | return false; 61 | 62 | foreach (var actionBinding in action.bindings) { 63 | if (actionBinding.id == bindingId) { 64 | binding = actionBinding; 65 | return true; 66 | } 67 | } 68 | 69 | return false; 70 | } 71 | 72 | public static bool TryGetBindingIndex (this InputAction action, string bindingId, out int index) { 73 | index = -1; 74 | return Guid.TryParse (bindingId, out var guid) && TryGetBindingIndex (action, guid, out index); 75 | } 76 | 77 | public static bool TryGetBindingIndex (this InputAction action, Guid bindingId, out int index) { 78 | index = -1; 79 | if (action == null) 80 | return false; 81 | 82 | var bindings = action.bindings; 83 | for (int i = 0; i < bindings.Count; i++) { 84 | if (bindings[i].id == bindingId) { 85 | index = i; 86 | return true; 87 | } 88 | } 89 | 90 | return false; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/KeybindUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49f6b89aa9ee8aa4380c7b29b2123c52 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/Keybinding.cs: -------------------------------------------------------------------------------- 1 | namespace Zenvin.Settings.Samples { 2 | public struct Keybinding { 3 | public string Id { get; set; } 4 | public string Path { get; set; } 5 | 6 | 7 | public override string ToString () { 8 | var pathEmpty = string.IsNullOrWhiteSpace (Path); 9 | var idEmpty = string.IsNullOrWhiteSpace (Id); 10 | 11 | if (pathEmpty && idEmpty) 12 | return "Keybinding [empty]"; 13 | if (!pathEmpty && !idEmpty) 14 | return $"Keybinding [{Path}] (overrides {Id})"; 15 | if (idEmpty) 16 | return $"Keybinding [{Path}]"; 17 | 18 | return $"Keybinding [empty] overrides Binding {Id}"; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/Keybinding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a93022adf5efaa04883a69de71ecaaf3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Keybind Setting/Scripts/Runtime/RebindOperationSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bbaf504749d593749b8ae64ecafcdf0d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Localization Setting.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e27a8d9b87f316c4492d81ca2d38bc4e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 914ed58e417a97043baef06cd1a680c4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Prefabs/Localization Control.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41a6ecb8dbed19d43a16980b0314a064 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79386ec064734e946aab9be099773c03 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5cdf03a05d6714a4abe66700f2a3ed82 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/Editor/LocaleSelectorPropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.ObjectModel; 3 | using UnityEditor; 4 | using UnityEditor.Localization; 5 | using UnityEngine; 6 | 7 | namespace Zenvin.Settings.Samples { 8 | [CustomPropertyDrawer(typeof(LocaleSelectorAttribute))] 9 | internal class LocaleSelectorPropertyDrawer : PropertyDrawer { 10 | 11 | private GUIContent[] options; 12 | 13 | 14 | public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { 15 | if (property.propertyType != SerializedPropertyType.Integer) { 16 | EditorGUI.PropertyField (position, property, label); 17 | return; 18 | } 19 | 20 | var locales = LocalizationEditorSettings.GetLocales (); 21 | UpdateOptions (locales); 22 | 23 | property.intValue = EditorGUI.Popup (position, label, property.intValue, options); 24 | property.serializedObject.ApplyModifiedProperties (); 25 | } 26 | 27 | private void UpdateOptions (ReadOnlyCollection locales) { 28 | if (options == null) { 29 | options = new GUIContent[locales.Count]; 30 | } else if (options.Length != locales.Count) { 31 | Array.Resize (ref options, locales.Count); 32 | } 33 | 34 | for (int i = 0; i < options.Length; i++) { 35 | options[i] = new GUIContent(locales[i].LocaleName); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/Editor/LocaleSelectorPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1253e435f2229134289f78430a5d8d62 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocaleSelectorAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Zenvin.Settings.Samples { 5 | [AttributeUsage(AttributeTargets.Field)] 6 | public class LocaleSelectorAttribute : PropertyAttribute { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocaleSelectorAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cee5c18ede837d64185bab6c35443989 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizationControl.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine.Localization.Settings; 2 | using UnityEngine.Localization.Tables; 3 | using System.Collections.Generic; 4 | using Zenvin.Settings.Framework; 5 | using UnityEngine.Localization; 6 | using UnityEngine; 7 | using TMPro; 8 | 9 | namespace Zenvin.Settings.Samples { 10 | [AddComponentMenu("Zenvin/Settings/UI/Localization Control")] 11 | public class LocalizationControl : LocalizedControlBase { 12 | 13 | [SerializeField] private TextMeshProUGUI label; 14 | [SerializeField] private TMP_Dropdown dropdown; 15 | [SerializeField] private TableReference localizationTable; 16 | 17 | 18 | protected override void OnLocalizedSetup () { 19 | var options = new List (); 20 | int current = 0; 21 | 22 | // generate dropdown info and get selected locale index 23 | for (int i = 0; i < Setting.LocaleCount; i++) { 24 | var locale = Setting[i]; 25 | options.Add (new TMP_Dropdown.OptionData (locale.LocaleName)); 26 | if (locale == LocalizationSettings.SelectedLocale) { 27 | current = i; 28 | } 29 | } 30 | 31 | // set up dropdown 32 | if (dropdown != null) { 33 | dropdown.ClearOptions (); 34 | dropdown.AddOptions (options); 35 | } 36 | 37 | // update setting to be selected locale 38 | Setting.SetValue (current); 39 | Setting.ApplyValue (); 40 | } 41 | 42 | protected override void OnLocalizationChanged (Locale locale) { 43 | if (label != null) { 44 | if (string.IsNullOrWhiteSpace (Setting.NameLocalizationKey)) { 45 | label.text = Setting.Name; 46 | } else { 47 | label.text = LocalizationSettings.StringDatabase.GetLocalizedString (localizationTable, Setting.NameLocalizationKey, locale); 48 | } 49 | } 50 | } 51 | 52 | protected override void OnSettingValueChanged (SettingBase.ValueChangeMode mode) { 53 | if (dropdown != null) { 54 | dropdown.SetValueWithoutNotify (Setting.CachedValue); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizationControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00b5a61efb2635440b4a337455a69599 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizationControlFactory.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | using Zenvin.Settings.Loading; 3 | 4 | namespace Zenvin.Settings.Samples { 5 | public class LocalizationControlFactory : ISettingFactory { 6 | 7 | string ISettingFactory.GetDefaultValidType () { 8 | return "language"; 9 | } 10 | 11 | SettingBase ISettingFactory.CreateSettingFromType (string defaultValue, StringValuePair[] values) { 12 | return LocalizationSetting.CreateInstanceWithValues (int.TryParse (defaultValue, out int val) ? val : 0, values); 13 | } 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizationControlFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63b351144bdbf88419cb18ddb7534d63 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizationSetting.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Localization; 5 | using UnityEngine.Localization.Settings; 6 | using Zenvin.Settings.Framework; 7 | using Zenvin.Settings.Framework.Serialization; 8 | using Zenvin.Settings.Utility; 9 | 10 | namespace Zenvin.Settings.Samples { 11 | [HasDeviatingDefaultValue] 12 | public class LocalizationSetting : SettingBase, ISerializable, ISerializable { 13 | 14 | private List locales; 15 | 16 | [SerializeField, LocaleSelector] private int defaultLocale; 17 | 18 | public int LocaleCount => locales?.Count ?? 0; 19 | public Locale this[int index] => locales == null || index < 0 || index >= locales.Count ? null : locales[index]; 20 | 21 | 22 | protected override void ProcessValue (ref int value) { 23 | value = Mathf.Clamp (value, 0, LocaleCount - 1); 24 | } 25 | 26 | // On initialization 27 | protected override void OnInitialize () { 28 | // update locales list 29 | locales = LocalizationSettings.AvailableLocales.Locales; 30 | } 31 | 32 | protected override int OnSetupInitialDefaultValue () { 33 | return defaultLocale; 34 | } 35 | 36 | // After appying the Setting 37 | protected override void OnValueChanged (ValueChangeMode mode) { 38 | // if the value is not being applied, cancel 39 | if (mode != ValueChangeMode.Apply) { 40 | return; 41 | } 42 | 43 | // get locale that the setting wants to be selected 44 | var loc = this[CurrentValue]; 45 | 46 | if (loc != null) { 47 | // update selected locale 48 | LocalizationSettings.SelectedLocale = loc; 49 | } 50 | } 51 | 52 | 53 | void ISerializable.OnDeserialize (JObject value) { 54 | if (value.TryGetValue ("value", out JToken token)) { 55 | SetValue ((int)token); 56 | } 57 | } 58 | 59 | void ISerializable.OnDeserialize (ValuePacket value) { 60 | if (value.TryRead ("value", out int val)) { 61 | SetValue (val); 62 | } 63 | } 64 | 65 | void ISerializable.OnSerialize (JObject value) { 66 | value.Add ("value", CurrentValue); 67 | } 68 | 69 | void ISerializable.OnSerialize (ValuePacket value) { 70 | value.Write ("value", CurrentValue); 71 | } 72 | 73 | } 74 | } -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizationSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 22bf1eb2fee5b5b42a0b2da424b93d10 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizedControlBase.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine.Localization.Settings; 2 | using Zenvin.Settings.Framework; 3 | using UnityEngine.Localization; 4 | using Zenvin.Settings.UI; 5 | 6 | namespace Zenvin.Settings.Samples { 7 | public abstract class LocalizedControlBase : SettingControl where T : SettingBase { 8 | 9 | protected sealed override void OnSetup () { 10 | LocalizationSettings.SelectedLocaleChanged += OnLocalizationChanged; 11 | OnLocalizedSetup (); 12 | OnLocalizationChanged (LocalizationSettings.SelectedLocale); 13 | } 14 | 15 | protected override void OnDestroy () { 16 | LocalizationSettings.SelectedLocaleChanged -= OnLocalizationChanged; 17 | base.OnDestroy (); 18 | } 19 | 20 | /// 21 | /// Method to replace , because that is used by .

22 | /// 23 | ///
24 | protected virtual void OnLocalizedSetup () { } 25 | 26 | protected virtual void OnLocalizationChanged (Locale locale) { } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /Samples~/Localization Setting/Scripts/LocalizedControlBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6a22d91fa366b4498cb6d9b31373992 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1372e4deda63a024db81e63d3189d8a5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c54d5418f21ceca44a2a4c06defd8b98 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs/Dropdown Control.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: faa0f1f188e6f3544aa00d94143d7df9 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs/Header.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 64568e354908bce42bb6cccd47335488 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs/Slider Control.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94280cc4c5815d147a24070d834c82e0 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs/Tab Button.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 867b0b2c85620d746940f832227a3045 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs/Tab Content.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &5608609929991201355 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 5608609929991201348} 12 | - component: {fileID: 5608609929991201350} 13 | - component: {fileID: 5608609929991201349} 14 | m_Layer: 5 15 | m_Name: Tab Content 16 | m_TagString: Untagged 17 | m_Icon: {fileID: 0} 18 | m_NavMeshLayer: 0 19 | m_StaticEditorFlags: 0 20 | m_IsActive: 1 21 | --- !u!224 &5608609929991201348 22 | RectTransform: 23 | m_ObjectHideFlags: 0 24 | m_CorrespondingSourceObject: {fileID: 0} 25 | m_PrefabInstance: {fileID: 0} 26 | m_PrefabAsset: {fileID: 0} 27 | m_GameObject: {fileID: 5608609929991201355} 28 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 29 | m_LocalPosition: {x: 0, y: 0, z: 0} 30 | m_LocalScale: {x: 1, y: 1, z: 1} 31 | m_Children: [] 32 | m_Father: {fileID: 0} 33 | m_RootOrder: 0 34 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 35 | m_AnchorMin: {x: 0, y: 1} 36 | m_AnchorMax: {x: 1, y: 1} 37 | m_AnchoredPosition: {x: 0, y: -0} 38 | m_SizeDelta: {x: 0, y: 0} 39 | m_Pivot: {x: 0.5, y: 1} 40 | --- !u!114 &5608609929991201350 41 | MonoBehaviour: 42 | m_ObjectHideFlags: 0 43 | m_CorrespondingSourceObject: {fileID: 0} 44 | m_PrefabInstance: {fileID: 0} 45 | m_PrefabAsset: {fileID: 0} 46 | m_GameObject: {fileID: 5608609929991201355} 47 | m_Enabled: 1 48 | m_EditorHideFlags: 0 49 | m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} 50 | m_Name: 51 | m_EditorClassIdentifier: 52 | m_Padding: 53 | m_Left: 0 54 | m_Right: 0 55 | m_Top: 0 56 | m_Bottom: 0 57 | m_ChildAlignment: 1 58 | m_Spacing: 10 59 | m_ChildForceExpandWidth: 1 60 | m_ChildForceExpandHeight: 1 61 | m_ChildControlWidth: 1 62 | m_ChildControlHeight: 0 63 | m_ChildScaleWidth: 1 64 | m_ChildScaleHeight: 0 65 | m_ReverseArrangement: 0 66 | --- !u!114 &5608609929991201349 67 | MonoBehaviour: 68 | m_ObjectHideFlags: 0 69 | m_CorrespondingSourceObject: {fileID: 0} 70 | m_PrefabInstance: {fileID: 0} 71 | m_PrefabAsset: {fileID: 0} 72 | m_GameObject: {fileID: 5608609929991201355} 73 | m_Enabled: 1 74 | m_EditorHideFlags: 0 75 | m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} 76 | m_Name: 77 | m_EditorClassIdentifier: 78 | m_HorizontalFit: 0 79 | m_VerticalFit: 2 80 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs/Tab Content.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33e85b8a14fc3c94d9d8cc562a355d76 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Prefabs/Toggle Control.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 755c3dab683e5af48aca1961f036a904 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80ee52d9db5c02541af1d141aa7dafbf 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Controls.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ddacd463a66876040a671d93c5c6b7f2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Controls/DropdownControl.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using TMPro; 4 | 5 | using Zenvin.Settings.Framework; 6 | using Zenvin.Settings.UI; 7 | 8 | namespace Zenvin.Settings.Samples { 9 | [AddComponentMenu("Zenvin/Settings/UI/Dropdown Control")] 10 | public class DropdownControl : SettingControl { 11 | 12 | [SerializeField] private TextMeshProUGUI label; 13 | [SerializeField] private TMP_Dropdown dropdown; 14 | 15 | 16 | protected override void OnSetup () { 17 | dropdown.ClearOptions (); 18 | dropdown.AddOptions (new List (Setting.Options)); 19 | dropdown.SetValueWithoutNotify (Setting.CurrentValue); 20 | label?.SetText (Setting.Name); 21 | } 22 | 23 | protected override void OnSettingValueChanged (SettingBase.ValueChangeMode mode) { 24 | dropdown?.SetValueWithoutNotify (Setting.CachedValue); 25 | } 26 | 27 | protected override void OnVisibilityChanged () { 28 | SettingVisibility vis = Setting.GetVisibilityInHierarchy (); 29 | dropdown.interactable = vis == SettingVisibility.Visible; 30 | gameObject.SetActive (vis != SettingVisibility.Hidden); 31 | } 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Controls/DropdownControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a1a8b976ca5c4a4fbccf87c73504ed9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Controls/SliderControl.cs: -------------------------------------------------------------------------------- 1 | using TMPro; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | using Zenvin.Settings.Framework; 6 | using Zenvin.Settings.UI; 7 | 8 | namespace Zenvin.Settings.Samples { 9 | [AddComponentMenu("Zenvin/Settings/UI/Slider Control")] 10 | public class SliderControl : SettingControl { 11 | 12 | [SerializeField] private TextMeshProUGUI label; 13 | [SerializeField] private Slider slider; 14 | [SerializeField] private TextMeshProUGUI valueLabel; 15 | 16 | 17 | protected override void OnSetup () { 18 | if (Setting.Increment == 0f) { 19 | slider.minValue = Setting.MinValue; 20 | slider.maxValue = Setting.MaxValue; 21 | slider.wholeNumbers = false; 22 | 23 | slider.SetValueWithoutNotify (Setting.CurrentValue); 24 | } else { 25 | slider.minValue = Setting.MinValue; 26 | slider.maxValue = (Setting.MaxValue - Setting.MinValue + Setting.Increment) / Setting.Increment + Setting.MinValue; 27 | slider.wholeNumbers = true; 28 | 29 | slider.SetValueWithoutNotify (Setting.CurrentValue * Setting.Increment); 30 | } 31 | 32 | label?.SetText (Setting.Name); 33 | UpdateValueLabel (); 34 | } 35 | 36 | protected override void OnSettingValueChanged (SettingBase.ValueChangeMode mode) { 37 | UpdateSlider (); 38 | } 39 | 40 | protected override void OnVisibilityChanged () { 41 | SettingVisibility vis = Setting.GetVisibilityInHierarchy (); 42 | slider.interactable = vis == SettingVisibility.Visible; 43 | gameObject.SetActive (vis != SettingVisibility.Hidden); 44 | } 45 | 46 | 47 | // TODO: Redo so increment snapping actually works RELIABLY. 48 | public void OnValueChange (float value) { 49 | if (Setting == null) { 50 | return; 51 | } 52 | 53 | //value = Mathf.Lerp (Setting.MinValue, Setting.MaxValue, value); 54 | //value = MathUtility.SnapValueToIncrement (value, Setting.Increment); 55 | 56 | //Setting.SetValue (value * Setting.Increment); 57 | 58 | if (Setting.Increment == 0f) { 59 | Setting.SetValue (value); 60 | } else { 61 | Setting.SetValue (value * Setting.Increment); 62 | } 63 | 64 | UpdateSlider (); 65 | } 66 | 67 | private void UpdateSlider () { 68 | if (slider != null) { 69 | //slider.SetValueWithoutNotify (Mathf.InverseLerp (Setting.MinValue, Setting.MaxValue, Setting.CachedValue)); 70 | slider.SetValueWithoutNotify (Setting.CachedValue / (Setting.Increment > 0 ? Setting.Increment : 1f)); 71 | } 72 | UpdateValueLabel (); 73 | } 74 | 75 | private void UpdateValueLabel () { 76 | if (valueLabel != null) { 77 | valueLabel.SetText ((Setting.CachedValue/* * Setting.Increment*/).ToString ("0.0")); 78 | } 79 | } 80 | 81 | } 82 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Controls/SliderControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00010136719e92649919462e3c8e48f8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Controls/ToggleControl.cs: -------------------------------------------------------------------------------- 1 | using TMPro; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | using Zenvin.Settings.Framework; 6 | using Zenvin.Settings.UI; 7 | 8 | namespace Zenvin.Settings.Samples { 9 | [AddComponentMenu("Zenvin/Settings/UI/Toggle Control")] 10 | public class ToggleControl : SettingControl { 11 | 12 | [SerializeField] private TextMeshProUGUI label; 13 | [SerializeField] private Toggle toggle; 14 | 15 | 16 | protected override void OnSetup () { 17 | label?.SetText (Setting.Name); 18 | toggle.SetIsOnWithoutNotify (Setting.CurrentValue); 19 | } 20 | 21 | protected override void OnSettingValueChanged (SettingBase.ValueChangeMode mode) { 22 | toggle?.SetIsOnWithoutNotify (Setting.CachedValue); 23 | } 24 | 25 | protected override void OnVisibilityChanged () { 26 | SettingVisibility vis = Setting.GetVisibilityInHierarchy (); 27 | toggle.interactable = vis == SettingVisibility.Visible; 28 | gameObject.SetActive (vis != SettingVisibility.Hidden); 29 | } 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Controls/ToggleControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 413e32404eac5b0418bec1617042e973 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/DropdownSettingFactory.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | using Zenvin.Settings.Loading; 3 | 4 | namespace Zenvin.Settings.Samples { 5 | public class DropdownSettingFactory : ISettingFactory { 6 | string ISettingFactory.GetDefaultValidType () { 7 | return "dropdown"; 8 | } 9 | 10 | SettingBase ISettingFactory.CreateSettingFromType (string defaultValue, StringValuePair[] values) { 11 | return DropdownSetting.CreateInstanceWithValues (int.TryParse (defaultValue, out int val) ? val : 0, values); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/DropdownSettingFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c9aea3f33dcd2e46b6fd4feac5f94c2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Settings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd90a101829dcad49b6c713a80e77624 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Settings/DropdownSetting.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | using Zenvin.Settings.Framework; 4 | 5 | namespace Zenvin.Settings.Samples { 6 | public class DropdownSetting : IntSetting { 7 | 8 | [SerializeField] private string[] options; 9 | 10 | public string[] Options => options; 11 | 12 | 13 | protected override void ProcessValue (ref int value) { 14 | value = Mathf.Clamp (value, 0, options.Length - 1); 15 | } 16 | 17 | protected override void OnCreateWithValues (StringValuePair[] values) { 18 | options = new string[values.Length]; 19 | for (int i = 0; i < values.Length; i++) { 20 | options[i] = values[i].Value; 21 | } 22 | } 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Settings/DropdownSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51447b6fb6a837c47abf7f6bfd2ad11d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Settings/SliderSetting.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | using UnityEngine; 3 | 4 | using Zenvin.Settings.Utility; 5 | 6 | namespace Zenvin.Settings.Samples { 7 | public class SliderSetting : FloatSetting { 8 | 9 | // slider settings 10 | [SerializeField] private float minValue = 0f; 11 | [SerializeField] private float maxValue = 1f; 12 | [SerializeField, Min (0f)] private float increment = 0.5f; 13 | 14 | public float MinValue => minValue; 15 | public float MaxValue => maxValue; 16 | public float Increment => increment; 17 | 18 | 19 | // make sure the value snaps to an increment 20 | protected override void ProcessValue (ref float value) { 21 | value = Mathf.Clamp (value, minValue, maxValue); 22 | } 23 | 24 | // try assigning slider settings 25 | protected override void OnCreateWithValues (StringValuePair[] values) { 26 | 27 | float? min = null; 28 | float? max = null; 29 | float? inc = null; 30 | 31 | foreach (var value in values) { 32 | 33 | if (min == null && value.Key.Equals ("minValue", System.StringComparison.OrdinalIgnoreCase)) { 34 | float.TryParse (value.Value, out float _min); 35 | min = _min; 36 | continue; 37 | } 38 | 39 | if (value.Key.Equals ("maxValue", System.StringComparison.OrdinalIgnoreCase)) { 40 | float.TryParse (value.Value, out float _max); 41 | max = _max; 42 | continue; 43 | } 44 | 45 | if (value.Key.Equals ("increment", System.StringComparison.OrdinalIgnoreCase)) { 46 | float.TryParse (value.Value, out float _inc); 47 | inc = Mathf.Max (0f, _inc); 48 | continue; 49 | } 50 | 51 | } 52 | 53 | min = min ?? 0f; 54 | max = max ?? 1f; 55 | inc = inc ?? 0f; 56 | 57 | minValue = min.Value; 58 | maxValue = max.Value; 59 | increment = inc.Value; 60 | 61 | AssignMinMax (ref minValue, ref maxValue); 62 | } 63 | 64 | private static void AssignMinMax (ref float min, ref float max) { 65 | if (min <= max) { 66 | return; 67 | } 68 | var cache = max; 69 | max = min; 70 | min = cache; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/Settings/SliderSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1abe613ed870bf6489aa19cbc8a5bc63 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/SettingsInitializer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Zenvin.Settings.Framework; 3 | using Zenvin.Settings.Loading; 4 | 5 | namespace Zenvin.Settings.Samples { 6 | [DisallowMultipleComponent] 7 | public class SettingsInitializer : MonoBehaviour { 8 | 9 | public enum InitMode { 10 | Awake, 11 | Start, 12 | } 13 | 14 | public enum DynamicLoading { 15 | Disabled, 16 | DuringInitialization, 17 | AfterInitialization, 18 | } 19 | 20 | 21 | [SerializeField] private InitMode mode = InitMode.Start; 22 | [SerializeField] private SettingsAsset settings; 23 | [SerializeField] private bool resetToDefaults = true; 24 | [Space, SerializeField] private DynamicLoading loadDynamicSettings = DynamicLoading.DuringInitialization; 25 | [SerializeField] private SettingsImportData dynamicSettings; 26 | [SerializeField, TextArea (25, 35), Space (20)] private string dynamicSettingsJsonOutput = ""; 27 | 28 | 29 | private void Awake () { 30 | if (mode == InitMode.Awake) { 31 | Init (); 32 | } 33 | } 34 | 35 | private void Start () { 36 | if (mode == InitMode.Start) { 37 | Init (); 38 | } 39 | 40 | if (loadDynamicSettings == DynamicLoading.AfterInitialization) { 41 | LoadSettings (settings); 42 | } 43 | } 44 | 45 | 46 | private void Init () { 47 | if (loadDynamicSettings == DynamicLoading.DuringInitialization) { 48 | SettingsAsset.OnInitialize += LoadSettings; 49 | } 50 | if (settings != null) { 51 | settings.Initialize (); 52 | if (resetToDefaults) { 53 | settings.ResetAllSettings (true); 54 | } 55 | } 56 | } 57 | 58 | private void LoadSettings (SettingsAsset asset) { 59 | if (dynamicSettingsJsonOutput == null || dynamicSettingsJsonOutput.Length == 0) { 60 | return; 61 | } 62 | 63 | var options = new SettingLoaderOptions (asset) 64 | .WithData (dynamicSettingsJsonOutput) 65 | .WithSettingFactory ("bool", new BoolSettingFactory ()) 66 | .WithSettingFactory ("int", new IntSettingFactory ()) 67 | .WithSettingFactory ("float", new FloatSettingFactory ()) 68 | .WithSettingFactory ("dropdown", new DropdownSettingFactory ()) 69 | .WithSettingFactory ("slider", new SliderSettingFactory ()) 70 | .WithComponentType ("conditional_visibility", typeof (ConditionalVisibility)); 71 | 72 | RuntimeSettingLoader.LoadSettingsIntoAsset (options); 73 | SettingsAsset.OnInitialize -= LoadSettings; 74 | } 75 | 76 | private void OnValidate () { 77 | dynamicSettingsJsonOutput = JsonUtility.ToJson (dynamicSettings, true); 78 | } 79 | 80 | } 81 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/SettingsInitializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c51ac20d3ea06d44fbcc8ca88588ecbc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/SettingsMenu.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.UI; 2 | using UnityEngine; 3 | 4 | using Zenvin.Settings.Framework; 5 | using Zenvin.Settings.Framework.Serialization; 6 | using System.IO; 7 | using TMPro; 8 | 9 | namespace Zenvin.Settings.Samples { 10 | public class SettingsMenu : MonoBehaviour { 11 | 12 | [SerializeField] private SettingsAsset asset; 13 | [SerializeField] private bool sortSettings = true; 14 | [SerializeField] private RectTransform settingHeaderPrefab; 15 | [SerializeField] private SettingControlCollection controlPrefabs; 16 | [SerializeField] private TabView tabView; 17 | 18 | private JsonSerializer serializer; 19 | 20 | 21 | private void Start () { 22 | if (asset == null) { 23 | return; 24 | } 25 | SpawnMenu (); 26 | 27 | serializer = new JsonFileSerializer (Path.Combine (Application.dataPath, "settings_test.json")); 28 | } 29 | 30 | private void SpawnMenu () { 31 | 32 | // get settings groups for tabs 33 | var tabGroups = asset.GetGroups (); 34 | 35 | foreach (var tg in tabGroups) { 36 | 37 | // spawn tab 38 | RectTransform tabTransform = tabView.AddTab (tg); 39 | 40 | // populate tab 41 | var tabSettings = tg.GetSettings (sortSettings); 42 | foreach (var setting in tabSettings) { 43 | SpawnPrefab (tabTransform, setting); 44 | } 45 | 46 | var contentGroups = tg.GetAllGroups (); 47 | foreach (var cg in contentGroups) { 48 | 49 | // spawn group header, if possible 50 | if (settingHeaderPrefab != null) { 51 | RectTransform header = Instantiate (settingHeaderPrefab); 52 | header.SetParent (tabTransform); 53 | header.localScale = Vector3.one; 54 | 55 | TextMeshProUGUI label = header.GetComponentInChildren (); 56 | if (label != null) { 57 | label.SetText (cg.Name); 58 | } 59 | } 60 | 61 | // spawn controls 62 | var settings = cg.GetAllSettings (sortSettings); 63 | foreach (var setting in settings) { 64 | SpawnPrefab (tabTransform, setting); 65 | } 66 | 67 | } 68 | 69 | } 70 | 71 | } 72 | 73 | private void SpawnPrefab (RectTransform parent, SettingBase setting) { 74 | // get prefab fitting the setting type. 75 | if (controlPrefabs.TryGetControl (setting.GetType (), out SettingControl ctrl)) { 76 | // spawn prefab, if it is spawnable for the current setting 77 | if (ctrl.TryInstantiateWith (setting, out SettingControl control)) { 78 | // setup instance 79 | control.transform.SetParent (parent); 80 | control.transform.localScale = Vector3.one; 81 | control.transform.localPosition = Vector3.zero; 82 | } else { 83 | Debug.Log ($"Can't spawn prefab for {setting.Name} ({setting.GetType ()})"); 84 | } 85 | } else { 86 | Debug.Log ($"No prefab found for {setting.Name} ({setting.GetType ()})."); 87 | } 88 | } 89 | 90 | 91 | // Button methods 92 | 93 | public void ApplyDirtySettings () { 94 | asset.ApplyDirtySettings (); 95 | } 96 | 97 | public void RevertDirtySettings () { 98 | asset.RevertDirtySettings (); 99 | } 100 | 101 | public void ResetAllSettings () { 102 | asset.ResetAllSettings (true); 103 | } 104 | 105 | public void Save () { 106 | asset.SerializeSettings (serializer); 107 | } 108 | 109 | public void Load () { 110 | asset.DeserializeSettings (serializer); 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/SettingsMenu.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d901fe074f0173e43bec7130474786ef 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/SliderSettingFactory.cs: -------------------------------------------------------------------------------- 1 | using Zenvin.Settings.Framework; 2 | using Zenvin.Settings.Loading; 3 | 4 | namespace Zenvin.Settings.Samples { 5 | public class SliderSettingFactory : ISettingFactory { 6 | string ISettingFactory.GetDefaultValidType () { 7 | return "slider"; 8 | } 9 | 10 | SettingBase ISettingFactory.CreateSettingFromType (string defaultValue, StringValuePair[] values) { 11 | return SliderSetting.CreateInstanceWithValues (float.TryParse (defaultValue, out float val) ? val : 0, values); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/SliderSettingFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7ef6de7a8a612c4c8b9662b07955efd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/TabButton.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using TMPro; 4 | using UnityEngine; 5 | using UnityEngine.UI; 6 | 7 | namespace Zenvin.Settings.Samples { 8 | public class TabButton : MonoBehaviour { 9 | 10 | private TabView view; 11 | private int index; 12 | 13 | [SerializeField] private Image image; 14 | [SerializeField] private TextMeshProUGUI text; 15 | 16 | 17 | public void Setup (TabView view, int index, string label) { 18 | this.view = view; 19 | this.index = index; 20 | 21 | text?.SetText (label); 22 | } 23 | 24 | public void OnClick () { 25 | view.SelectTab (index); 26 | } 27 | 28 | public void OnTabStateChanged (bool active) { 29 | image.enabled = active; 30 | } 31 | 32 | } 33 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/TabButton.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc6b9596268a9914f8de5f5548bf7f25 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/TabView.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections; 3 | using UnityEngine.UI; 4 | using UnityEngine; 5 | 6 | using Zenvin.Settings.Framework; 7 | 8 | namespace Zenvin.Settings.Samples { 9 | [DisallowMultipleComponent] 10 | public class TabView : MonoBehaviour { 11 | 12 | private readonly List tabs = new List (); 13 | private int activeTab = 0; 14 | 15 | [SerializeField] private LayoutGroup tabButtonParent; 16 | [SerializeField] private TabButton tabButtonPrefab; 17 | [Space, SerializeField] private RectTransform tabContentParent; 18 | [SerializeField] private RectTransform tabContentPrefab; 19 | 20 | 21 | public RectTransform AddTab (SettingsGroup group) { 22 | if (group == null) { 23 | return null; 24 | } 25 | 26 | TabButton button = Instantiate (tabButtonPrefab); 27 | button.Setup (this, tabs.Count, group.Name); 28 | button.transform.SetParent (tabButtonParent.transform); 29 | button.transform.localScale = Vector3.one; 30 | 31 | RectTransform content = Instantiate (tabContentPrefab); 32 | content.SetParent (tabContentParent); 33 | content.localScale = Vector3.one; 34 | 35 | LayoutRebuilder.MarkLayoutForRebuild (content); 36 | 37 | tabs.Add (new TabData () { Button = button, ContentParent = content, Group = group }); 38 | 39 | SelectTab (0); 40 | return content; 41 | } 42 | 43 | public void SelectTab (int index) { 44 | activeTab = index; 45 | for (int i = 0; i < tabs.Count; i++) { 46 | tabs[i].Button.OnTabStateChanged (i == index); 47 | tabs[i].ContentParent.gameObject.SetActive (i == index); 48 | } 49 | } 50 | 51 | 52 | public class TabData { 53 | public TabButton Button; 54 | public SettingsGroup Group; 55 | public RectTransform ContentParent; 56 | } 57 | 58 | } 59 | } -------------------------------------------------------------------------------- /Samples~/Settings Menu/Scripts/TabView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eeb4f24d1b53d904dbe02c81c91c0c88 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Settings Menu/Settings Menu Demo.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5109f5001ecc96b4ca742327c31c5397 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 805fe34cdc265494cb563505c6e3cd46 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dfdc7f0f6da5dc04e9d6030df8c15063 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Prefabs/Volume Control.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42c2f2de1fb15a045ab775fed6afa774 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 05a7ab18991186748a7567b44ad25f3b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Scripts/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7296073b49e61d7429d81e00d2d85483 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Scripts/Runtime/VolumeControlFMOD.cs: -------------------------------------------------------------------------------- 1 | using TMPro; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | using Zenvin.Settings.Framework; 5 | using Zenvin.Settings.UI; 6 | 7 | namespace Zenvin.Settings.Samples { 8 | [AddComponentMenu ("Zenvin/Settings/UI/FMOD Volume Control")] 9 | public class VolumeControlFMOD : SettingControl { 10 | 11 | [SerializeField] private TextMeshProUGUI label; 12 | [SerializeField] private Slider slider; 13 | [SerializeField] private TextMeshProUGUI valueLabel; 14 | 15 | 16 | protected override void OnSetup () { 17 | if (slider != null) { 18 | slider.minValue = 0f; 19 | slider.maxValue = 1f; 20 | slider.wholeNumbers = false; 21 | UpdateSlider (Setting.TargetValue); 22 | } 23 | 24 | if (label != null) { 25 | label.SetText (Setting.Name); 26 | } 27 | UpdateValueLabel (Setting.CachedValue * 100f); 28 | } 29 | 30 | protected override void OnSettingValueChanged (SettingBase.ValueChangeMode mode) { 31 | if (mode != SettingBase.ValueChangeMode.Set) { 32 | UpdateSlider (Setting.TargetValue); 33 | } 34 | UpdateValueLabel (Setting.CachedValue * 100f); 35 | } 36 | 37 | 38 | private void UpdateSlider (float sliderValue) { 39 | if (slider != null) { 40 | slider.SetValueWithoutNotify (sliderValue); 41 | } 42 | } 43 | 44 | private void UpdateValueLabel (float sliderValue) { 45 | if (valueLabel != null) { 46 | valueLabel.SetText (sliderValue.ToString ("000")); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Scripts/Runtime/VolumeControlFMOD.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5248b119bf562143807af344d9d08ce 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Scripts/Runtime/VolumeSettingFMOD.cs: -------------------------------------------------------------------------------- 1 | using FMOD; 2 | using FMOD.Studio; 3 | using FMODUnity; 4 | using UnityEngine; 5 | using Zenvin.Settings.Framework; 6 | using Debug = UnityEngine.Debug; 7 | 8 | namespace Zenvin.Settings.Samples { 9 | public class VolumeSettingFMOD : FloatSetting { 10 | 11 | public const float MinValue = 0f; 12 | public const float MaxValue = 1f; 13 | 14 | private Bus? targetBus; 15 | 16 | [SerializeField, Tooltip ("The name of the target bus. Must start with 'bus:/'"), BankRef] 17 | private string targetBusName = "evt:/"; 18 | [SerializeField, Tooltip ("Whether to apply the Setting's value to the AudioMixer any time the value is changed, or wait for the Setting's value to be applied.")] 19 | private bool changeOnSet = true; 20 | [SerializeField, Tooltip ("Will log an error to the console if no bus was found for the given name.")] 21 | private bool missingBusError = true; 22 | [SerializeField, Tooltip ("Will log an error to the console if setting the volume on the target bus failed.")] 23 | private bool setVolumeFailedError = true; 24 | 25 | 26 | public float TargetValue => changeOnSet ? CachedValue : CurrentValue; 27 | public Bus? TargetBus => targetBus; 28 | 29 | 30 | /// 31 | protected override void ProcessValue (ref float value) { 32 | value = Mathf.Clamp01 (value); 33 | } 34 | 35 | /// 36 | protected override void OnValueChanged (ValueChangeMode mode) { 37 | if (string.IsNullOrEmpty (targetBusName)) 38 | return; 39 | if (!TryGetBus ()) 40 | return; 41 | 42 | if (changeOnSet || mode == ValueChangeMode.Apply || mode == ValueChangeMode.Initialize || mode == ValueChangeMode.Deserialize) { 43 | var result = targetBus.Value.setVolume (TargetValue); 44 | if(setVolumeFailedError && result != RESULT.OK) 45 | Debug.LogError ($"Setting volume of bus '{targetBusName}' failed: {result}"); 46 | } 47 | } 48 | 49 | private bool TryGetBus () { 50 | if (targetBus.HasValue) 51 | return true; 52 | if (string.IsNullOrWhiteSpace (targetBusName)) 53 | return false; 54 | 55 | try { 56 | targetBus = RuntimeManager.GetBus (targetBusName); 57 | return true; 58 | } catch { 59 | if (missingBusError) 60 | Debug.LogError ($"[FMOD Volume Setting] Could not find FMOD Bus with name '{targetBusName}'.", this); 61 | 62 | return false; 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /Samples~/Volume Setting FMOD/Scripts/Runtime/VolumeSettingFMOD.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4ed81eedc06eac4eb96347e2d29b08a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Volume Setting.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4fc57d79b151164f8009d792ef3d2a5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e90f216de6db8b46ab0ce869d044c77 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Prefabs/Volume Control.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a08b9bc6894ad19409b6a0a4565d22ec 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a890fe08b2b3bb542b2c900bda064fac 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a03757a385047bf4d8cef5adb75accdd 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Editor/MixerVariablePropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEditor; 3 | using UnityEngine; 4 | using UnityEngine.Audio; 5 | 6 | namespace Zenvin.Settings.Samples { 7 | [CustomPropertyDrawer (typeof (MixerVariable))] 8 | public class MixerVariablePropertyDrawer : PropertyDrawer { 9 | 10 | private static readonly List paramNames = new List (); 11 | private SerializedObject mixerObject; 12 | 13 | 14 | public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { 15 | // Get serialized properties 16 | var mixerProp = property.FindPropertyRelative ("mixer"); 17 | var paramProp = property.FindPropertyRelative ("variable"); 18 | 19 | // Draw prefix label 20 | position.height = EditorGUIUtility.singleLineHeight; 21 | position = EditorGUI.PrefixLabel (position, label); 22 | 23 | // Calculate property field rects 24 | var mixerRect = new Rect (position); 25 | var paramRect = new Rect (position); 26 | paramRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 27 | 28 | // Draw property fields 29 | DrawMixer (mixerRect, mixerProp); 30 | DrawParam (paramRect, paramProp, mixerProp?.objectReferenceValue as AudioMixer); 31 | } 32 | 33 | private void DrawMixer (Rect position, SerializedProperty prop) { 34 | if (prop == null) { 35 | EditorGUI.LabelField (position, "Error: Mixer property not found."); 36 | return; 37 | } 38 | // Draw object field for mixer reference 39 | EditorGUI.PropertyField (position, prop, GUIContent.none); 40 | } 41 | 42 | private void DrawParam (Rect position, SerializedProperty prop, AudioMixer mixer) { 43 | if (prop == null || mixer == null) { 44 | GUI.enabled = false; 45 | EditorGUI.LabelField (position, "", EditorStyles.popup); 46 | GUI.enabled = true; 47 | return; 48 | } 49 | 50 | if (mixerObject == null || mixerObject.targetObject != mixer) { 51 | mixerObject = new SerializedObject (mixer); 52 | } 53 | 54 | // Find the serialized list of exposed parameters 55 | var paramsProp = mixerObject.FindProperty ("m_ExposedParameters"); 56 | if (paramsProp == null) { 57 | EditorGUI.LabelField (position, "Error: ExposedParameters property not found."); 58 | return; 59 | } 60 | 61 | if (GUI.Button (position, prop.stringValue, EditorStyles.popup)) { 62 | ShowParameterSelection (position, prop, paramsProp); 63 | } 64 | } 65 | 66 | public override float GetPropertyHeight (SerializedProperty property, GUIContent label) { 67 | return EditorGUIUtility.singleLineHeight * 2 + EditorGUIUtility.standardVerticalSpacing; 68 | } 69 | 70 | 71 | private void ShowParameterSelection (Rect position, SerializedProperty originalParamsProp, SerializedProperty paramsProp) { 72 | paramNames.Clear (); 73 | while (paramsProp.Next (true)) { 74 | if (paramsProp.depth == 2 && paramsProp.name == "name") { 75 | paramNames.Add (paramsProp.stringValue); 76 | } 77 | } 78 | 79 | var menu = new GenericMenu (); 80 | for (int i = 0; i < paramNames.Count - 1; i++) { 81 | var name = paramNames[i]; 82 | menu.AddItem (new GUIContent (name), false, SelectParameterName, (originalParamsProp, name)); 83 | } 84 | menu.DropDown (position); 85 | } 86 | 87 | private static void SelectParameterName (object obj) { 88 | var values = obj as (SerializedProperty prop, string value)?; 89 | if (!values.HasValue) { 90 | return; 91 | } 92 | if (values.Value.prop != null && values.Value.prop.propertyType == SerializedPropertyType.String) { 93 | values.Value.prop.stringValue = values.Value.value; 94 | values.Value.prop.serializedObject.ApplyModifiedProperties (); 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Editor/MixerVariablePropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5e6d839385e6c64aa74d73d5e54720d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4cfa518269e73e840af1a5b81a99b2bc 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Runtime/MixerVariable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.Audio; 4 | 5 | namespace Zenvin.Settings.Samples { 6 | /// 7 | /// Wrapper for an exposed parameter of an . 8 | /// 9 | [Serializable] 10 | public sealed class MixerVariable { 11 | [SerializeField] private AudioMixer mixer; 12 | [SerializeField] private string variable; 13 | 14 | 15 | public bool TryGetValue (out float value) { 16 | if (mixer == null || string.IsNullOrWhiteSpace (variable)) { 17 | value = 0f; 18 | return false; 19 | } 20 | return mixer.GetFloat (variable, out value); 21 | } 22 | 23 | public bool SetValue (float value) { 24 | if (mixer == null || string.IsNullOrWhiteSpace (variable)) { 25 | return false; 26 | } 27 | return mixer.SetFloat (variable, value); 28 | } 29 | 30 | 31 | public override string ToString () { 32 | return $"AudioMixer Target '{(mixer == null ? "" : mixer.name)}' -> '{variable}'"; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Runtime/MixerVariable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41d3c9ed88c28bb4c8946b6d35a6fd29 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Runtime/VolumeControl.cs: -------------------------------------------------------------------------------- 1 | using TMPro; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | using Zenvin.Settings.Framework; 5 | using Zenvin.Settings.UI; 6 | 7 | namespace Zenvin.Settings.Samples { 8 | [AddComponentMenu("Zenvin/Settings/UI/Volume Control")] 9 | public class VolumeControl : SettingControl { 10 | 11 | [SerializeField] private TextMeshProUGUI label; 12 | [SerializeField] private Slider slider; 13 | [SerializeField] private TextMeshProUGUI valueLabel; 14 | 15 | 16 | protected override void OnSetup () { 17 | if (slider != null) { 18 | slider.minValue = 0f; 19 | slider.maxValue = 1f; 20 | slider.wholeNumbers = false; 21 | UpdateSlider (Setting.TargetValue); 22 | } 23 | 24 | if (label != null) { 25 | label.SetText (Setting.Name); 26 | } 27 | UpdateValueLabel (Setting.CachedValue * 100f); 28 | } 29 | 30 | protected override void OnSettingValueChanged (SettingBase.ValueChangeMode mode) { 31 | if (mode != SettingBase.ValueChangeMode.Set) { 32 | UpdateSlider (Setting.TargetValue); 33 | } 34 | UpdateValueLabel (Setting.CachedValue * 100f); 35 | } 36 | 37 | 38 | private void UpdateSlider (float sliderValue) { 39 | if (slider != null) { 40 | slider.SetValueWithoutNotify (sliderValue); 41 | } 42 | } 43 | 44 | private void UpdateValueLabel (float sliderValue) { 45 | if (valueLabel != null) { 46 | valueLabel.SetText (sliderValue.ToString ("000")); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Runtime/VolumeControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43ce2bb806801164b910b8d4b2c3cb98 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Runtime/VolumeSetting.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Zenvin.Settings.Framework; 3 | 4 | namespace Zenvin.Settings.Samples { 5 | public class VolumeSetting : FloatSetting { 6 | 7 | public const float LogMinValue = -80f; 8 | public const float LogMaxValue = 20f; 9 | public const float LinMinValue = 0.0001f; 10 | public const float LinMaxValue = 1f; 11 | 12 | 13 | [SerializeField] private MixerVariable target = new MixerVariable (); 14 | [SerializeField, Tooltip ("Whether to apply the Setting's value to the AudioMixer any time the value is changed, or wait for the Setting's value to be applied.")] 15 | private bool changeOnSet = true; 16 | 17 | 18 | public float TargetValue => changeOnSet ? CachedValue : CurrentValue; 19 | 20 | 21 | /// 22 | protected override void ProcessValue (ref float value) { 23 | value = Mathf.Clamp01 (value); 24 | } 25 | 26 | /// 27 | protected override void OnValueChanged (ValueChangeMode mode) { 28 | if (changeOnSet || mode == ValueChangeMode.Apply || mode == ValueChangeMode.Initialize || mode == ValueChangeMode.Deserialize) { 29 | var value = ValueToVolume(TargetValue); 30 | target.SetValue (value); 31 | } 32 | } 33 | 34 | 35 | private static float VolumeToValue (float dB) { 36 | // a = 10 ^ (b / 20) 37 | // where { -80 <= b <= 20 } 38 | dB = Mathf.Clamp (dB, LogMinValue, LogMaxValue); 39 | return Mathf.Pow (10f, dB / 20f); 40 | } 41 | 42 | private static float ValueToVolume (float value) { 43 | var rangeValue = Mathf.Lerp (LinMinValue, LinMaxValue, value); 44 | // b = log10(a) * 20 45 | // where { 0.0001 <= a <= 1 } 46 | var volume = Mathf.Log10 (rangeValue) * 20f; 47 | return volume; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Samples~/Volume Setting/Scripts/Runtime/VolumeSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3868acfd6cefd1940a6e383b760b0fd6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.zenvin.settings-framework", 3 | "version": "3.0.1", 4 | "displayName": "Settings Framework", 5 | "description": "Made to allow for simple implementation of arbitrarily typed game settings.", 6 | "unity": "2020.1", 7 | "author": { 8 | "name": "Zenvin", 9 | "email": "zenvin@outlook.de" 10 | }, 11 | "dependencies": { 12 | "com.unity.nuget.newtonsoft-json": "2.0.0" 13 | }, 14 | "hideInEditor": false, 15 | "keywords": [ 16 | "settings" 17 | ], 18 | "license": "LICENSE.md", 19 | "samples": [ 20 | { 21 | "displayName": "Settings Menu", 22 | "description": "A complete demonstration of how a settings menu could be set up with this package.", 23 | "path": "Samples~/Settings Menu" 24 | }, 25 | { 26 | "displayName": "Localization Setting", 27 | "description": "An implementation of a dropdown setting, specifically for changing the localization of the game.\nREQUIRES UNITY'S LOCALIZATION PACKAGE!", 28 | "path": "Samples~/Localization Setting" 29 | }, 30 | { 31 | "displayName": "Volume Setting", 32 | "description": "An implementation of a Slider for changing volumes. \nIncludes property drawer for picking an exposed AudioMixer parameter and takes logarithmic scaling into account when setting values.", 33 | "path": "Samples~/Volume Setting" 34 | }, 35 | { 36 | "displayName": "Volume Setting FMOD", 37 | "description": "An implementation of a Slider for changing volumes in FMOD projects. \nREQUIRES THE FMOD ASSET TO BE PRESENT IN THE PROJECT. \nLearn more: \nhttps://fmod.com/unity \nhttps://assetstore.unity.com/packages/tools/audio/fmod-for-unity-161631", 38 | "path": "Samples~/Volume Setting FMOD" 39 | }, 40 | { 41 | "displayName": "Keybind Setting", 42 | "description": "An implementation of a Setting for remapping a key binding. \nREQUIRES THE PROJECT TO BE USING THE NEW INPUT SYSTEM. \nLearn more: \nhttps://docs.unity3d.com/Packages/com.unity.inputsystem@1.10/manual/index.html", 43 | "path": "Samples~/Keybind Setting" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ec9654c1d15c9644aa01f0d47d84b75 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------