Cleanup the editor assembly and provide a tool overview doc
This commit is contained in:
211
Assets/Editor/Settings/DeveloperSettingsEditorWindow.cs
Normal file
211
Assets/Editor/Settings/DeveloperSettingsEditorWindow.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace AppleHills.Core.Settings.Editor
|
||||
{
|
||||
public class DeveloperSettingsEditorWindow : EditorWindow
|
||||
{
|
||||
private Vector2 scrollPosition;
|
||||
private List<BaseDeveloperSettings> allDeveloperSettings = new List<BaseDeveloperSettings>();
|
||||
private string[] tabNames = new string[] { "Diving", "Debug", "Other Systems" }; // Added Debug tab
|
||||
private int selectedTab = 0;
|
||||
private Dictionary<string, SerializedObject> serializedSettingsObjects = new Dictionary<string, SerializedObject>();
|
||||
private GUIStyle headerStyle;
|
||||
|
||||
[MenuItem("AppleHills/Developer Settings Editor")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
GetWindow<DeveloperSettingsEditorWindow>("Developer Settings");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
LoadAllSettings();
|
||||
}
|
||||
|
||||
private void LoadAllSettings()
|
||||
{
|
||||
allDeveloperSettings.Clear();
|
||||
serializedSettingsObjects.Clear();
|
||||
|
||||
// Find all developer settings assets
|
||||
string[] guids = AssetDatabase.FindAssets("t:BaseDeveloperSettings");
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
BaseDeveloperSettings settings = AssetDatabase.LoadAssetAtPath<BaseDeveloperSettings>(path);
|
||||
if (settings != null)
|
||||
{
|
||||
allDeveloperSettings.Add(settings);
|
||||
serializedSettingsObjects[settings.GetType().Name] = new SerializedObject(settings);
|
||||
}
|
||||
}
|
||||
|
||||
// If any settings are missing, create them
|
||||
CreateSettingsIfMissing<DivingDeveloperSettings>("DivingDeveloperSettings");
|
||||
CreateSettingsIfMissing<DebugSettings>("DebugSettings");
|
||||
|
||||
// Add more developer settings types here as needed
|
||||
// CreateSettingsIfMissing<OtherDeveloperSettings>("OtherDeveloperSettings");
|
||||
}
|
||||
|
||||
private void CreateSettingsIfMissing<T>(string fileName) where T : BaseDeveloperSettings
|
||||
{
|
||||
if (!allDeveloperSettings.Any(s => s is T))
|
||||
{
|
||||
// Check if the asset already exists
|
||||
string[] guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}");
|
||||
if (guids.Length == 0)
|
||||
{
|
||||
// Create the settings folder if it doesn't exist
|
||||
string settingsFolder = "Assets/Settings/Developer";
|
||||
if (!AssetDatabase.IsValidFolder("Assets/Settings"))
|
||||
{
|
||||
AssetDatabase.CreateFolder("Assets", "Settings");
|
||||
}
|
||||
if (!AssetDatabase.IsValidFolder(settingsFolder))
|
||||
{
|
||||
AssetDatabase.CreateFolder("Assets/Settings", "Developer");
|
||||
}
|
||||
|
||||
// Create new settings asset
|
||||
T settings = CreateInstance<T>();
|
||||
string path = $"{settingsFolder}/{fileName}.asset";
|
||||
AssetDatabase.CreateAsset(settings, path);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
allDeveloperSettings.Add(settings);
|
||||
serializedSettingsObjects[typeof(T).Name] = new SerializedObject(settings);
|
||||
Debug.Log($"Created missing developer settings asset: {path}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load existing asset
|
||||
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||
T settings = AssetDatabase.LoadAssetAtPath<T>(path);
|
||||
allDeveloperSettings.Add(settings);
|
||||
serializedSettingsObjects[typeof(T).Name] = new SerializedObject(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (headerStyle == null)
|
||||
{
|
||||
headerStyle = new GUIStyle(EditorStyles.boldLabel);
|
||||
headerStyle.fontSize = 14;
|
||||
headerStyle.margin = new RectOffset(0, 0, 10, 10);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Apple Hills Developer Settings", headerStyle);
|
||||
EditorGUILayout.HelpBox("This editor is for technical settings intended for developers. For gameplay settings, use the Game Settings editor.", MessageType.Info);
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
selectedTab = GUILayout.Toolbar(selectedTab, tabNames);
|
||||
|
||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||||
|
||||
switch (selectedTab)
|
||||
{
|
||||
case 0: // Diving
|
||||
DrawSettingsEditor<DivingDeveloperSettings>();
|
||||
break;
|
||||
case 1: // Debug
|
||||
DrawSettingsEditor<DebugSettings>();
|
||||
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
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("Refresh", GUILayout.Width(100)))
|
||||
{
|
||||
LoadAllSettings();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Save All", GUILayout.Width(100)))
|
||||
{
|
||||
foreach (var serializedObj in serializedSettingsObjects.Values)
|
||||
{
|
||||
serializedObj.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(serializedObj.targetObject);
|
||||
}
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
Debug.Log("All developer settings saved!");
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawSettingsEditor<T>() where T : BaseDeveloperSettings
|
||||
{
|
||||
BaseDeveloperSettings settings = allDeveloperSettings.Find(s => s is T);
|
||||
if (settings == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox($"No {typeof(T).Name} found. Click Refresh to create one.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
SerializedObject serializedObj = serializedSettingsObjects[typeof(T).Name];
|
||||
serializedObj.Update();
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
// Draw all properties
|
||||
SerializedProperty property = serializedObj.GetIterator();
|
||||
bool enterChildren = true;
|
||||
while (property.NextVisible(enterChildren))
|
||||
{
|
||||
enterChildren = false;
|
||||
|
||||
// Skip the script field
|
||||
if (property.name == "m_Script") continue;
|
||||
|
||||
// Group headers
|
||||
if (property.isArray && property.propertyType == SerializedPropertyType.Generic)
|
||||
{
|
||||
EditorGUILayout.LabelField(property.displayName, EditorStyles.boldLabel);
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(property, true);
|
||||
}
|
||||
|
||||
// Apply changes
|
||||
if (serializedObj.ApplyModifiedProperties())
|
||||
{
|
||||
EditorUtility.SetDirty(settings);
|
||||
|
||||
// Trigger OnValidate on the asset
|
||||
if (settings != null)
|
||||
{
|
||||
settings.OnValidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to highlight important fields
|
||||
private void DrawHighlightedProperty(SerializedProperty property, string tooltip = null)
|
||||
{
|
||||
GUI.backgroundColor = new Color(0.8f, 0.9f, 1f); // Light blue for developer settings
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
EditorGUILayout.PropertyField(property, new GUIContent(property.displayName, tooltip));
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ab6d9fee0924431b8e22edb500b35df
|
||||
timeCreated: 1758710778
|
||||
104
Assets/Editor/Settings/EditorSettingsProvider.cs
Normal file
104
Assets/Editor/Settings/EditorSettingsProvider.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using UnityEditor;
|
||||
using AppleHills.Core.Settings;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppleHills.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to settings in editor (non-play) mode
|
||||
/// </summary>
|
||||
[InitializeOnLoad]
|
||||
public static class EditorSettingsProvider
|
||||
{
|
||||
private static PlayerFollowerSettings _playerFollowerSettings;
|
||||
private static InteractionSettings _interactionSettings;
|
||||
private static DivingMinigameSettings _divingMinigameSettings;
|
||||
|
||||
// Static constructor will be called when Unity loads/reloads scripts
|
||||
static EditorSettingsProvider()
|
||||
{
|
||||
LoadAllSettings();
|
||||
|
||||
// Set up the delegates in SettingsAccess
|
||||
AppleHills.SettingsAccess.SetupEditorProviders(
|
||||
GetPlayerStopDistance,
|
||||
GetPlayerStopDistanceDirectInteraction,
|
||||
GetPuzzlePromptRange
|
||||
);
|
||||
|
||||
// Subscribe to asset changes to auto-refresh when settings are modified
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
EditorApplication.projectChanged += OnProjectChanged;
|
||||
};
|
||||
}
|
||||
|
||||
private static void OnProjectChanged()
|
||||
{
|
||||
// Check if any settings assets have changed
|
||||
if (HasSettingsChanged())
|
||||
{
|
||||
LoadAllSettings();
|
||||
RefreshSceneViews();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasSettingsChanged()
|
||||
{
|
||||
// Simplified check - you might want to make this more efficient
|
||||
// by checking timestamps or specific files
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void LoadAllSettings()
|
||||
{
|
||||
_playerFollowerSettings = AssetDatabase.LoadAssetAtPath<PlayerFollowerSettings>("Assets/Settings/PlayerFollowerSettings.asset");
|
||||
_interactionSettings = AssetDatabase.LoadAssetAtPath<InteractionSettings>("Assets/Settings/InteractionSettings.asset");
|
||||
_divingMinigameSettings = AssetDatabase.LoadAssetAtPath<DivingMinigameSettings>("Assets/Settings/MinigameSettings.asset");
|
||||
|
||||
// Re-register the delegates in case they were lost
|
||||
AppleHills.SettingsAccess.SetupEditorProviders(
|
||||
GetPlayerStopDistance,
|
||||
GetPlayerStopDistanceDirectInteraction,
|
||||
GetPuzzlePromptRange
|
||||
);
|
||||
|
||||
Debug.Log("Editor settings loaded for Scene View use");
|
||||
}
|
||||
|
||||
public static void RefreshSceneViews()
|
||||
{
|
||||
// Force scene views to repaint to refresh gizmos
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
// Implementation of delegate methods
|
||||
private static float GetPlayerStopDistance()
|
||||
{
|
||||
return _interactionSettings?.PlayerStopDistance ?? 6.0f;
|
||||
}
|
||||
|
||||
private static float GetPlayerStopDistanceDirectInteraction()
|
||||
{
|
||||
return _interactionSettings?.PlayerStopDistanceDirectInteraction ?? 2.0f;
|
||||
}
|
||||
|
||||
private static float GetPuzzlePromptRange()
|
||||
{
|
||||
return _interactionSettings?.DefaultPuzzlePromptRange ?? 3.0f;
|
||||
}
|
||||
|
||||
// Other utility methods
|
||||
public static T GetSettings<T>() where T : BaseSettings
|
||||
{
|
||||
if (typeof(T) == typeof(PlayerFollowerSettings))
|
||||
return _playerFollowerSettings as T;
|
||||
else if (typeof(T) == typeof(InteractionSettings))
|
||||
return _interactionSettings as T;
|
||||
else if (typeof(T) == typeof(DivingMinigameSettings))
|
||||
return _divingMinigameSettings as T;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Editor/Settings/EditorSettingsProvider.cs.meta
Normal file
3
Assets/Editor/Settings/EditorSettingsProvider.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e8da573a8db4ea892fe476592276e0f
|
||||
timeCreated: 1758634265
|
||||
195
Assets/Editor/Settings/SettingsEditorWindow.cs
Normal file
195
Assets/Editor/Settings/SettingsEditorWindow.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace AppleHills.Core.Settings.Editor
|
||||
{
|
||||
public class SettingsEditorWindow : EditorWindow
|
||||
{
|
||||
private Vector2 scrollPosition;
|
||||
private List<BaseSettings> allSettings = new List<BaseSettings>();
|
||||
private string[] tabNames = new string[] { "Player & Follower", "Interaction & Items", "Diving Minigame" };
|
||||
private int selectedTab = 0;
|
||||
private Dictionary<string, SerializedObject> serializedSettingsObjects = new Dictionary<string, SerializedObject>();
|
||||
private GUIStyle headerStyle;
|
||||
|
||||
[MenuItem("AppleHills/Settings Editor")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
GetWindow<SettingsEditorWindow>("Game Settings");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
LoadAllSettings();
|
||||
}
|
||||
|
||||
private void LoadAllSettings()
|
||||
{
|
||||
allSettings.Clear();
|
||||
serializedSettingsObjects.Clear();
|
||||
|
||||
// Find all settings assets
|
||||
string[] guids = AssetDatabase.FindAssets("t:BaseSettings");
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
BaseSettings settings = AssetDatabase.LoadAssetAtPath<BaseSettings>(path);
|
||||
if (settings != null)
|
||||
{
|
||||
allSettings.Add(settings);
|
||||
serializedSettingsObjects[settings.GetType().Name] = new SerializedObject(settings);
|
||||
}
|
||||
}
|
||||
|
||||
// If any settings are missing, create them
|
||||
CreateSettingsIfMissing<PlayerFollowerSettings>("PlayerFollowerSettings");
|
||||
CreateSettingsIfMissing<InteractionSettings>("InteractionSettings");
|
||||
CreateSettingsIfMissing<DivingMinigameSettings>("DivingMinigameSettings");
|
||||
}
|
||||
|
||||
private void CreateSettingsIfMissing<T>(string fileName) where T : BaseSettings
|
||||
{
|
||||
if (!allSettings.Any(s => s is T))
|
||||
{
|
||||
// Check if the asset already exists
|
||||
string[] guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}");
|
||||
if (guids.Length == 0)
|
||||
{
|
||||
// Create the settings folder if it doesn't exist
|
||||
if (!AssetDatabase.IsValidFolder("Assets/Settings"))
|
||||
{
|
||||
AssetDatabase.CreateFolder("Assets", "Settings");
|
||||
}
|
||||
|
||||
// Create new settings asset
|
||||
T settings = CreateInstance<T>();
|
||||
string path = $"Assets/Settings/{fileName}.asset";
|
||||
AssetDatabase.CreateAsset(settings, path);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
allSettings.Add(settings);
|
||||
serializedSettingsObjects[typeof(T).Name] = new SerializedObject(settings);
|
||||
Debug.Log($"Created missing settings asset: {path}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load existing asset
|
||||
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||
T settings = AssetDatabase.LoadAssetAtPath<T>(path);
|
||||
allSettings.Add(settings);
|
||||
serializedSettingsObjects[typeof(T).Name] = new SerializedObject(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (headerStyle == null)
|
||||
{
|
||||
headerStyle = new GUIStyle(EditorStyles.boldLabel);
|
||||
headerStyle.fontSize = 14;
|
||||
headerStyle.margin = new RectOffset(0, 0, 10, 10);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Apple Hills Game Settings", headerStyle);
|
||||
EditorGUILayout.HelpBox("Use this window to modify game settings. Changes are saved automatically.", MessageType.Info);
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
selectedTab = GUILayout.Toolbar(selectedTab, tabNames);
|
||||
|
||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||||
|
||||
switch (selectedTab)
|
||||
{
|
||||
case 0: // Player & Follower
|
||||
DrawSettingsEditor<PlayerFollowerSettings>();
|
||||
break;
|
||||
case 1: // Interaction & Items
|
||||
DrawSettingsEditor<InteractionSettings>();
|
||||
break;
|
||||
case 2: // Minigames
|
||||
DrawSettingsEditor<DivingMinigameSettings>();
|
||||
break;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("Refresh", GUILayout.Width(100)))
|
||||
{
|
||||
LoadAllSettings();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Save All", GUILayout.Width(100)))
|
||||
{
|
||||
foreach (var serializedObj in serializedSettingsObjects.Values)
|
||||
{
|
||||
serializedObj.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(serializedObj.targetObject);
|
||||
}
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
// Refresh editor settings after save
|
||||
AppleHills.Editor.EditorSettingsProvider.LoadAllSettings();
|
||||
AppleHills.Editor.EditorSettingsProvider.RefreshSceneViews();
|
||||
|
||||
Debug.Log("All settings saved and editor views refreshed!");
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawSettingsEditor<T>() where T : BaseSettings
|
||||
{
|
||||
BaseSettings settings = allSettings.Find(s => s is T);
|
||||
if (settings == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox($"No {typeof(T).Name} found. Click Refresh to create one.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
SerializedObject serializedObj = serializedSettingsObjects[typeof(T).Name];
|
||||
serializedObj.Update();
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
// Draw all properties
|
||||
SerializedProperty property = serializedObj.GetIterator();
|
||||
bool enterChildren = true;
|
||||
while (property.NextVisible(enterChildren))
|
||||
{
|
||||
enterChildren = false;
|
||||
|
||||
// Skip the script field
|
||||
if (property.name == "m_Script") continue;
|
||||
|
||||
EditorGUILayout.PropertyField(property, true);
|
||||
}
|
||||
|
||||
// Apply changes
|
||||
if (serializedObj.ApplyModifiedProperties())
|
||||
{
|
||||
EditorUtility.SetDirty(settings);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to highlight important fields
|
||||
private void DrawHighlightedProperty(SerializedProperty property, string tooltip = null)
|
||||
{
|
||||
GUI.backgroundColor = new Color(1f, 1f, 0.8f);
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
EditorGUILayout.PropertyField(property, new GUIContent(property.displayName, tooltip));
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Editor/Settings/SettingsEditorWindow.cs.meta
Normal file
3
Assets/Editor/Settings/SettingsEditorWindow.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfb9e77c746e41a2903603a39df3d424
|
||||
timeCreated: 1758619952
|
||||
Reference in New Issue
Block a user