diff --git a/Assets/AddressableAssetsData/AddressableAssetSettings.asset b/Assets/AddressableAssetsData/AddressableAssetSettings.asset index ed913a8e..d803318b 100644 --- a/Assets/AddressableAssetsData/AddressableAssetSettings.asset +++ b/Assets/AddressableAssetsData/AddressableAssetSettings.asset @@ -15,7 +15,7 @@ MonoBehaviour: m_DefaultGroup: 6f3207429a65b3e4b83935ac19791077 m_currentHash: serializedVersion: 2 - Hash: 785995fbc50aef9057b52982d915e9e3 + Hash: 9754c7f6c4b6446b0110799319d5bcb8 m_OptimizeCatalogSize: 0 m_BuildRemoteCatalog: 0 m_CatalogRequestsTimeout: 0 diff --git a/Assets/AddressableAssetsData/AssetGroups/Settings.asset b/Assets/AddressableAssetsData/AssetGroups/Settings.asset index 97d7a5e4..06f456b8 100644 --- a/Assets/AddressableAssetsData/AssetGroups/Settings.asset +++ b/Assets/AddressableAssetsData/AssetGroups/Settings.asset @@ -25,6 +25,11 @@ MonoBehaviour: m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: 44f8b357e56ef9d4784ec1b1df1a13a8 + m_Address: Settings/Developer/DebugSettings + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 - m_GUID: 8f5195fb013895049a19488fd4d8f2a1 m_Address: Settings/InteractionSettings m_ReadOnly: 0 diff --git a/Assets/Editor/DeveloperSettingsEditorWindow.cs b/Assets/Editor/DeveloperSettingsEditorWindow.cs index 85935172..96339675 100644 --- a/Assets/Editor/DeveloperSettingsEditorWindow.cs +++ b/Assets/Editor/DeveloperSettingsEditorWindow.cs @@ -10,7 +10,7 @@ namespace AppleHills.Core.Settings.Editor { private Vector2 scrollPosition; private List allDeveloperSettings = new List(); - private string[] tabNames = new string[] { "Diving", "Other Systems" }; // Add more tabs as needed + private string[] tabNames = new string[] { "Diving", "Debug", "Other Systems" }; // Added Debug tab private int selectedTab = 0; private Dictionary serializedSettingsObjects = new Dictionary(); private GUIStyle headerStyle; @@ -46,6 +46,7 @@ namespace AppleHills.Core.Settings.Editor // If any settings are missing, create them CreateSettingsIfMissing("DivingDeveloperSettings"); + CreateSettingsIfMissing("DebugSettings"); // Add more developer settings types here as needed // CreateSettingsIfMissing("OtherDeveloperSettings"); @@ -114,7 +115,10 @@ namespace AppleHills.Core.Settings.Editor case 0: // Diving DrawSettingsEditor(); break; - case 1: // Other Systems + case 1: // Debug + DrawSettingsEditor(); + break; + case 2: // Other Systems EditorGUILayout.HelpBox("Other developer settings will appear here as they are added.", MessageType.Info); break; // Add additional cases as more developer settings types are added diff --git a/Assets/Scenes/Levels/AppleHillsOverworld.unity b/Assets/Scenes/Levels/AppleHillsOverworld.unity index 87b41e6f..52047450 100644 --- a/Assets/Scenes/Levels/AppleHillsOverworld.unity +++ b/Assets/Scenes/Levels/AppleHillsOverworld.unity @@ -529,6 +529,50 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 539b408cd1191614abdcd99506f1157d, type: 3} +--- !u!1 &327210514 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 327210516} + - component: {fileID: 327210515} + m_Layer: 0 + m_Name: TEST_DEBUG + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &327210515 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 327210514} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 95aaca445e0285645819c42cd00a4868, type: 3} + m_Name: + m_EditorClassIdentifier: '::' +--- !u!4 &327210516 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 327210514} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4.15698, y: 1.79286, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1001 &368640488 PrefabInstance: m_ObjectHideFlags: 0 @@ -3033,3 +3077,4 @@ SceneRoots: - {fileID: 1668240411} - {fileID: 1443361597} - {fileID: 1238302921} + - {fileID: 327210516} diff --git a/Assets/Scripts/Core/Settings/Developer.meta b/Assets/Scripts/Core/Settings/Developer.meta new file mode 100644 index 00000000..bf41ca17 --- /dev/null +++ b/Assets/Scripts/Core/Settings/Developer.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5974bd02c2114bcbbbbb1b8d8f91da3c +timeCreated: 1760102254 \ No newline at end of file diff --git a/Assets/Scripts/Core/Settings/BaseDeveloperSettings.cs b/Assets/Scripts/Core/Settings/Developer/BaseDeveloperSettings.cs similarity index 100% rename from Assets/Scripts/Core/Settings/BaseDeveloperSettings.cs rename to Assets/Scripts/Core/Settings/Developer/BaseDeveloperSettings.cs diff --git a/Assets/Scripts/Core/Settings/BaseDeveloperSettings.cs.meta b/Assets/Scripts/Core/Settings/Developer/BaseDeveloperSettings.cs.meta similarity index 100% rename from Assets/Scripts/Core/Settings/BaseDeveloperSettings.cs.meta rename to Assets/Scripts/Core/Settings/Developer/BaseDeveloperSettings.cs.meta diff --git a/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs new file mode 100644 index 00000000..f0dfffb5 --- /dev/null +++ b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs @@ -0,0 +1,62 @@ +using UnityEngine; + +namespace AppleHills.Core.Settings +{ + /// + /// Enum defining log verbosity levels + /// + public enum LogVerbosity + { + None = 0, + Errors = 1, + Warnings = 2, + Info = 3, + Verbose = 4 + } + + /// + /// Developer settings for debugging features and options. + /// These settings are meant to be used during development and testing. + /// + [CreateAssetMenu(fileName = "DebugSettings", menuName = "AppleHills/Developer Settings/Debug", order = 2)] + public class DebugSettings : BaseDeveloperSettings + { + [Header("Visualization")] + [Tooltip("Show colliders for game objects")] + [SerializeField] private bool showColliders = false; + + [Tooltip("Show performance statistics (FPS, memory usage, etc.)")] + [SerializeField] private bool showPerformanceStats = false; + + [Header("Logging")] + [Tooltip("Level of detail for logging")] + [SerializeField] private LogVerbosity logLevel = LogVerbosity.Warnings; + + [Header("Gameplay")] + [Tooltip("Make player invulnerable and ignore gameplay restrictions")] + [SerializeField] private bool godMode = false; + + [Tooltip("Global time scale for debugging animations and effects")] + [Range(0.1f, 10f)] + [SerializeField] private float timeScale = 1.0f; + + // Property getters + public bool ShowColliders => showColliders; + public bool ShowPerformanceStats => showPerformanceStats; + public LogVerbosity LogLevel => logLevel; + public bool GodMode => godMode; + public float TimeScale => timeScale; + + public override void OnValidate() + { + base.OnValidate(); + + // Apply any immediate effects when values change in the editor + if (Application.isPlaying) + { + // Set time scale directly when changed in editor + Time.timeScale = timeScale; + } + } + } +} diff --git a/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs.meta b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs.meta new file mode 100644 index 00000000..5ae3b2e0 --- /dev/null +++ b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d9fd485d4ab84bea9946425e742ccd9c +timeCreated: 1760102133 \ No newline at end of file diff --git a/Assets/Scripts/Core/Settings/DeveloperSettingsProvider.cs b/Assets/Scripts/Core/Settings/Developer/DeveloperSettingsProvider.cs similarity index 100% rename from Assets/Scripts/Core/Settings/DeveloperSettingsProvider.cs rename to Assets/Scripts/Core/Settings/Developer/DeveloperSettingsProvider.cs diff --git a/Assets/Scripts/Core/Settings/DeveloperSettingsProvider.cs.meta b/Assets/Scripts/Core/Settings/Developer/DeveloperSettingsProvider.cs.meta similarity index 100% rename from Assets/Scripts/Core/Settings/DeveloperSettingsProvider.cs.meta rename to Assets/Scripts/Core/Settings/Developer/DeveloperSettingsProvider.cs.meta diff --git a/Assets/Scripts/Core/Settings/DivingDeveloperSettings.cs b/Assets/Scripts/Core/Settings/Developer/DivingDeveloperSettings.cs similarity index 100% rename from Assets/Scripts/Core/Settings/DivingDeveloperSettings.cs rename to Assets/Scripts/Core/Settings/Developer/DivingDeveloperSettings.cs diff --git a/Assets/Scripts/Core/Settings/DivingDeveloperSettings.cs.meta b/Assets/Scripts/Core/Settings/Developer/DivingDeveloperSettings.cs.meta similarity index 100% rename from Assets/Scripts/Core/Settings/DivingDeveloperSettings.cs.meta rename to Assets/Scripts/Core/Settings/Developer/DivingDeveloperSettings.cs.meta diff --git a/Assets/Scripts/Data/CardSystem/CardDefinition.cs b/Assets/Scripts/Data/CardSystem/CardDefinition.cs index 0fa7902d..318579df 100644 --- a/Assets/Scripts/Data/CardSystem/CardDefinition.cs +++ b/Assets/Scripts/Data/CardSystem/CardDefinition.cs @@ -7,7 +7,7 @@ namespace AppleHills.Data.CardSystem /// Scriptable object defining a collectible card's properties. /// Used as a template for generating CardData instances. /// - [CreateAssetMenu(fileName = "New Card", menuName = "Apple Hills/Card System/Card Definition")] + [CreateAssetMenu(fileName = "New Card", menuName = "AppleHills/Card System/Card Definition")] public class CardDefinition : ScriptableObject { [Header("Identification")] diff --git a/Assets/Scripts/Data/CardSystem/CardVisualConfig.cs b/Assets/Scripts/Data/CardSystem/CardVisualConfig.cs index 9d1488f0..85e1197e 100644 --- a/Assets/Scripts/Data/CardSystem/CardVisualConfig.cs +++ b/Assets/Scripts/Data/CardSystem/CardVisualConfig.cs @@ -8,7 +8,7 @@ namespace AppleHills.Data.CardSystem /// ScriptableObject containing visual configuration for card display /// Maps card rarities to colors and zones to colors/shapes /// - [CreateAssetMenu(fileName = "CardVisualConfig", menuName = "Apple Hills/Card System/Visual Config")] + [CreateAssetMenu(fileName = "CardVisualConfig", menuName = "AppleHills/Card System/Visual Config")] public class CardVisualConfig : ScriptableObject { [Serializable] diff --git a/Assets/Scripts/Dialogue/DialogueComponent.cs b/Assets/Scripts/Dialogue/DialogueComponent.cs index be3a2ee1..0e18a733 100644 --- a/Assets/Scripts/Dialogue/DialogueComponent.cs +++ b/Assets/Scripts/Dialogue/DialogueComponent.cs @@ -8,7 +8,7 @@ using PuzzleS; namespace Dialogue { - [AddComponentMenu("Apple Hills/Dialogue/Dialogue Component")] + [AddComponentMenu("AppleHills/Dialogue/Dialogue Component")] public class DialogueComponent : MonoBehaviour { [SerializeField] private RuntimeDialogueGraph dialogueGraph; diff --git a/Assets/Scripts/Dialogue/SpeechBubble.cs b/Assets/Scripts/Dialogue/SpeechBubble.cs index c86878bc..47cf5c3a 100644 --- a/Assets/Scripts/Dialogue/SpeechBubble.cs +++ b/Assets/Scripts/Dialogue/SpeechBubble.cs @@ -15,7 +15,7 @@ namespace Dialogue Typewriter // Display text one character at a time } - [AddComponentMenu("Apple Hills/Dialogue/Speech Bubble")] + [AddComponentMenu("AppleHills/Dialogue/Speech Bubble")] public class SpeechBubble : MonoBehaviour { [SerializeField] private TextMeshProUGUI textDisplay; diff --git a/Assets/Scripts/Interactions/PickupItemData.cs b/Assets/Scripts/Interactions/PickupItemData.cs index 34931817..5665e3ae 100644 --- a/Assets/Scripts/Interactions/PickupItemData.cs +++ b/Assets/Scripts/Interactions/PickupItemData.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System; -[CreateAssetMenu(fileName = "PickupItemData", menuName = "Game/Pickup Item Data")] +[CreateAssetMenu(fileName = "PickupItemData", menuName = "AppleHills/Items + Puzzles/Pickup Item Data")] public class PickupItemData : ScriptableObject { [SerializeField] private string _itemId; diff --git a/Assets/Scripts/LevelS/LevelSwitchData.cs b/Assets/Scripts/LevelS/LevelSwitchData.cs index 14a759f7..f709e5e3 100644 --- a/Assets/Scripts/LevelS/LevelSwitchData.cs +++ b/Assets/Scripts/LevelS/LevelSwitchData.cs @@ -3,7 +3,7 @@ /// /// ScriptableObject holding data for a level switch (scene name, description, icon). /// -[CreateAssetMenu(fileName = "LevelSwitchData", menuName = "Game/Level Switch Data")] +[CreateAssetMenu(fileName = "LevelSwitchData", menuName = "AppleHills/Items & Puzzles/Level Switch Data")] public class LevelSwitchData : ScriptableObject { /// diff --git a/Assets/Scripts/PuzzleS/PuzzleStepSO.cs b/Assets/Scripts/PuzzleS/PuzzleStepSO.cs index 65968105..b0844507 100644 --- a/Assets/Scripts/PuzzleS/PuzzleStepSO.cs +++ b/Assets/Scripts/PuzzleS/PuzzleStepSO.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; /// /// ScriptableObject representing a single puzzle step, its display info, and which steps it unlocks. /// -[CreateAssetMenu(fileName = "PuzzleStepSO", menuName = "Puzzle/Step")] +[CreateAssetMenu(fileName = "PuzzleStepSO", menuName = "AppleHills/Items & Puzzles/Step")] public class PuzzleStepSO : ScriptableObject { /// diff --git a/Assets/Scripts/Settings/SceneOrientationConfig.cs b/Assets/Scripts/Settings/SceneOrientationConfig.cs index e1bb2fc5..fe92171c 100644 --- a/Assets/Scripts/Settings/SceneOrientationConfig.cs +++ b/Assets/Scripts/Settings/SceneOrientationConfig.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Settings { - [CreateAssetMenu(fileName = "SceneOrientationConfig", menuName = "Settings/Scene Orientation Config")] + [CreateAssetMenu(fileName = "SceneOrientationConfig", menuName = "AppleHills/Settings/Scene Orientation Config")] public class SceneOrientationConfig : ScriptableObject { [System.Serializable] diff --git a/Assets/Settings/Developer/DebugSettings.asset b/Assets/Settings/Developer/DebugSettings.asset new file mode 100644 index 00000000..38822d61 --- /dev/null +++ b/Assets/Settings/Developer/DebugSettings.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d9fd485d4ab84bea9946425e742ccd9c, type: 3} + m_Name: DebugSettings + m_EditorClassIdentifier: AppleHillsScripts::AppleHills.Core.Settings.DebugSettings + showColliders: 0 + showPerformanceStats: 0 + logLevel: 2 + godMode: 0 + timeScale: 7.09 diff --git a/Assets/Settings/Developer/DebugSettings.asset.meta b/Assets/Settings/Developer/DebugSettings.asset.meta new file mode 100644 index 00000000..8ddd2e5d --- /dev/null +++ b/Assets/Settings/Developer/DebugSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44f8b357e56ef9d4784ec1b1df1a13a8 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/docs/media/addressables_configuration.png b/docs/media/addressables_configuration.png new file mode 100644 index 00000000..5c3a32a6 Binary files /dev/null and b/docs/media/addressables_configuration.png differ diff --git a/docs/media/create_settings_asset.png b/docs/media/create_settings_asset.png new file mode 100644 index 00000000..0c6a53cf Binary files /dev/null and b/docs/media/create_settings_asset.png differ diff --git a/docs/media/developer_settings_editor.png b/docs/media/developer_settings_editor.png new file mode 100644 index 00000000..0204a822 Binary files /dev/null and b/docs/media/developer_settings_editor.png differ diff --git a/docs/media/game_settings_editor.png b/docs/media/game_settings_editor.png new file mode 100644 index 00000000..53bca347 Binary files /dev/null and b/docs/media/game_settings_editor.png differ diff --git a/docs/media/settings_class_hierarchy.png b/docs/media/settings_class_hierarchy.png new file mode 100644 index 00000000..c33fa661 Binary files /dev/null and b/docs/media/settings_class_hierarchy.png differ diff --git a/docs/media/settings_system_overview.png b/docs/media/settings_system_overview.png new file mode 100644 index 00000000..b2f60f7a Binary files /dev/null and b/docs/media/settings_system_overview.png differ diff --git a/docs/settings_readme.md b/docs/settings_readme.md new file mode 100644 index 00000000..a89a74eb --- /dev/null +++ b/docs/settings_readme.md @@ -0,0 +1,398 @@ +# Apple Hills Settings System + +![Settings System Overview](media/settings_system_overview.png) + +## Overview + +The Apple Hills settings system consists of two main categories: +- **Game Settings**: Designed for gameplay parameters and configuration values that affect the player experience +- **Developer Settings**: Technical settings used for development, debugging, and behind-the-scenes functionality that we don't want Angry Argentinians to accidentaly overwrite + +The settings framework uses ScriptableObjects to store configuration data, making it easy to modify values in the editor and reference them in code. Settings are organized into logical groups and can be accessed through custom editor windows or directly in code. + +Benefits of this approach include: +- Central location for all configuration values +- Type-safe access to settings in code +- Custom inspector support for better editing experience +- Settings validation through the OnValidate method +- Support for both runtime and development-time settings + +## Quick Start + +### How to Access and Edit Settings in Editor + +#### Game Settings +1. Open the Game Settings Editor window through the menu: **AppleHills → Game Settings Editor** +2. Navigate through the tabs to find the settings group you want to edit +3. Modify values directly in the inspector +4. Click "Save All" to apply changes + +![Game Settings Editor](media/game_settings_editor.png) + +#### Developer Settings +1. Open the Developer Settings Editor window through the menu: **AppleHills → Developer Settings Editor** +2. Select the appropriate tab (Diving, Debug, etc.) +3. Modify values directly in the inspector +4. Click "Save All" to apply changes + +![Developer Settings Editor](media/developer_settings_editor.png) + +### How to Access Settings from Code + +#### Game Settings + +```csharp +// Get player follower settings +var playerSettings = SettingsProvider.Instance.GetSettings(); +float moveSpeed = playerSettings.MoveSpeed; + +// Get interaction settings +var interactionSettings = SettingsProvider.Instance.GetSettings(); +float stopDistance = interactionSettings.PlayerStopDistance; +``` + +#### Developer Settings + +```csharp +// Get diving developer settings +var divingDevSettings = DeveloperSettingsProvider.Instance.GetSettings(); +bool useObjectPooling = divingDevSettings.BubbleUseObjectPooling; + +// Get debug settings +var debugSettings = DeveloperSettingsProvider.Instance.GetSettings(); +if (debugSettings.GodMode) { + // Apply god mode functionality +} +``` + +### Creating Your Own Settings + +#### 1. Create the Settings Class + +```csharp +// For gameplay settings +[CreateAssetMenu(fileName = "MyGameplaySettings", menuName = "AppleHills/Settings/My Gameplay Settings", order = 1)] +public class MyGameplaySettings : BaseSettings +{ + [Header("Movement")] + [Tooltip("Base movement speed")] + [SerializeField] private float baseSpeed = 5f; + + public float BaseSpeed => baseSpeed; + + public override void OnValidate() + { + // Validation logic here + } +} + +// For developer settings +[CreateAssetMenu(fileName = "MyDeveloperSettings", menuName = "AppleHills/Developer Settings/My Feature", order = 3)] +public class MyDeveloperSettings : BaseDeveloperSettings +{ + [Header("Configuration")] + [Tooltip("Enable advanced features")] + [SerializeField] private bool enableAdvancedFeatures = false; + + public bool EnableAdvancedFeatures => enableAdvancedFeatures; +} +``` + +#### 2. Create the Settings Asset +- Right-click in the Project window +- Select Create → AppleHills → Settings → My Gameplay Settings (or Developer Settings → My Feature) +- Save the asset in the appropriate location (Assets/Settings or Assets/Settings/Developer) + +![Create Settings Asset](media/create_settings_asset.png) + +#### 3. Register in the Editor Window (for custom tabs) +See the detailed workflow section for a complete guide. + +## Architecture Breakdown + +The settings system consists of several key components: + +### Base Classes + +- **BaseSettings**: The root class for all game settings ScriptableObjects +- **BaseDeveloperSettings**: The root class for all developer settings ScriptableObjects + +![Settings Class Hierarchy](media/settings_class_hierarchy.png) + +### Provider Classes + +- **SettingsProvider**: Singleton for accessing game settings +- **DeveloperSettingsProvider**: Singleton for accessing developer settings + +Both providers handle loading settings from Addressables or Resources, caching them for efficient access, and providing type-safe retrieval methods. + +### Editor Windows + +- **GameSettingsEditorWindow**: Custom editor window for editing game settings +- **DeveloperSettingsEditorWindow**: Custom editor window for editing developer settings + +These windows provide a clean interface for browsing and modifying settings, organized into tabs by category. + +### Settings Storage + +Settings assets are stored in: +- **Assets/Settings**: For game settings +- **Assets/Settings/Developer**: For developer settings + +These assets are loaded via Addressables during runtime, with a fallback to Resources if needed. + +## Detailed Workflows + +### Creating a New Settings Class + +1. **Determine the Type of Settings** + - Game settings: Inherit from `BaseSettings` + - Developer settings: Inherit from `BaseDeveloperSettings` + +2. **Create the Class File** + - Create a new script in the `Assets/Scripts/Core/Settings` folder + - Name it appropriately, e.g., `MyFeatureSettings.cs` or `MyFeatureDeveloperSettings.cs` + +3. **Implement the Settings Class** + +Here's an example of how to implement a settings class with proper structure: + +```csharp +using UnityEngine; +using AppleHills.Core.Settings; + +namespace AppleHills.Core.Settings +{ + [CreateAssetMenu(fileName = "MyFeatureSettings", menuName = "AppleHills/Settings/My Feature", order = 1)] + public class MyFeatureSettings : BaseSettings + { + [Header("Main Configuration")] + [Tooltip("Description of this setting")] + [SerializeField] private float mainValue = 10f; + + [Tooltip("Another important setting")] + [Range(0, 100)] + [SerializeField] private int secondaryValue = 50; + + [Header("Advanced Settings")] + [Tooltip("Enable special features")] + [SerializeField] private bool enableSpecialFeatures = false; + + // Public property accessors (follow this pattern) + public float MainValue => mainValue; + public int SecondaryValue => secondaryValue; + public bool EnableSpecialFeatures => enableSpecialFeatures; + + // Optional validation + public override void OnValidate() + { + // Ensure values are within acceptable ranges + mainValue = Mathf.Max(0, mainValue); + } + } +} +``` + +The key elements to include are: +- Proper attribute decorations (`Header`, `Tooltip`, `Range`, etc.) +- Serialized private fields with default values +- Public property accessors using the expression-bodied syntax +- Validation in the OnValidate method when needed + +### Creating Settings Assets + +1. **Create the Asset** + - Right-click in the Project window + - Navigate to Create → AppleHills → Settings → My Feature (or Developer Settings → My Feature) + - A new settings asset will be created + +2. **Configure the Asset** + - Set the default values for your settings + - Organize the asset in the correct folder: + - Game settings: `Assets/Settings/` + - Developer settings: `Assets/Settings/Developer/` + +3. **Add to Addressables** + - Open the Addressables Groups window (Window → Asset Management → Addressables → Groups) + - Drag your settings asset to the Settings group + - For game settings, ensure the addressable address is `Settings/YourSettingsClassName` + - For developer settings, ensure the addressable address is `Settings/Developer/YourSettingsClassName` + +![Addressables Configuration](media/addressables_configuration.png) + +### Adding to the Settings Editor Window + +For game settings: + +1. Open the `GameSettingsEditorWindow.cs` file in `Assets/Editor` +2. Update the tab names array to include your new settings category +3. Add a case to the switch statement in the `OnGUI` method to draw your settings +4. Add your settings type to the `LoadAllSettings` method's `CreateSettingsIfMissing` calls + +Here's an example of the code changes needed: + +```csharp +// 1. Update tab names array +private string[] tabNames = new string[] { "Player", "Interaction", "My Feature" }; // Add your tab + +// 2. Add to switch statement in OnGUI +switch (selectedTab) +{ + case 0: // Player + DrawSettingsEditor(); + break; + case 1: // Interaction + DrawSettingsEditor(); + break; + case 2: // My Feature + DrawSettingsEditor(); // Add your case + break; +} + +// 3. Add to LoadAllSettings method +private void LoadAllSettings() +{ + // ... existing code ... + + // Add your settings type + CreateSettingsIfMissing("MyFeatureSettings"); +} +``` + +For developer settings: + +1. Open the `DeveloperSettingsEditorWindow.cs` file in `Assets/Editor` +2. Update the tab names array to include your new settings category +3. Add a case to the switch statement in the `OnGUI` method to draw your settings +4. Add your settings type to the `LoadAllSettings` method's `CreateSettingsIfMissing` calls + +As seen in your current implementation for the Debug tab: + +```csharp +// 1. Tab names include the Debug category +private string[] tabNames = new string[] { "Diving", "Debug", "Other Systems" }; + +// 2. Switch statement handles the Debug tab +switch (selectedTab) +{ + case 0: // Diving + DrawSettingsEditor(); + break; + case 1: // Debug + DrawSettingsEditor(); + break; + case 2: // Other Systems + // ... existing code ... + break; +} + +// 3. LoadAllSettings includes DebugSettings +private void LoadAllSettings() +{ + // ... existing code ... + CreateSettingsIfMissing("DivingDeveloperSettings"); + CreateSettingsIfMissing("DebugSettings"); +} +``` + +### Using Settings in Game Code + +1. **Access game settings**: + +```csharp +public class MyGameplaySystem : MonoBehaviour +{ + private MyFeatureSettings settings; + + private void Awake() + { + // Get settings from provider + settings = SettingsProvider.Instance.GetSettings(); + + if (settings == null) + { + Debug.LogError("Failed to load MyFeatureSettings!"); + return; + } + + // Use the settings + float value = settings.MainValue; + bool specialEnabled = settings.EnableSpecialFeatures; + + // Configure components based on settings + // ... + } +} +``` + +2. **Access developer settings**: + +```csharp +public class MyDevelopmentTool : MonoBehaviour +{ + private MyFeatureDeveloperSettings devSettings; + + private void Awake() + { + // Get developer settings + devSettings = DeveloperSettingsProvider.Instance.GetSettings(); + + if (devSettings == null) + { + Debug.LogError("Failed to load MyFeatureDeveloperSettings!"); + return; + } + + // Use the settings + bool advancedEnabled = devSettings.EnableAdvancedFeatures; + + // Configure development tools based on settings + // ... + } +} +``` + +### Best Practices + +1. **Organization** + - Group related settings into a single settings class + - Use `[Header]` attributes to create logical sections + - Use `[Tooltip]` attributes to document settings + +2. **Validation** + - Implement `OnValidate()` to ensure values are within acceptable ranges + - Consider dependencies between settings + +3. **Naming** + - Use descriptive names for settings properties + - Follow a consistent naming pattern + +4. **Performance** + - Cache settings references rather than calling `GetSettings()` repeatedly + - Only access settings when needed + +5. **Defaults** + - Provide sensible default values for all settings + - Document the expected ranges for numeric values + +## Required Screenshots + +To complete this documentation, you'll need to take the following screenshots: + +1. **settings_system_overview.png** + - Screenshot of both settings editor windows side by side to show the full system + +2. **game_settings_editor.png** + - Screenshot of the Game Settings Editor window with the PlayerFollowerSettings tab selected + +3. **developer_settings_editor.png** + - Screenshot of the Developer Settings Editor window with the Debug tab selected + +4. **create_settings_asset.png** + - Screenshot of the right-click Create menu showing the AppleHills/Settings and AppleHills/Developer Settings options + +5. **settings_class_hierarchy.png** + - Screenshot of the Project window showing the folder structure with expanded Settings folder highlighting the base classes + +6. **addressables_configuration.png** + - Screenshot of the Addressables Groups window showing settings assets properly configured