diff --git a/Editor/Core/Architecture.meta b/Documentation/Information.meta
similarity index 77%
rename from Editor/Core/Architecture.meta
rename to Documentation/Information.meta
index b1a05d71..0b4d1848 100644
--- a/Editor/Core/Architecture.meta
+++ b/Documentation/Information.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 600171c84a5cb1e4c9936a94efd94541
+guid: b31819f8abae8d6498ef952fa251bb85
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Documentation/Information/ClassViewer.txt b/Documentation/Information/ClassViewer.txt
new file mode 100644
index 00000000..4d82ba38
--- /dev/null
+++ b/Documentation/Information/ClassViewer.txt
@@ -0,0 +1,70 @@
+Runtime
+ Core
+ Architecture
+ Game -> This is a red word and bold green. Go to TEST https://github.com/AliJimpa/RealMethod/wiki/Assets.
+ World -> just test text ColortTEst Without link
+ GameConfig
+ GameBridge
+ ManagerContracts
+ ServiceContracts
+ WorldSceneConfig
+ ProjectSettingAsset -> ProjectSettingAsset Should be in Resource>RealMethod>RealMethodSetting.asset and all RealMethod setting handeled by this asset and this name.
+ Attributes
+ ButtonAttribute
+ ColorFieldAttribute
+ ConditionalHideAttribute
+ DropdownAttribute
+ DropdownFromArrayAttribute
+ DropdownFromDictionaryAttribute
+ EnumDescriptionAttribute
+ ExpandableAttribute
+ HelpBoxAttribute
+ HideInInspectorByEnumAttribute
+ InterfaceValidationDrawer
+ LayerAttribute
+ ListToPopupAttribute
+ MinMaxRangeAttribute
+ ReadOnlyAttribute
+ SeparatorAttribute
+ ShowInInspectorByEnumAttribute
+ ShowOnlyAttribute
+ ShowTypeAttribute
+ TagSelectorAttribute
+ Definitions
+ Assets
+ Identifier
+ Prefab
+ Tick
+ ProjectSetting
+ ProjectSettingAsset
+ Library
+ Extension
+ Interfaces
+ SharedScripts
+ Utilities
+ Vendor
+ Pattern
+ Components
+ DataAssets
+ DesignPatterns
+ Managers
+ Services
+ ReadySet
+ Commands
+ Components
+ DefaultsClass
+ Managers
+ Presets
+ Services
+ Toolkit
+ Ability
+ Actor
+ CSVFile
+ CurveViewer
+ Interaction
+ Inventory
+ PCG
+ Pickup
+ RPG
+ Tutorial
+ Upgrade
diff --git a/Reservoir/ScriptTemplates/ItemAssetTemplate.txt.meta b/Documentation/Information/ClassViewer.txt.meta
similarity index 75%
rename from Reservoir/ScriptTemplates/ItemAssetTemplate.txt.meta
rename to Documentation/Information/ClassViewer.txt.meta
index d7efbd4a..9d6bfdd0 100644
--- a/Reservoir/ScriptTemplates/ItemAssetTemplate.txt.meta
+++ b/Documentation/Information/ClassViewer.txt.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: bb63fd5394661484babdcdc725c3d48a
+guid: 79055230a8dc125418831907cfeb785e
TextScriptImporter:
externalObjects: {}
userData:
diff --git a/Editor/Library/Vendor.meta b/Documentation/Resource.meta
similarity index 77%
rename from Editor/Library/Vendor.meta
rename to Documentation/Resource.meta
index 95cd04e7..16b30863 100644
--- a/Editor/Library/Vendor.meta
+++ b/Documentation/Resource.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: b6449ef571a85534abe38c8766ce2b2c
+guid: 7b6dff7ffa0c54f4c93b41811af269d5
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Reservoir/Icons/Core/RealMethod.png b/Documentation/Resource/RM_Title.png
similarity index 100%
rename from Reservoir/Icons/Core/RealMethod.png
rename to Documentation/Resource/RM_Title.png
diff --git a/Reservoir/Icons/Core/RealMethod.png.meta b/Documentation/Resource/RM_Title.png.meta
similarity index 100%
rename from Reservoir/Icons/Core/RealMethod.png.meta
rename to Documentation/Resource/RM_Title.png.meta
diff --git a/Editor/Core/Architecture/GameCompWindow.cs b/Editor/Core/Architecture/GameCompWindow.cs
deleted file mode 100644
index 589ee281..00000000
--- a/Editor/Core/Architecture/GameCompWindow.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using PlasticGui.WorkspaceWindow;
-using UnityEditor;
-
-namespace RealMethod
-{
- [CustomEditor(typeof(Game), true)]
- public class GameCompWindow : UnityEditor.Editor
- {
- private Game BaseComponent;
-
- private void OnEnable()
- {
- BaseComponent = (Game)target;
- }
- public override void OnInspectorGUI()
- {
- base.OnInspectorGUI();
- EditorGUILayout.Space();
- if (BaseComponent != null)
- {
- if (Game.World != null)
- {
-
- }
- EditorGUILayout.LabelField($"{GetWorld()} | {GetSetvice()} | {GetConfig()}");
- EditorGUILayout.Space(0.5f);
- string[] Data = BaseComponent.GetAllServiceNames();
- for (int i = 0; i < Data.Length; i++)
- {
- EditorGUILayout.LabelField($"{i + 1}. {Data[i]}");
- }
- }
- }
-
-
-
-
-
- private string GetWorld()
- {
- return Game.World != null ? Game.World.GetType().Name : "World Not Valid";
- }
- private string GetSetvice()
- {
- return Game.Service != null ? Game.Service.GetType().Name : "GameService Not Valid";
- }
- private string GetConfig()
- {
- return Game.Config != null ? Game.Config.GetType().Name : "GameConfig Not Valid";
- }
-
-
-
-
-
-
-
-
-
- }
-
-
-
-}
\ No newline at end of file
diff --git a/Editor/Core/Definitions/ConfigAssetValidator.cs b/Editor/Core/Definitions/ConfigAssetValidator.cs
deleted file mode 100644
index bec8bc5d..00000000
--- a/Editor/Core/Definitions/ConfigAssetValidator.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-#if UNITY_EDITOR
-using UnityEditor;
-using UnityEngine;
-using System;
-using System.Reflection;
-using System.Linq;
-
-namespace RealMethod.Editor
-{
- [InitializeOnLoad]
- public static class ConfigAssetValidator
- {
- static ConfigAssetValidator()
- {
- EditorApplication.delayCall += ValidateAllConfigs;
- }
-
- public static void ValidateAllConfigs()
- {
- var configTypes = AppDomain.CurrentDomain.GetAssemblies()
- .SelectMany(a => a.GetTypes())
- .Where(t => t.IsSubclassOf(typeof(ConfigAsset)));
-
- foreach (var type in configTypes)
- {
- // 🔹 Check fields
- var badFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
- .Where(f => !f.IsInitOnly && !f.IsLiteral && !f.IsDefined(typeof(SerializeField), false))
- .ToList();
-
- foreach (var f in badFields)
- {
- Debug.LogError($"❌ '{type.Name}' has non-readonly field '{f.Name}' — only readonly fields allowed in Config-derived classes.");
- }
-
- // 🔹 Check methods
- var badMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
- .Where(m => !m.IsSpecialName && !m.IsConstructor)
- .Where(m => ViolatesPureMethodRules(m))
- .ToList();
-
- foreach (var m in badMethods)
- {
- Debug.LogError($"❌ '{type.Name}' public method '{m.Name}' modifies state — only pure getter/return methods are allowed in Config-derived classes.");
- }
- }
- }
- private static bool ViolatesPureMethodRules(MethodInfo method)
- {
- try
- {
- var body = method.GetMethodBody();
- if (body == null)
- return false;
-
- var il = body.GetILAsByteArray();
- if (il == null)
- return false;
-
- // Look for IL opcodes that store data or call setters
- for (int i = 0; i < il.Length - 1; i++)
- {
- byte b = il[i];
- byte next = il[i + 1];
-
- // Store field (stfld or stsfld)
- if (b == 0x7D || b == 0x80)
- return true;
-
- // Callvirt / call that might be setter
- if (b == 0x28)
- {
- var tokens = method.Module.ResolveMethod(BitConverter.ToInt32(il, i + 1));
- if (tokens.Name.StartsWith("set_", StringComparison.Ordinal))
- return true;
- }
- }
- }
- catch
- {
- // Ignore methods that can't be inspected
- }
-
- return false;
- }
- }
-#endif
-
-}
\ No newline at end of file
diff --git a/Editor/Core/Definitions/PrefabDrawer.cs b/Editor/Core/Definitions/PrefabDrawer.cs
deleted file mode 100644
index 7962de34..00000000
--- a/Editor/Core/Definitions/PrefabDrawer.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-#if UNITY_EDITOR
-using UnityEditor;
-using UnityEngine;
-using System;
-
-namespace RealMethod.Editor
-{
- [CustomPropertyDrawer(typeof(PrefabCore), true)]
- public class PrefabDrawer : PropertyDrawer
- {
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- SerializedProperty prefabGOProp = property.FindPropertyRelative("PrefabAsset");
-
- if (prefabGOProp == null)
- {
- EditorGUI.LabelField(position, label.text, "Invalid Prefab Field");
- return;
- }
-
- EditorGUI.BeginProperty(position, label, property);
-
- UnityEngine.Object newObject = EditorGUI.ObjectField(
- position,
- label,
- prefabGOProp.objectReferenceValue,
- typeof(GameObject),
- false
- );
-
- if (newObject != prefabGOProp.objectReferenceValue)
- {
- if (newObject == null)
- {
- prefabGOProp.objectReferenceValue = null;
- }
- else if (PrefabUtility.IsPartOfPrefabAsset(newObject))
- {
- GameObject go = newObject as GameObject;
-
- // Get the actual object instance for this SerializedProperty
- PrefabCore targetPrefab = GetTargetObjectOfProperty(property) as PrefabCore;
-
- if (targetPrefab == null)
- {
- EditorGUI.LabelField(position, label.text, "Invalid prefab wrapper.");
- return;
- }
-
- var targetClass = targetPrefab.GetTargetClass();
-
- if (targetClass != null && go.GetComponent(targetClass) != null)
- {
- prefabGOProp.objectReferenceValue = newObject;
- }
- else
- {
- Debug.LogWarning($"Selected prefab does not have required component: {targetClass?.Name}");
- }
- }
- else
- {
- Debug.LogWarning("Only prefab assets from the project can be assigned.");
- }
- }
-
- EditorGUI.EndProperty();
- }
-
- // Utility to get the real object from a SerializedProperty
- private object GetTargetObjectOfProperty(SerializedProperty prop)
- {
- if (prop == null) return null;
-
- string path = prop.propertyPath.Replace(".Array.data[", "[");
- object obj = prop.serializedObject.targetObject;
- string[] elements = path.Split('.');
-
- foreach (string element in elements)
- {
- if (element.Contains("["))
- {
- string elementName = element.Substring(0, element.IndexOf("["));
- int index = Convert.ToInt32(element.Substring(element.IndexOf("[")).Replace("[", "").Replace("]", ""));
- obj = GetValue(obj, elementName, index);
- }
- else
- {
- obj = GetValue(obj, element);
- }
- }
- return obj;
- }
-
- private object GetValue(object source, string name)
- {
- if (source == null) return null;
- var type = source.GetType();
- var f = type.GetField(name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
- if (f == null) return null;
- return f.GetValue(source);
- }
-
- private object GetValue(object source, string name, int index)
- {
- var enumerable = GetValue(source, name) as System.Collections.IEnumerable;
- if (enumerable == null) return null;
- var enm = enumerable.GetEnumerator();
- for (int i = 0; i <= index; i++)
- {
- if (!enm.MoveNext()) return null;
- }
- return enm.Current;
- }
- }
-}
-#endif
diff --git a/Editor/Library/Vendor/SerializableDictionary.meta b/Editor/Core/Drawers.meta
similarity index 77%
rename from Editor/Library/Vendor/SerializableDictionary.meta
rename to Editor/Core/Drawers.meta
index 52041f27..c71d71ad 100644
--- a/Editor/Library/Vendor/SerializableDictionary.meta
+++ b/Editor/Core/Drawers.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8c73a086c2d5b9142b2f8d4d8befecfe
+guid: 4b2ca676aa99da945bf729d345f81474
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Runtime/Core/Attributes/ExpandableAttribute.cs b/Editor/Core/Drawers/AssetInlinDrawer.cs
similarity index 79%
rename from Runtime/Core/Attributes/ExpandableAttribute.cs
rename to Editor/Core/Drawers/AssetInlinDrawer.cs
index eaf64240..6d602555 100644
--- a/Runtime/Core/Attributes/ExpandableAttribute.cs
+++ b/Editor/Core/Drawers/AssetInlinDrawer.cs
@@ -1,35 +1,18 @@
using System;
+using System.Collections.Generic;
+using UnityEditor;
using UnityEngine;
-namespace RealMethod
+namespace RealMethod.Editor
{
-
-#if UNITY_EDITOR
- using System.Collections.Generic;
- using UnityEditor;
-#endif
-
- ///
- /// Use this property on a ScriptableObject type to allow the editors drawing the field to draw an expandable
- /// area that allows for changing the values on the object without having to change editor.
- ///
- public class ExpandableAttribute : PropertyAttribute
- {
- public ExpandableAttribute()
- {
-
- }
- }
-
-#if UNITY_EDITOR
///
/// Draws the property field for any field marked with ExpandableAttribute.
///
- [CustomPropertyDrawer(typeof(ExpandableAttribute), true)]
- public class ExpandableAttributeDrawer : PropertyDrawer
+ [CustomPropertyDrawer(typeof(AssetInlinAttribute), true)]
+ public class AssetInlinDrawer : PropertyDrawer
{
+ // Style Setup
// Use the following area to change the style of the expandable ScriptableObject drawers;
- #region Style Setup
private enum BackgroundStyles
{
None,
@@ -37,42 +20,37 @@ private enum BackgroundStyles
Darken,
Lighten
}
-
+
///
/// Whether the default editor Script field should be shown.
///
private static bool SHOW_SCRIPT_FIELD = false;
-
///
/// The spacing on the inside of the background rect.
///
private static float INNER_SPACING = 6.0f;
-
///
/// The spacing on the outside of the background rect.
///
private static float OUTER_SPACING = 4.0f;
-
///
/// The style the background uses.
///
private static BackgroundStyles BACKGROUND_STYLE = BackgroundStyles.HelpBox;
-
///
/// The colour that is used to darken the background.
///
private static Color DARKEN_COLOUR = new Color(0.0f, 0.0f, 0.0f, 0.2f);
-
///
/// The colour that is used to lighten the background.
///
private static Color LIGHTEN_COLOUR = new Color(1.0f, 1.0f, 1.0f, 0.2f);
- #endregion
+
///
/// Cached editor reference.
///
- private Editor editor = null;
+ private UnityEditor.Editor editor = null;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
@@ -87,7 +65,7 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent
return totalHeight;
if (editor == null)
- Editor.CreateCachedEditor(property.objectReferenceValue, null, ref editor);
+ UnityEditor.Editor.CreateCachedEditor(property.objectReferenceValue, null, ref editor);
if (editor == null)
return totalHeight;
@@ -111,7 +89,6 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent
return totalHeight;
}
-
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Rect fieldRect = new Rect(position);
@@ -119,11 +96,11 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
EditorGUI.PropertyField(fieldRect, property, label, true);
- if (property.objectReferenceValue == null)
- {
- Debug.Log("It's secretly null");
- return;
- }
+ // if (property.objectReferenceValue == null)
+ // {
+ // Debug.Log("It's secretly null");
+ // return;
+ // }
property.isExpanded = EditorGUI.Foldout(fieldRect, property.isExpanded, GUIContent.none, true);
@@ -131,7 +108,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
return;
if (editor == null)
- Editor.CreateCachedEditor(property.objectReferenceValue, null, ref editor);
+ UnityEditor.Editor.CreateCachedEditor(property.objectReferenceValue, null, ref editor);
if (editor == null)
{
@@ -211,6 +188,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
#endregion
}
+
///
/// Draws the Background
///
@@ -235,21 +213,7 @@ private void DrawBackground(Rect rect)
}
}
- ///
- /// Required for the fetching of a default editor on MonoBehaviour objects.
- ///
- [CanEditMultipleObjects]
- [CustomEditor(typeof(MonoBehaviour), true)]
- public class MonoBehaviourEditor : Editor { }
+
- ///
- /// Required for the fetching of a default editor on ScriptableObject objects.
- ///
- [CanEditMultipleObjects]
- [CustomEditor(typeof(ScriptableObject), true)]
- public class ScriptableObjectEditor : Editor { }
-#endif
-}
-// ----Use
-//[Expandable]
-//public ScriptableObject TEST;
\ No newline at end of file
+
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/AssetInlinDrawer.cs.meta b/Editor/Core/Drawers/AssetInlinDrawer.cs.meta
new file mode 100644
index 00000000..845d3428
--- /dev/null
+++ b/Editor/Core/Drawers/AssetInlinDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 4d330d952dca5b1429429089ed414c8a
\ No newline at end of file
diff --git a/Editor/Core/Drawers/AssetsDrawer.cs b/Editor/Core/Drawers/AssetsDrawer.cs
new file mode 100644
index 00000000..c772820d
--- /dev/null
+++ b/Editor/Core/Drawers/AssetsDrawer.cs
@@ -0,0 +1,17 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(PrimitiveAsset), true)]
+ public class Asset_Drawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ Color prevColor = GUI.color;
+ GUI.color = new Color(1f, 0.8f, 0.8f);
+ EditorGUI.PropertyField(position, property, label, true);
+ GUI.color = prevColor;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/AssetsDrawer.cs.meta b/Editor/Core/Drawers/AssetsDrawer.cs.meta
new file mode 100644
index 00000000..5f2cec98
--- /dev/null
+++ b/Editor/Core/Drawers/AssetsDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: a177970772cd9c04184171cfabfc6ae9
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ColorFieldDrawet.cs b/Editor/Core/Drawers/ColorFieldDrawet.cs
new file mode 100644
index 00000000..0fa3b795
--- /dev/null
+++ b/Editor/Core/Drawers/ColorFieldDrawet.cs
@@ -0,0 +1,19 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(ColorFieldAttribute))]
+ public class RequiredFieldDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ ColorFieldAttribute field = attribute as ColorFieldAttribute;
+
+ GUI.color = field.color; //Set the color of the GUI
+ EditorGUI.PropertyField(position, property, label); //Draw the GUI
+ GUI.color = Color.white; //Reset the color of the GUI to white
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ColorFieldDrawet.cs.meta b/Editor/Core/Drawers/ColorFieldDrawet.cs.meta
new file mode 100644
index 00000000..658df024
--- /dev/null
+++ b/Editor/Core/Drawers/ColorFieldDrawet.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: eeddf87aa2f38034791a447abc095062
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ConditionalHideByEnumDrawer.cs b/Editor/Core/Drawers/ConditionalHideByEnumDrawer.cs
new file mode 100644
index 00000000..7d9be6a9
--- /dev/null
+++ b/Editor/Core/Drawers/ConditionalHideByEnumDrawer.cs
@@ -0,0 +1,54 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(ConditionalHideByEnumAttribute))]
+ public class ConditionalHideByEnumDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ var attr = (ConditionalHideByEnumAttribute)attribute;
+
+ // Build sibling path: replace "UseAsset" with "Mode", etc.
+ string enumPath = property.propertyPath.Replace(property.name, attr.EnumFieldName);
+ SerializedProperty enumField = property.serializedObject.FindProperty(enumPath);
+
+ if (enumField != null && !ShouldHide(enumField, attr.HideValues))
+ {
+ EditorGUI.PropertyField(position, property, label, true);
+ }
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ var attr = (ConditionalHideByEnumAttribute)attribute;
+
+ // Must use the SAME path logic as in OnGUI
+ string enumPath = property.propertyPath.Replace(property.name, attr.EnumFieldName);
+ SerializedProperty enumField = property.serializedObject.FindProperty(enumPath);
+
+ if (enumField != null && !ShouldHide(enumField, attr.HideValues))
+ {
+ return EditorGUI.GetPropertyHeight(property, label, true);
+ }
+
+ // fully hide line
+ return -EditorGUIUtility.standardVerticalSpacing;
+ }
+
+ private bool ShouldHide(SerializedProperty enumField, object[] hideValues)
+ {
+ if (enumField.propertyType == SerializedPropertyType.Enum)
+ {
+ foreach (var value in hideValues)
+ {
+ if (enumField.enumValueIndex == (int)value)
+ return true; // hide when enum matches any of these
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/Editor/Core/Drawers/ConditionalHideByEnumDrawer.cs.meta b/Editor/Core/Drawers/ConditionalHideByEnumDrawer.cs.meta
new file mode 100644
index 00000000..f4b02353
--- /dev/null
+++ b/Editor/Core/Drawers/ConditionalHideByEnumDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 07df77986e5a9f64eb6288db1009335b
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ConditionalHideDrawer.cs b/Editor/Core/Drawers/ConditionalHideDrawer.cs
new file mode 100644
index 00000000..7d6df370
--- /dev/null
+++ b/Editor/Core/Drawers/ConditionalHideDrawer.cs
@@ -0,0 +1,69 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(ConditionalHideAttribute))]
+ public class ConditionalHidePropertyDrawer : PropertyDrawer
+ {
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ ConditionalHideAttribute condHAtt = (ConditionalHideAttribute)attribute;
+ bool enabled = GetConditionalHideAttributeResult(condHAtt, property);
+
+ if (!condHAtt.HideInInspector || enabled)
+ {
+ return EditorGUI.GetPropertyHeight(property, label);
+ }
+ else
+ {
+ return -EditorGUIUtility.standardVerticalSpacing;
+ }
+ }
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ ConditionalHideAttribute condHAtt = (ConditionalHideAttribute)attribute;
+ bool enabled = GetConditionalHideAttributeResult(condHAtt, property);
+
+ bool wasEnabled = GUI.enabled;
+ GUI.enabled = enabled;
+
+ if (!condHAtt.HideInInspector || enabled)
+ {
+ EditorGUI.PropertyField(position, property, label, true);
+ }
+
+ GUI.enabled = wasEnabled;
+ }
+
+
+
+ private bool GetConditionalHideAttributeResult(ConditionalHideAttribute condHAtt, SerializedProperty property)
+ {
+ bool enabled = true;
+
+ string propertyPath = property.propertyPath; // returns the property path of the property we want to apply the attribute to
+ string conditionPath = propertyPath.Replace(property.name, condHAtt.ConditionalSourceField); // changes the path to the conditionalsource property path
+ SerializedProperty sourcePropertyValue = property.serializedObject.FindProperty(conditionPath);
+
+ if (sourcePropertyValue != null)
+ {
+ if (!condHAtt.ReverceCondition)
+ {
+ enabled = sourcePropertyValue.boolValue;
+ }
+ else
+ {
+ enabled = !sourcePropertyValue.boolValue;
+ }
+
+ }
+ else
+ {
+ Debug.LogWarning("Attempting to use a ConditionalHideAttribute but no matching SourcePropertyValue found in object: " + condHAtt.ConditionalSourceField);
+ }
+
+ return enabled;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ConditionalHideDrawer.cs.meta b/Editor/Core/Drawers/ConditionalHideDrawer.cs.meta
new file mode 100644
index 00000000..6c85b642
--- /dev/null
+++ b/Editor/Core/Drawers/ConditionalHideDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 47ed489e327ef2e41b5047aaa4bc4d7d
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ConditionalShowByEnumDrawer.cs b/Editor/Core/Drawers/ConditionalShowByEnumDrawer.cs
new file mode 100644
index 00000000..0d41b4ed
--- /dev/null
+++ b/Editor/Core/Drawers/ConditionalShowByEnumDrawer.cs
@@ -0,0 +1,53 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(ConditionalShowByEnumAttribute))]
+ public class ConditionalShowByEnumDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ var attr = (ConditionalShowByEnumAttribute)attribute;
+
+ // Build sibling path: replace "UseAsset" with "Mode", etc.
+ string enumPath = property.propertyPath.Replace(property.name, attr.EnumFieldName);
+ SerializedProperty enumField = property.serializedObject.FindProperty(enumPath);
+
+ if (enumField != null && IsVisible(enumField, attr.ShowValues))
+ {
+ EditorGUI.PropertyField(position, property, label);
+ }
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ var attr = (ConditionalShowByEnumAttribute)attribute;
+
+ // Must use the SAME path logic as in OnGUI
+ string enumPath = property.propertyPath.Replace(property.name, attr.EnumFieldName);
+ SerializedProperty enumField = property.serializedObject.FindProperty(enumPath);
+
+ if (enumField != null && IsVisible(enumField, attr.ShowValues))
+ {
+ return EditorGUI.GetPropertyHeight(property, label, true);
+ }
+
+ // fully hide line
+ return -EditorGUIUtility.standardVerticalSpacing;
+ }
+
+ private bool IsVisible(SerializedProperty enumField, object[] showValues)
+ {
+ foreach (var value in showValues)
+ {
+ if (enumField.propertyType == SerializedPropertyType.Enum && enumField.enumValueIndex == (int)value)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ConditionalShowByEnumDrawer.cs.meta b/Editor/Core/Drawers/ConditionalShowByEnumDrawer.cs.meta
new file mode 100644
index 00000000..054c05a8
--- /dev/null
+++ b/Editor/Core/Drawers/ConditionalShowByEnumDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: efb65d24cd2c9e04c867b0cae6a7d5ef
\ No newline at end of file
diff --git a/Runtime/Core/Attributes/EnumDescriptionAttribute.cs b/Editor/Core/Drawers/DescriptionEnumDrawer.cs
similarity index 66%
rename from Runtime/Core/Attributes/EnumDescriptionAttribute.cs
rename to Editor/Core/Drawers/DescriptionEnumDrawer.cs
index 713b9da5..5f802a4c 100644
--- a/Runtime/Core/Attributes/EnumDescriptionAttribute.cs
+++ b/Editor/Core/Drawers/DescriptionEnumDrawer.cs
@@ -1,28 +1,11 @@
using System;
-using UnityEngine;
-#if UNITY_EDITOR
using UnityEditor;
-#endif
+using UnityEngine;
-namespace RealMethod
+namespace RealMethod.Editor
{
- [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
- public class EnumDescriptionAttribute : PropertyAttribute
- {
- public string Description { get; }
-
- public EnumDescriptionAttribute(string description)
- {
- Description = description;
- }
- }
-
-
-#if UNITY_EDITOR
-
-
- [CustomPropertyDrawer(typeof(EnumDescriptionAttribute))]
- public class EnumWithDescriptionsDrawer : PropertyDrawer
+ [CustomPropertyDrawer(typeof(DescriptionEnumAttribute))]
+ public class DescriptionEnumDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
@@ -60,26 +43,11 @@ private string[] GetEnumDescriptions(Type enumType)
for (int i = 0; i < names.Length; i++)
{
var field = enumType.GetField(names[i]);
- var descriptionAttribute = Attribute.GetCustomAttribute(field, typeof(EnumDescriptionAttribute)) as EnumDescriptionAttribute;
+ var descriptionAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionEnumAttribute)) as DescriptionEnumAttribute;
descriptions[i] = descriptionAttribute != null ? descriptionAttribute.Description : names[i];
}
return descriptions;
}
}
-#endif
-}
-
-
-//////Use
-// public enum MyEnumWithDescriptions
-// {
-// [EnumDescription("This is the first option.")]
-// Option1,
-
-// [EnumDescription("This is the second option.")]
-// Option2,
-
-// [EnumDescription("This is the third option.")]
-// Option3
-// }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/DescriptionEnumDrawer.cs.meta b/Editor/Core/Drawers/DescriptionEnumDrawer.cs.meta
new file mode 100644
index 00000000..05ee81f3
--- /dev/null
+++ b/Editor/Core/Drawers/DescriptionEnumDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 16a6b6f8280e964489d2e6b7629652a9
\ No newline at end of file
diff --git a/Editor/Core/Drawers/DropdownDrawer.cs b/Editor/Core/Drawers/DropdownDrawer.cs
new file mode 100644
index 00000000..0bc2d7f8
--- /dev/null
+++ b/Editor/Core/Drawers/DropdownDrawer.cs
@@ -0,0 +1,31 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(DropdownAttribute))]
+ public class DropdownDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ DropdownAttribute dropdownAttribute = (DropdownAttribute)attribute;
+
+ if (property.propertyType == SerializedPropertyType.String)
+ {
+ int index = Mathf.Max(0, System.Array.IndexOf(dropdownAttribute.options, property.stringValue));
+ index = EditorGUI.Popup(position, label.text, index, dropdownAttribute.options);
+ property.stringValue = dropdownAttribute.options[index];
+ }
+ else if (property.propertyType == SerializedPropertyType.Integer)
+ {
+ int index = Mathf.Clamp(property.intValue, 0, dropdownAttribute.options.Length - 1);
+ index = EditorGUI.Popup(position, label.text, index, dropdownAttribute.options);
+ property.intValue = index;
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Use Dropdown with string or int.");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/DropdownDrawer.cs.meta b/Editor/Core/Drawers/DropdownDrawer.cs.meta
new file mode 100644
index 00000000..8003b34b
--- /dev/null
+++ b/Editor/Core/Drawers/DropdownDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 93150ce5c26a6bd44b4f1552fc8553b3
\ No newline at end of file
diff --git a/Editor/Core/Drawers/DropdownFromArrayDrawer.cs b/Editor/Core/Drawers/DropdownFromArrayDrawer.cs
new file mode 100644
index 00000000..19c58842
--- /dev/null
+++ b/Editor/Core/Drawers/DropdownFromArrayDrawer.cs
@@ -0,0 +1,53 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(DropdownFromArrayAttribute))]
+ public class DropdownFromArrayDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ DropdownFromArrayAttribute dropdownAttribute = (DropdownFromArrayAttribute)attribute;
+ string[] options = GetOptions(property, dropdownAttribute.TargetArray);
+
+ if (options != null && options.Length > 0)
+ {
+ if (property.propertyType == SerializedPropertyType.String)
+ {
+ int index = Mathf.Max(0, System.Array.IndexOf(options, property.stringValue));
+ index = EditorGUI.Popup(position, label.text, index, options);
+ property.stringValue = options[index];
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Use DropdownFromArray with string.");
+ }
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Array not found or empty.");
+ }
+ }
+
+ private string[] GetOptions(SerializedProperty property, string targetArry)
+ {
+ string[] options = null;
+ Object targetObject = property.serializedObject.targetObject;
+ System.Type targetType = targetObject.GetType();
+ System.Reflection.FieldInfo fieldInfo = targetType.GetField(targetArry);
+
+ if (fieldInfo != null)
+ {
+ options = fieldInfo.GetValue(targetObject) as string[];
+ }
+
+ return options;
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ return EditorGUI.GetPropertyHeight(property, label, true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/DropdownFromArrayDrawer.cs.meta b/Editor/Core/Drawers/DropdownFromArrayDrawer.cs.meta
new file mode 100644
index 00000000..d5209d00
--- /dev/null
+++ b/Editor/Core/Drawers/DropdownFromArrayDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: ad31a5019cd88d54c94626d1bbb037aa
\ No newline at end of file
diff --git a/Editor/Core/Drawers/DropdownFromDictionaryDrawer.cs b/Editor/Core/Drawers/DropdownFromDictionaryDrawer.cs
new file mode 100644
index 00000000..17fec49d
--- /dev/null
+++ b/Editor/Core/Drawers/DropdownFromDictionaryDrawer.cs
@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(DropdownFromDictionaryAttribute))]
+ public class DropdownFromDictionaryDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ DropdownFromDictionaryAttribute dropdownAttribute = (DropdownFromDictionaryAttribute)attribute;
+ string[] options = GetOptions(property, dropdownAttribute.dictionaryFieldName);
+
+ if (options != null && options.Length > 0)
+ {
+ if (property.propertyType == SerializedPropertyType.String)
+ {
+ int index = Mathf.Max(0, System.Array.IndexOf(options, property.stringValue));
+ index = EditorGUI.Popup(position, label.text, index, options);
+ property.stringValue = options[index];
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Use DropdownFromDictionary with string.");
+ }
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Dictionary not found or empty.");
+ }
+ }
+
+ private string[] GetOptions(SerializedProperty property, string dictionaryFieldName)
+ {
+ string[] options = null;
+ Object targetObject = property.serializedObject.targetObject;
+ System.Type targetType = targetObject.GetType();
+ System.Reflection.FieldInfo fieldInfo = targetType.GetField(dictionaryFieldName);
+
+ if (fieldInfo != null)
+ {
+ var dictionary = fieldInfo.GetValue(targetObject) as Dictionary;
+ if (dictionary != null)
+ {
+ options = new string[dictionary.Count];
+ dictionary.Keys.CopyTo(options, 0);
+ }
+ }
+
+ return options;
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ return EditorGUI.GetPropertyHeight(property, label, true);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/DropdownFromDictionaryDrawer.cs.meta b/Editor/Core/Drawers/DropdownFromDictionaryDrawer.cs.meta
new file mode 100644
index 00000000..b982d39e
--- /dev/null
+++ b/Editor/Core/Drawers/DropdownFromDictionaryDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: dd4e08a9c9afbc649ba64dc8a002168c
\ No newline at end of file
diff --git a/Editor/Core/Drawers/GlobalEnumDrawer.cs b/Editor/Core/Drawers/GlobalEnumDrawer.cs
new file mode 100644
index 00000000..9c21d5b7
--- /dev/null
+++ b/Editor/Core/Drawers/GlobalEnumDrawer.cs
@@ -0,0 +1,40 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(GlobalEnum))]
+ public class GlobalEnumDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty valueProp = property.FindPropertyRelative("Value");
+ int index = valueProp.intValue;
+
+ if (RM_Editor.TryGetSettingAsset(out ProjectSettingAsset setting))
+ {
+ string[] names = setting.Status.ToArray();
+
+ if (index >= 0 && index < names.Length)
+ {
+ int newIndex = EditorGUI.Popup(position, label.text, index, names);
+ valueProp.intValue = newIndex;
+ }
+ else
+ {
+ Color prev = GUI.color;
+ GUI.color = Color.red;
+ EditorGUI.LabelField(position, $"{label.text} [{index}]: Not Defined!");
+ GUI.color = prev;
+ }
+ }
+ else
+ {
+ Color prev = GUI.color;
+ GUI.color = Color.yellow;
+ EditorGUI.LabelField(position, $"{label.text} [{index}]: Can't load ProjectSettingAsset.");
+ GUI.color = prev;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/GlobalEnumDrawer.cs.meta b/Editor/Core/Drawers/GlobalEnumDrawer.cs.meta
new file mode 100644
index 00000000..2ea542e7
--- /dev/null
+++ b/Editor/Core/Drawers/GlobalEnumDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: b498f42342792244b9f4ab755fd39a70
\ No newline at end of file
diff --git a/Editor/Core/Drawers/HelpBoxDrawer.cs b/Editor/Core/Drawers/HelpBoxDrawer.cs
new file mode 100644
index 00000000..17c6f60e
--- /dev/null
+++ b/Editor/Core/Drawers/HelpBoxDrawer.cs
@@ -0,0 +1,30 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(HelpBoxAttribute))]
+ public class HelpBoxDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ HelpBoxAttribute helpBoxAttribute = (HelpBoxAttribute)attribute;
+ EditorGUI.BeginProperty(position, label, property);
+ // Calculate the height of the help box
+ var helpBoxHeight = EditorGUIUtility.singleLineHeight * helpBoxAttribute.height;
+ var helpBoxRect = new Rect(position.x, position.y, position.width, helpBoxHeight);
+ EditorGUI.HelpBox(helpBoxRect, helpBoxAttribute.text, (MessageType)helpBoxAttribute.messageType);
+ // Calculate the position of the property field
+ var propertyRect = new Rect(position.x, position.y + helpBoxHeight + EditorGUIUtility.standardVerticalSpacing, position.width, EditorGUIUtility.singleLineHeight);
+ EditorGUI.PropertyField(propertyRect, property, label);
+ EditorGUI.EndProperty();
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ HelpBoxAttribute helpBoxAttribute = (HelpBoxAttribute)attribute;
+ var helpBoxHeight = EditorGUIUtility.singleLineHeight * 2;
+ return helpBoxHeight + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/HelpBoxDrawer.cs.meta b/Editor/Core/Drawers/HelpBoxDrawer.cs.meta
new file mode 100644
index 00000000..f9d948e8
--- /dev/null
+++ b/Editor/Core/Drawers/HelpBoxDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 7dc2a9809fb29c84f99cf655165efe0f
\ No newline at end of file
diff --git a/Editor/Core/Drawers/LayerDrawer.cs b/Editor/Core/Drawers/LayerDrawer.cs
new file mode 100644
index 00000000..c65b375f
--- /dev/null
+++ b/Editor/Core/Drawers/LayerDrawer.cs
@@ -0,0 +1,21 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(LayerAttribute))]
+ public class LayerDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ if (property.propertyType == SerializedPropertyType.Integer)
+ {
+ property.intValue = EditorGUI.LayerField(position, label, property.intValue);
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Use [Layer] with int.");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/LayerDrawer.cs.meta b/Editor/Core/Drawers/LayerDrawer.cs.meta
new file mode 100644
index 00000000..626a7fe8
--- /dev/null
+++ b/Editor/Core/Drawers/LayerDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: af5212a855fb5084d898aba471657705
\ No newline at end of file
diff --git a/Editor/Core/Drawers/LineDrawer.cs b/Editor/Core/Drawers/LineDrawer.cs
new file mode 100644
index 00000000..b13c274d
--- /dev/null
+++ b/Editor/Core/Drawers/LineDrawer.cs
@@ -0,0 +1,39 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(LineAttribute))]
+ public class LineDrawer : DecoratorDrawer
+ {
+ public override void OnGUI(Rect position)
+ {
+ // get a reference to the attribute
+ LineAttribute separatorAttribute
+ = attribute as LineAttribute;
+ // define the line to draw
+ Rect separatorRect = new Rect(position.xMin,
+ position.yMin + separatorAttribute.Spacing,
+ position.width,
+ separatorAttribute.Height);
+ // draw it
+ Color lineColor = EditorGUIUtility.isProSkin
+ ? new Color(0.2f, 0.2f, 0.2f, 1)
+ : new Color(0.7f, 0.7f, 0.7f, 1);
+
+ EditorGUI.DrawRect(separatorRect, lineColor);
+ }
+
+ public override float GetHeight()
+ {
+ LineAttribute separatorAttribute
+ = attribute as LineAttribute;
+
+ float totalSpacing = separatorAttribute.Spacing
+ + separatorAttribute.Height
+ + separatorAttribute.Spacing;
+
+ return totalSpacing;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/LineDrawer.cs.meta b/Editor/Core/Drawers/LineDrawer.cs.meta
new file mode 100644
index 00000000..62243d73
--- /dev/null
+++ b/Editor/Core/Drawers/LineDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: e2604c09d5b614044a87657f1f3c6b54
\ No newline at end of file
diff --git a/Editor/Core/Drawers/MinMaxRangeDrawer.cs b/Editor/Core/Drawers/MinMaxRangeDrawer.cs
new file mode 100644
index 00000000..a1ab2628
--- /dev/null
+++ b/Editor/Core/Drawers/MinMaxRangeDrawer.cs
@@ -0,0 +1,51 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(MinMaxRangeAttribute))]
+ public class MinMaxRangeDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ if (property.propertyType == SerializedPropertyType.Vector2)
+ {
+ MinMaxRangeAttribute range = (MinMaxRangeAttribute)attribute;
+
+ Vector2 value = property.vector2Value;
+
+ EditorGUI.BeginProperty(position, label, property);
+
+ // Draw label
+ position = EditorGUI.PrefixLabel(position, label);
+
+ // Draw min-max slider
+ float min = value.x;
+ float max = value.y;
+
+ float sliderWidth = position.width * 0.6f;
+ float fieldWidth = (position.width - sliderWidth) / 2f;
+
+ Rect minFieldRect = new Rect(position.x, position.y, fieldWidth - 2, position.height);
+ Rect sliderRect = new Rect(position.x + fieldWidth, position.y, sliderWidth, position.height);
+ Rect maxFieldRect = new Rect(position.x + fieldWidth + sliderWidth + 2, position.y, fieldWidth - 2, position.height);
+
+ min = EditorGUI.FloatField(minFieldRect, min);
+ EditorGUI.MinMaxSlider(sliderRect, ref min, ref max, range.minLimit, range.maxLimit);
+ max = EditorGUI.FloatField(maxFieldRect, max);
+
+ // Clamp values
+ min = Mathf.Clamp(min, range.minLimit, max);
+ max = Mathf.Clamp(max, min, range.maxLimit);
+
+ property.vector2Value = new Vector2(min, max);
+
+ EditorGUI.EndProperty();
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Use MinMaxRange with Vector2");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/MinMaxRangeDrawer.cs.meta b/Editor/Core/Drawers/MinMaxRangeDrawer.cs.meta
new file mode 100644
index 00000000..b0639726
--- /dev/null
+++ b/Editor/Core/Drawers/MinMaxRangeDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 06fcdbe99bffac94b949f0b3d29aabe7
\ No newline at end of file
diff --git a/Editor/Core/Drawers/Name16Drawer.cs b/Editor/Core/Drawers/Name16Drawer.cs
new file mode 100644
index 00000000..aeb20013
--- /dev/null
+++ b/Editor/Core/Drawers/Name16Drawer.cs
@@ -0,0 +1,49 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(Name16))]
+ public class Name16Drawer : PropertyDrawer
+ {
+ const int MaxLength = 16;
+ static readonly Color Tint = new Color(1f, 0.82f, 0.9f); // very light pink
+
+
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ var aProp = property.FindPropertyRelative("Name_A");
+ var bProp = property.FindPropertyRelative("Name_B");
+
+ Name16 value = new Name16();
+ value.Name_A = (ulong)aProp.longValue;
+ value.Name_B = (ulong)bProp.longValue;
+
+ string text = value.ToString();
+
+ EditorGUI.BeginProperty(position, label, property);
+
+ Color oldColor = GUI.color;
+ GUI.color = Tint; // apply pink tint
+
+ EditorGUI.BeginChangeCheck();
+ string newText = EditorGUI.TextField(position, label, text);
+
+ GUI.color = oldColor; // restore color
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ if (newText.Length > MaxLength)
+ newText = newText.Substring(0, MaxLength);
+
+ Name16 newValue = new Name16(newText);
+
+ aProp.longValue = (long)newValue.Name_A;
+ bProp.longValue = (long)newValue.Name_B;
+ }
+
+ EditorGUI.EndProperty();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/Name16Drawer.cs.meta b/Editor/Core/Drawers/Name16Drawer.cs.meta
new file mode 100644
index 00000000..efbed6d5
--- /dev/null
+++ b/Editor/Core/Drawers/Name16Drawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 2ddcecdd6b6816a40926f6a6d2ac2a9a
\ No newline at end of file
diff --git a/Runtime/Core/Attributes/ListToPopupAttribute.cs b/Editor/Core/Drawers/PopupListDrawer.cs
similarity index 64%
rename from Runtime/Core/Attributes/ListToPopupAttribute.cs
rename to Editor/Core/Drawers/PopupListDrawer.cs
index 86c823d9..b0a93d10 100644
--- a/Runtime/Core/Attributes/ListToPopupAttribute.cs
+++ b/Editor/Core/Drawers/PopupListDrawer.cs
@@ -1,33 +1,16 @@
-using System;
using System.Collections.Generic;
using System.Reflection;
-#if UNITY_EDITOR
using UnityEditor;
-#endif
using UnityEngine;
-namespace RealMethod
+namespace RealMethod.Editor
{
- public class ListToPopupAttribute : PropertyAttribute
- {
- public Type myType;
- public string propertyName;
-
- public ListToPopupAttribute(Type _myType, string _propertyName)
- {
- myType = _myType;
- propertyName = _propertyName;
- }
- }
-
-#if UNITY_EDITOR
-
- [CustomPropertyDrawer(typeof(ListToPopupAttribute))]
- public class ListToPopupDrawer : PropertyDrawer
+ [CustomPropertyDrawer(typeof(PopupListAttribute))]
+ public class PopupListDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
- ListToPopupAttribute atb = attribute as ListToPopupAttribute;
+ PopupListAttribute atb = attribute as PopupListAttribute;
List stringList = null;
// Get the field using reflection
@@ -57,10 +40,4 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
}
}
}
-
-#endif
-}
-// ------------Use
-// [ListToPopup(typeof(ExampleClass), "options")]
-// public string selectedOption;
-// public static List options = new List { "Option1", "Option2", "Option3" };
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/PopupListDrawer.cs.meta b/Editor/Core/Drawers/PopupListDrawer.cs.meta
new file mode 100644
index 00000000..6c9a03b0
--- /dev/null
+++ b/Editor/Core/Drawers/PopupListDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: a289ef88415dda149980554c00cc8cfe
\ No newline at end of file
diff --git a/Editor/Core/Drawers/PrefabCoreDrawer.cs b/Editor/Core/Drawers/PrefabCoreDrawer.cs
new file mode 100644
index 00000000..16ad77ff
--- /dev/null
+++ b/Editor/Core/Drawers/PrefabCoreDrawer.cs
@@ -0,0 +1,78 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(PrefabCore), true)]
+ public class PrefabCore_Drawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty prefabGOProp = property.FindPropertyRelative("PrefabAsset");
+
+ if (prefabGOProp == null)
+ {
+ EditorGUI.LabelField(position, label.text, "Cannot serialize generic prefab");
+ return;
+ }
+
+ EditorGUI.BeginProperty(position, label, property);
+
+ // Determine label text
+ // string displayLabel = prefabGOProp.objectReferenceValue != null ? label.text: $"{label.text} (Select a prefab...)";
+
+ // Draw the ObjectField for GameObject
+ UnityEngine.Object newObject = EditorGUI.ObjectField(
+ position,
+ label,
+ prefabGOProp.objectReferenceValue,
+ typeof(GameObject),
+ false
+ );
+
+ // Only update if changed
+ if (newObject != prefabGOProp.objectReferenceValue)
+ {
+ if (newObject == null)
+ {
+ prefabGOProp.objectReferenceValue = null;
+ }
+ else if (PrefabUtility.IsPartOfPrefabAsset(newObject))
+ {
+ // Get the concrete PrefabCore instance
+ PrefabCore targetPrefab = fieldInfo.GetValue(property.serializedObject.targetObject) as PrefabCore;
+
+ if (targetPrefab == null)
+ {
+ Debug.LogWarning("Invalid prefab wrapper.");
+ return;
+ }
+
+ var targetClass = targetPrefab.GetMainType();
+ GameObject go = newObject as GameObject;
+
+ // Type-check: the prefab must have the required component
+ if (targetClass != null && go.GetComponent(targetClass) != null)
+ {
+ prefabGOProp.objectReferenceValue = newObject;
+ }
+ else
+ {
+ Debug.LogWarning($"Selected prefab does not have required component: {targetClass?.Name}");
+ }
+ }
+ else
+ {
+ Debug.LogWarning("Only prefab assets from the project can be assigned.");
+ }
+ }
+
+ // --- Set GUI color to blue to indicate change ---
+ Color prevColor = GUI.color;
+ GUI.color = Color.cyan; // light blue
+ EditorGUI.ObjectField(position, label, prefabGOProp.objectReferenceValue, typeof(GameObject), false);
+ GUI.color = prevColor;
+ EditorGUI.EndProperty();
+ }
+ }
+}
diff --git a/Editor/Core/Definitions/PrefabDrawer.cs.meta b/Editor/Core/Drawers/PrefabCoreDrawer.cs.meta
similarity index 100%
rename from Editor/Core/Definitions/PrefabDrawer.cs.meta
rename to Editor/Core/Drawers/PrefabCoreDrawer.cs.meta
diff --git a/Editor/Core/Drawers/ReadOnlyDrawer.cs b/Editor/Core/Drawers/ReadOnlyDrawer.cs
new file mode 100644
index 00000000..3d0b1ad8
--- /dev/null
+++ b/Editor/Core/Drawers/ReadOnlyDrawer.cs
@@ -0,0 +1,21 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
+ public class ReadOnlyDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ GUI.enabled = false; // Disable the GUI
+ EditorGUI.PropertyField(position, property, label, true);
+ GUI.enabled = true; // Enable the GUI
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ return EditorGUI.GetPropertyHeight(property, label, true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ReadOnlyDrawer.cs.meta b/Editor/Core/Drawers/ReadOnlyDrawer.cs.meta
new file mode 100644
index 00000000..521007c0
--- /dev/null
+++ b/Editor/Core/Drawers/ReadOnlyDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: d44334cf564e8644e8c743b8e93b2507
\ No newline at end of file
diff --git a/Editor/Core/Drawers/SceneAssetDrawer.cs b/Editor/Core/Drawers/SceneAssetDrawer.cs
new file mode 100644
index 00000000..9df5964f
--- /dev/null
+++ b/Editor/Core/Drawers/SceneAssetDrawer.cs
@@ -0,0 +1,68 @@
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(SceneAsset), true)]
+ public class SceneAssetDrawer : PropertyDrawer
+ {
+ private Texture2D checkIcon;
+ private Texture2D warningIcon;
+
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ // Load icons once
+ if (checkIcon == null) checkIcon = EditorGUIUtility.IconContent("TestPassed").image as Texture2D;
+ if (warningIcon == null) warningIcon = EditorGUIUtility.IconContent("console.warnicon").image as Texture2D;
+
+ SerializedProperty sceneAssetProp = property.FindPropertyRelative("Asset");
+ SerializedProperty scenePathProp = property.FindPropertyRelative("ScenePath");
+
+ EditorGUI.BeginProperty(position, label, property);
+
+ // Restrict to SceneAsset type
+ Rect objectFieldRect = new Rect(position.x, position.y, position.width - 20, position.height);
+ EditorGUI.PropertyField(objectFieldRect, sceneAssetProp, label);
+
+ if (sceneAssetProp.objectReferenceValue != null)
+ {
+ string path = AssetDatabase.GetAssetPath(sceneAssetProp.objectReferenceValue);
+ scenePathProp.stringValue = path;
+
+ bool isInBuild = IsSceneInBuild(path);
+
+ // Icon display
+ Rect iconRect = new Rect(position.x + position.width - 16, position.y + 2, 16, 16);
+ GUI.DrawTexture(iconRect, isInBuild ? checkIcon : warningIcon);
+
+ // Tooltip if not included
+ if (!isInBuild)
+ {
+ GUIContent warningContent = new GUIContent("", "Scene is NOT in the active Build Profile.\nAdd it via File > Build Profiles.");
+ EditorGUI.LabelField(iconRect, warningContent);
+ }
+ }
+ else
+ {
+ scenePathProp.stringValue = string.Empty;
+ }
+
+ EditorGUI.EndProperty();
+ }
+
+ private bool IsSceneInBuild(string scenePath)
+ {
+ for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
+ {
+ string listedScenePath = SceneUtility.GetScenePathByBuildIndex(i);
+ if (listedScenePath == scenePath)
+ return true;
+ }
+ return false;
+ }
+ }
+}
+
+
+
diff --git a/Editor/Core/Drawers/SceneAssetDrawer.cs.meta b/Editor/Core/Drawers/SceneAssetDrawer.cs.meta
new file mode 100644
index 00000000..77fc6bd0
--- /dev/null
+++ b/Editor/Core/Drawers/SceneAssetDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 17b36a74fca686a45a451a08879dfe1c
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ShowOnlyDrawer.cs b/Editor/Core/Drawers/ShowOnlyDrawer.cs
new file mode 100644
index 00000000..58c3bd84
--- /dev/null
+++ b/Editor/Core/Drawers/ShowOnlyDrawer.cs
@@ -0,0 +1,35 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(ShowOnlyAttribute))]
+ public class ShowOnlyDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
+ {
+ string valueStr;
+
+ switch (prop.propertyType)
+ {
+ case SerializedPropertyType.Integer:
+ valueStr = prop.intValue.ToString();
+ break;
+ case SerializedPropertyType.Boolean:
+ valueStr = prop.boolValue.ToString();
+ break;
+ case SerializedPropertyType.Float:
+ valueStr = prop.floatValue.ToString("0.00000");
+ break;
+ case SerializedPropertyType.String:
+ valueStr = prop.stringValue;
+ break;
+ default:
+ valueStr = "(not supported)";
+ break;
+ }
+
+ EditorGUI.LabelField(position, label.text, valueStr);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/ShowOnlyDrawer.cs.meta b/Editor/Core/Drawers/ShowOnlyDrawer.cs.meta
new file mode 100644
index 00000000..17459bec
--- /dev/null
+++ b/Editor/Core/Drawers/ShowOnlyDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 24cc41ec6d04b4344b61e6551c7320ef
\ No newline at end of file
diff --git a/Editor/Core/Drawers/SlugDrawer.cs b/Editor/Core/Drawers/SlugDrawer.cs
new file mode 100644
index 00000000..fe09839f
--- /dev/null
+++ b/Editor/Core/Drawers/SlugDrawer.cs
@@ -0,0 +1,22 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+[CustomPropertyDrawer(typeof(SlugAttribute))]
+public class SlugDrawer : PropertyDrawer
+{
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ SlugAttribute attr = (SlugAttribute)attribute;
+
+ // Draw label normally
+ position = EditorGUI.PrefixLabel(position, label);
+
+ // Shrink width
+ position.width *= attr.WidthScale;
+
+ // Draw the text field
+ EditorGUI.PropertyField(position, property, GUIContent.none);
+ }
+}
+#endif
diff --git a/Editor/Core/Drawers/SlugDrawer.cs.meta b/Editor/Core/Drawers/SlugDrawer.cs.meta
new file mode 100644
index 00000000..fd2254ac
--- /dev/null
+++ b/Editor/Core/Drawers/SlugDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 943d7c0715f903d4fa0b76804a8f7110
\ No newline at end of file
diff --git a/Editor/Core/Drawers/SoftTypeDrawer.cs b/Editor/Core/Drawers/SoftTypeDrawer.cs
new file mode 100644
index 00000000..6108b67b
--- /dev/null
+++ b/Editor/Core/Drawers/SoftTypeDrawer.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(SoftType), true)]
+ public class SoftTypeDrawer : PropertyDrawer
+ {
+ private string[] displayNames;
+ private string[] typeNames;
+ private int currentIndex;
+
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ var typeProp = property.FindPropertyRelative("typeName");
+
+ if (displayNames == null)
+ {
+ Initialize(typeProp);
+ if (displayNames.Length > 0)
+ typeProp.stringValue = typeNames[currentIndex];
+ }
+
+ if (displayNames.Length == 0)
+ {
+ EditorGUI.LabelField(position, label.text, "No class found");
+ return;
+ }
+
+ int newIndex = EditorGUI.Popup(position, label.text, currentIndex, displayNames);
+
+ if (newIndex != currentIndex)
+ {
+ currentIndex = newIndex;
+ typeProp.stringValue = typeNames[newIndex];
+ }
+ }
+
+ private void Initialize(SerializedProperty property)
+ {
+ var baseType = fieldInfo.FieldType.GetGenericArguments()[0];
+
+ var types = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(a => a.GetTypes())
+ .Where(t => baseType.IsAssignableFrom(t) && !t.IsAbstract)
+ .OrderBy(t => t.Name)
+ .ToArray();
+
+ displayNames = types.Select(t => t.Name).ToArray();
+ typeNames = types.Select(t => t.AssemblyQualifiedName).ToArray();
+
+ currentIndex = Array.IndexOf(typeNames, property.stringValue);
+ if (currentIndex < 0) currentIndex = 0;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/SoftTypeDrawer.cs.meta b/Editor/Core/Drawers/SoftTypeDrawer.cs.meta
new file mode 100644
index 00000000..cc5f48ba
--- /dev/null
+++ b/Editor/Core/Drawers/SoftTypeDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 7d22a982c67c68d4aa07c4bc76bb7282
\ No newline at end of file
diff --git a/Editor/Core/Drawers/TagSelectorDrawer.cs b/Editor/Core/Drawers/TagSelectorDrawer.cs
new file mode 100644
index 00000000..f45531da
--- /dev/null
+++ b/Editor/Core/Drawers/TagSelectorDrawer.cs
@@ -0,0 +1,31 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(TagSelectorAttribute))]
+ public class TagSelectorDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ TagSelectorAttribute tagSelector = (TagSelectorAttribute)attribute;
+
+ if (tagSelector.UseDefaultTagFieldDrawer)
+ {
+ EditorGUI.PropertyField(position, property, label);
+ }
+ else
+ {
+ if (property.propertyType == SerializedPropertyType.String)
+ {
+ property.stringValue = EditorGUI.TagField(position, label, property.stringValue);
+ }
+ else
+ {
+ EditorGUI.PropertyField(position, property, label);
+ EditorGUI.HelpBox(position, "TagSelector can only be used with strings.", MessageType.Error);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/TagSelectorDrawer.cs.meta b/Editor/Core/Drawers/TagSelectorDrawer.cs.meta
new file mode 100644
index 00000000..b81f84f2
--- /dev/null
+++ b/Editor/Core/Drawers/TagSelectorDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: c3a11f74a60467949a0aea20cd3c704c
\ No newline at end of file
diff --git a/Editor/Core/Drawers/TypeSelectorDrawer.cs b/Editor/Core/Drawers/TypeSelectorDrawer.cs
new file mode 100644
index 00000000..fdcfa46d
--- /dev/null
+++ b/Editor/Core/Drawers/TypeSelectorDrawer.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(TypeSelectorAttribute))]
+ public class TypeSelectorDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ TypeSelectorAttribute typeSelector = (TypeSelectorAttribute)attribute;
+
+
+ if (property.propertyType == SerializedPropertyType.String)
+ {
+ // Get all types derived from the specified base type
+ Type[] types = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(assembly => assembly.GetTypes())
+ .Where(t => typeSelector.BaseType.IsAssignableFrom(t) && !t.IsAbstract)
+ .ToArray();
+
+ // Get the current type
+ string ClassName = property.stringValue;
+ Type currentType = !string.IsNullOrEmpty(ClassName) ? Type.GetType(ClassName) : null;
+
+ // Get type names for the dropdown
+ string[] typeNames = types.Select(t => t.FullName).ToArray();
+ int currentIndex = Array.IndexOf(typeNames, currentType?.FullName);
+
+ // Show the dropdown in the Inspector
+ int selectedIndex = EditorGUI.Popup(position, label.text, currentIndex, typeNames);
+
+ // Update the selected type
+ if (selectedIndex >= 0 && selectedIndex < types.Length)
+ {
+ property.stringValue = types[selectedIndex].AssemblyQualifiedName;
+ }
+ else
+ {
+ property.stringValue = string.Empty;
+ }
+ }
+ else
+ {
+ EditorGUI.LabelField(position, label.text, "Use TypeSelector with string.");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Drawers/TypeSelectorDrawer.cs.meta b/Editor/Core/Drawers/TypeSelectorDrawer.cs.meta
new file mode 100644
index 00000000..7ee35387
--- /dev/null
+++ b/Editor/Core/Drawers/TypeSelectorDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: bbe6e5799205f324690a4af7e1a541d0
\ No newline at end of file
diff --git a/Editor/Core/Definitions.meta b/Editor/Core/InitializeOnLoad.meta
similarity index 77%
rename from Editor/Core/Definitions.meta
rename to Editor/Core/InitializeOnLoad.meta
index ff7fd276..6c8fe827 100644
--- a/Editor/Core/Definitions.meta
+++ b/Editor/Core/InitializeOnLoad.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 04563dc2f2c64684c987eb7ddde21c3d
+guid: efad1f04ce1244c449edfa22bfb8686f
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Editor/Core/InitializeOnLoad/CompileGuard.cs b/Editor/Core/InitializeOnLoad/CompileGuard.cs
new file mode 100644
index 00000000..3a0cd574
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/CompileGuard.cs
@@ -0,0 +1,249 @@
+using UnityEditor;
+using UnityEditor.Compilation;
+using System;
+using UnityEngine;
+
+
+namespace RealMethod.Editor
+{
+ ///
+ /// Base class for creating custom compile-time or editor-time validation rules.
+ /// Rules are instantiated by CompileGuard and triggered automatically depending
+ /// on the selected .
+ ///
+ public abstract class CompileRule
+ {
+ ///
+ /// Defines when a should be executed by .
+ /// This controls which editor event triggers the rule validation.
+ ///
+ public enum RuleExecutionMode
+ {
+ ///
+ /// Rule runs after Unity finishes compiling scripts.
+ /// Triggered by .
+ /// Useful for validating code structure or assets after compilation.
+ ///
+ AfterCompilation = 0,
+ ///
+ /// Rule runs on the editor update loop after the editor loads.
+ /// Triggered using .
+ /// Useful for checks that should occur once the editor is ready.
+ ///
+ EditorStartup = 1,
+ ///
+ /// Rule runs after the editor has fully returned to Edit Mode.
+ /// The editor is back to its normal editing state.
+ ///
+ EnteredEditMode = 2,
+ ///
+ /// Rule runs when the editor is about to leave Edit Mode and start entering Play Mode.
+ /// This happens before Play Mode is fully active.
+ ///
+ ExitingEditMode = 3,
+ ///
+ /// Rule runs after the editor has fully entered Play Mode.
+ /// Game logic is now running.
+ ///
+ EnteredPlayMode = 4,
+ ///
+ /// Rule runs when the editor is about to stop Play Mode and return to Edit Mode.
+ /// Game execution is shutting down.
+ ///
+ ExitingPlayMode = 5,
+ }
+
+
+ public CompileRule()
+ {
+ Initilized();
+ }
+
+
+ ///
+ /// Called automatically right after the rule is constructed.
+ /// Use this to initialize internal data, cache values, or set up
+ /// anything needed before the rule is used by CompileGuard.
+ ///
+ protected abstract void Initilized();
+ ///
+ /// Performs rule initialization for the specified execution mode.
+ /// This method is called once per mode before any type scanning or rule checks begin.
+ /// Use it to reset internal state, prepare data, or configure the rule
+ ///
+ /// The execution mode for the current validation pass.
+ public abstract void OnStartCheck(RuleExecutionMode mode);
+ ///
+ /// Determines whether this rule can perform a check using the specified
+ /// execution mode and target type. Override this method in derived classes
+ /// to define which modes and types the rule supports.
+ ///
+ /// The rule execution mode being requested.
+ /// The target data type to evaluate.
+ ///
+ /// True if the rule can check the given mode and type; otherwise, false.
+ ///
+ public abstract bool CanCheck(RuleExecutionMode mode, Type type);
+ ///
+ /// Called when CompileGuard finds a type that inherits from the rule's base type.
+ /// Implement validation logic here. This method is invoked automatically for each
+ /// matching type during the selected rule mode.
+ ///
+ ///
+ /// The discovered type that matches .
+ ///
+ public abstract void OnCheck(Type type);
+ }
+
+
+ [InitializeOnLoad]
+ ///
+ /// Central system that discovers and executes all CompileRule instances.
+ /// It triggers rules during compilation or editor updates depending on their mode,
+ /// and passes every project type that matches the rule's base type.
+ ///
+ public static class CompileGuard
+ {
+ private static ProjectSettingAsset ProjectSetting_Cache;
+ private static ProjectSettingAsset ProjectSetting
+ {
+ get
+ {
+ if (ProjectSetting_Cache == null)
+ {
+ if (!RM_Editor.TryGetSettingAsset(out ProjectSetting_Cache))
+ {
+ return null;
+ }
+ }
+ return ProjectSetting_Cache;
+ }
+ }
+ private static System.Reflection.Assembly[] Assemblies;
+ private static CompileRule[] Rules;
+ private static bool initialized;
+
+ public static readonly Type[] DefaultRuls = new Type[4] {
+ // Array of ruls to that should be run always for RealMethod
+ typeof(ConfigAssetsRule),
+ typeof(ServiceRule),
+ typeof(PrimitveAssetsRule),
+ typeof(PureRule),
+ };
+
+
+ static CompileGuard()
+ {
+ if (!ProjectSetting.CanCompile())
+ {
+ return;
+ }
+
+ if (initialized) return;
+ initialized = true;
+
+ CompilationPipeline.compilationFinished += OnCompilationFinished;
+ EditorApplication.delayCall += OnEditorUpdated;
+ EditorApplication.playModeStateChanged += OnPlayModeChanged;
+ }
+
+ private static void OnCompilationFinished(object obj)
+ {
+ CheckRuls(CompileRule.RuleExecutionMode.AfterCompilation);
+ }
+ private static void OnEditorUpdated()
+ {
+ CheckRuls(CompileRule.RuleExecutionMode.EditorStartup);
+ }
+ private static void OnPlayModeChanged(PlayModeStateChange state)
+ {
+ int index = (int)state + 2;
+ CheckRuls((CompileRule.RuleExecutionMode)index);
+ }
+
+
+ // Checking process
+ private static void CheckRuls(CompileRule.RuleExecutionMode mode)
+ {
+ if (ProjectSetting == null)
+ return;
+
+
+ if (Rules == null)
+ {
+ Type[] RulsClass = ProjectSetting.GetCompileRules();
+ if (RulsClass == null)
+ {
+ Debug.LogError($"ProjectSetting didn't have Compilerule but compileguard is enable");
+ return;
+ }
+
+ Rules = new CompileRule[RulsClass.Length];
+ for (int i = 0; i < RulsClass.Length; i++)
+ {
+ if (RulsClass[i] == null)
+ continue;
+
+ if (typeof(CompileRule).IsAssignableFrom(RulsClass[i]))
+ {
+ try
+ {
+ Rules[i] = (CompileRule)Activator.CreateInstance(RulsClass[i]);
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError($"Failed to instantiate {RulsClass[i]}: {ex.Message}.");
+ return;
+ }
+ }
+ else
+ {
+ Debug.LogError($"Type {RulsClass[i]} is not assignable to CompileRule.");
+ return;
+ }
+ }
+ }
+
+
+ if (Assemblies == null)
+ {
+ Assemblies = AppDomain.CurrentDomain.GetAssemblies();
+ }
+
+ // StartMode
+ foreach (var rule in Rules)
+ {
+ rule.OnStartCheck(mode);
+ }
+
+ // Checking
+ Type[] types;
+ foreach (var assembly in Assemblies)
+ {
+ try
+ {
+ types = assembly.GetTypes();
+ }
+ catch
+ {
+ continue;
+ }
+
+ foreach (var type in types)
+ {
+ foreach (var rule in Rules)
+ {
+ if (rule == null)
+ continue;
+ if (rule.CanCheck(mode, type) == false)
+ continue;
+
+ rule.OnCheck(type);
+ }
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/Editor/Core/InitializeOnLoad/CompileGuard.cs.meta b/Editor/Core/InitializeOnLoad/CompileGuard.cs.meta
new file mode 100644
index 00000000..169716b0
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/CompileGuard.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 7177b9c29b1bfdf4998168fa58642b35
\ No newline at end of file
diff --git a/Editor/Core/InitializeOnLoad/Rules.meta b/Editor/Core/InitializeOnLoad/Rules.meta
new file mode 100644
index 00000000..553a751e
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 24f3441ca9697e34f926a8ca3105ac53
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Core/InitializeOnLoad/Rules/ConfigAssetsRule.cs b/Editor/Core/InitializeOnLoad/Rules/ConfigAssetsRule.cs
new file mode 100644
index 00000000..0b0fc2c5
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules/ConfigAssetsRule.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+
+ public class ConfigAssetsRule : CompileRule
+ {
+ // CompileRule Methods
+ protected override void Initilized()
+ {
+ }
+ public override void OnStartCheck(RuleExecutionMode mode)
+ {
+ }
+ public override bool CanCheck(RuleExecutionMode mode, Type type)
+ {
+ if (mode == RuleExecutionMode.EditorStartup)
+ {
+ return type.IsSubclassOf(typeof(ConfigAsset));
+ }
+ else
+ {
+ return false;
+ }
+ }
+ public override void OnCheck(Type type)
+ {
+ // 🔹 Check fields
+ var badFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
+ .Where(f => !f.IsInitOnly && !f.IsLiteral && !f.IsDefined(typeof(SerializeField), false))
+ .ToList();
+
+ foreach (var f in badFields)
+ {
+ Debug.LogError($"❌ '{type.Name}' has non-readonly field '{f.Name}' — only readonly fields allowed in Config-derived classes.");
+ }
+
+ // 🔹 Check methods
+ var badMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
+ .Where(m => !m.IsSpecialName && !m.IsConstructor)
+ .Where(m => ViolatesPureMethodRules(m))
+ .ToList();
+
+ foreach (var m in badMethods)
+ {
+ Debug.LogError($"❌ '{type.Name}' public method '{m.Name}' modifies state — only pure getter/return methods are allowed in Config-derived classes.");
+ }
+ }
+
+
+ // Functions
+ private bool ViolatesPureMethodRules(MethodInfo method)
+ {
+ try
+ {
+ var body = method.GetMethodBody();
+ if (body == null)
+ return false;
+
+ var il = body.GetILAsByteArray();
+ if (il == null)
+ return false;
+
+ // Look for IL opcodes that store data or call setters
+ for (int i = 0; i < il.Length - 1; i++)
+ {
+ byte b = il[i];
+ byte next = il[i + 1];
+
+ // Store field (stfld or stsfld)
+ if (b == 0x7D || b == 0x80)
+ return true;
+
+ // Callvirt / call that might be setter
+ if (b == 0x28)
+ {
+ var tokens = method.Module.ResolveMethod(BitConverter.ToInt32(il, i + 1));
+ if (tokens.Name.StartsWith("set_", StringComparison.Ordinal))
+ return true;
+ }
+ }
+ }
+ catch
+ {
+ // Ignore methods that can't be inspected
+ }
+
+ return false;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Definitions/ConfigAssetValidator.cs.meta b/Editor/Core/InitializeOnLoad/Rules/ConfigAssetsRule.cs.meta
similarity index 100%
rename from Editor/Core/Definitions/ConfigAssetValidator.cs.meta
rename to Editor/Core/InitializeOnLoad/Rules/ConfigAssetsRule.cs.meta
diff --git a/Editor/Core/InitializeOnLoad/Rules/GameModuleRule.cs b/Editor/Core/InitializeOnLoad/Rules/GameModuleRule.cs
new file mode 100644
index 00000000..49953099
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules/GameModuleRule.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Reflection;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public class ServiceRule : CompileRule
+ {
+ // CompileRule Methods
+ protected override void Initilized()
+ {
+
+ }
+ public override void OnStartCheck(RuleExecutionMode mode)
+ {
+ }
+ public override bool CanCheck(RuleExecutionMode mode, Type type)
+ {
+ if (mode == RuleExecutionMode.AfterCompilation)
+ {
+ return type.IsSubclassOf(typeof(GameModule));
+ }
+ else
+ {
+ return false;
+ }
+ }
+ public override void OnCheck(Type type)
+ {
+ // Check if class is static
+ if (type.IsAbstract && type.IsSealed)
+ {
+ Debug.LogError($"{typeof(GameModule).Name} class '{type.FullName}' cannot be static.");
+ return;
+ }
+
+ // Check for static methods
+ var methods = type.GetMethods(
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Static |
+ BindingFlags.DeclaredOnly
+ );
+
+ foreach (var method in methods)
+ {
+ if (method.IsStatic)
+ {
+ Debug.LogError($"Module '{type.FullName}' contains static method '{method.Name}'. Static methods are not allowed in module classes.");
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/InitializeOnLoad/Rules/GameModuleRule.cs.meta b/Editor/Core/InitializeOnLoad/Rules/GameModuleRule.cs.meta
new file mode 100644
index 00000000..db007c21
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules/GameModuleRule.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: d5ced9cc83a3eaa4bbf313a3a3c0d44c
\ No newline at end of file
diff --git a/Editor/Core/InitializeOnLoad/Rules/PrimitveAssetsRule.cs b/Editor/Core/InitializeOnLoad/Rules/PrimitveAssetsRule.cs
new file mode 100644
index 00000000..8bdace9d
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules/PrimitveAssetsRule.cs
@@ -0,0 +1,55 @@
+using System;
+using UnityEngine;
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ public class PrimitveAssetsRule : CompileRule
+ {
+ private PrimitiveAsset[] assets = null;
+
+ protected override void Initilized()
+ {
+ assets = Resources.FindObjectsOfTypeAll();
+ }
+ public override void OnStartCheck(RuleExecutionMode mode)
+ {
+ if ((int)mode < 2)
+ return;
+
+ PlayModeStateChange CurrentMode = (PlayModeStateChange)((int)mode - 2);
+ foreach (var asset in assets)
+ {
+ if (mode == RuleExecutionMode.EnteredPlayMode)
+ {
+ if (asset is not DataAsset)
+ asset.SendMessage(FunctionNames.AssetPermission, SendMessageOptions.RequireReceiver);
+
+ // if (AssetDatabase.Contains(asset))
+ // {
+ // if (asset is FileAsset)
+ // {
+ // Debug.LogWarning($"InstanceAsset '{asset.name}' is used directly in Play Mode. " +
+ // $"A runtime instanceAsset should be used instead.Create() at runtime",
+ // asset);
+ // }
+ // }
+ }
+
+ if (asset.AutoReset(CurrentMode))
+ {
+ asset.SendMessage(FunctionNames.Reset, SendMessageOptions.RequireReceiver);
+ }
+ }
+ }
+ public override bool CanCheck(RuleExecutionMode mode, Type type)
+ {
+ return false;
+ }
+ public override void OnCheck(Type type)
+ {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/InitializeOnLoad/Rules/PrimitveAssetsRule.cs.meta b/Editor/Core/InitializeOnLoad/Rules/PrimitveAssetsRule.cs.meta
new file mode 100644
index 00000000..c7a5b4ed
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules/PrimitveAssetsRule.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 83de4f43792a7cd4bb82451acfff8360
\ No newline at end of file
diff --git a/Editor/Core/InitializeOnLoad/Rules/PureRule.cs b/Editor/Core/InitializeOnLoad/Rules/PureRule.cs
new file mode 100644
index 00000000..57bda237
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules/PureRule.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Reflection;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public class PureRule : CompileRule
+ {
+ // CompileRule MEthods
+ protected override void Initilized()
+ {
+ throw new NotImplementedException();
+ }
+ public override void OnStartCheck(RuleExecutionMode mode)
+ {
+ }
+ public override bool CanCheck(RuleExecutionMode mode, Type type)
+ {
+ if (mode == RuleExecutionMode.AfterCompilation)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ public override void OnCheck(Type type)
+ {
+ foreach (var method in type.GetMethods(
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.Static |
+ BindingFlags.DeclaredOnly))
+ {
+ // Ignore methods without PureAttribute
+ if (!method.IsDefined(typeof(PureAttribute), false))
+ continue;
+
+ // Check the calls inside the method
+ if (!IsMethodPure(method))
+ {
+ Debug.LogError(
+ $"PURE METHOD VIOLATION in {type.FullName}.{method.Name}():\n" +
+ $"→ This method is marked [Pure] but calls an impure method!"
+ );
+ }
+ }
+ }
+
+
+ private bool IsMethodPure(MethodInfo method)
+ {
+ var body = method.GetMethodBody();
+ if (body == null)
+ return true;
+
+ var il = body.GetILAsByteArray();
+ int pos = 0;
+
+ while (pos < il.Length)
+ {
+ byte op = il[pos];
+
+ // CALL or CALLVIRT opcodes
+ if (op == 0x28 || op == 0x6F)
+ {
+ int metadataToken = BitConverter.ToInt32(il, pos + 1);
+ var called = method.Module.ResolveMethod(metadataToken) as MethodInfo;
+
+ if (called != null)
+ {
+ // If called method is not marked [Pure] → error
+ if (!called.IsDefined(typeof(PureAttribute), false))
+ return false;
+ }
+ }
+
+ pos++;
+ }
+
+ return true;
+ }
+ private bool IsPure(MethodInfo method)
+ {
+ // 1. Explicitly marked as pure
+ if (method.GetCustomAttribute() != null)
+ return true;
+
+ // 2. Implicit analysis
+ return IsMethodImplicitlyPure(method);
+ }
+ private bool IsMethodImplicitlyPure(MethodInfo method)
+ {
+ // Any setter = NOT pure
+ if (method.IsSpecialName && method.Name.StartsWith("set_"))
+ return false;
+
+ // Inspect instructions (Cecil would be ideal, but unavailable at runtime)
+ // Simple heuristic: if method writes to fields, it's impure
+ var body = method.GetMethodBody();
+ if (body == null)
+ return true; // e.g., extern methods are assumed pure
+
+ var il = body.GetILAsByteArray();
+
+ // Look for IL opcodes that indicate mutation
+ // stfld = write to field
+ // stsfld = write to static field
+ // call/set = property setter
+ // callvirt = method call (we check purity recursively)
+
+ for (int i = 0; i < il.Length; i++)
+ {
+ byte code = il[i];
+
+ // stfld or stsfld (field writes)
+ if (code == 0x7D || code == 0x80)
+ return false;
+
+ // call / callvirt: check called method purity
+ if (code == 0x28 || code == 0x6F)
+ {
+ // Read metadata token
+ int token = BitConverter.ToInt32(il, i + 1);
+ var calledMethod = method.Module.ResolveMethod(token) as MethodInfo;
+
+ if (calledMethod == null)
+ continue;
+
+ // If called method is not pure => this method is impure
+ if (!IsPure(calledMethod))
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/InitializeOnLoad/Rules/PureRule.cs.meta b/Editor/Core/InitializeOnLoad/Rules/PureRule.cs.meta
new file mode 100644
index 00000000..108444b9
--- /dev/null
+++ b/Editor/Core/InitializeOnLoad/Rules/PureRule.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 14a6add6319d3c04e824d67efc811507
\ No newline at end of file
diff --git a/Editor/Core/Inspectors.meta b/Editor/Core/Inspectors.meta
new file mode 100644
index 00000000..cea3ae1e
--- /dev/null
+++ b/Editor/Core/Inspectors.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3b4a83e7828d63e4e893cb8244c6a31f
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Core/Inspectors/ButtonEditor.cs b/Editor/Core/Inspectors/ButtonEditor.cs
new file mode 100644
index 00000000..a3c8599d
--- /dev/null
+++ b/Editor/Core/Inspectors/ButtonEditor.cs
@@ -0,0 +1,30 @@
+using UnityEditor;
+using UnityEngine;
+using System.Linq;
+using System.Reflection;
+
+
+namespace RealMethod.Editor
+{
+ [CustomEditor(typeof(MonoBehaviour), true)]
+ public class ButtonDrawer : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+
+ var targetType = target.GetType();
+ var methods = targetType
+ .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
+ .Where(m => m.GetCustomAttribute() != null && m.GetParameters().Length == 0);
+
+ foreach (var method in methods)
+ {
+ if (GUILayout.Button(method.Name))
+ {
+ method.Invoke(target, null);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Inspectors/ButtonEditor.cs.meta b/Editor/Core/Inspectors/ButtonEditor.cs.meta
new file mode 100644
index 00000000..25039171
--- /dev/null
+++ b/Editor/Core/Inspectors/ButtonEditor.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: b9640b8b2e43dc0419208f4283f8aa82
\ No newline at end of file
diff --git a/Editor/Core/Inspectors/GameEditor.cs b/Editor/Core/Inspectors/GameEditor.cs
new file mode 100644
index 00000000..d34379a5
--- /dev/null
+++ b/Editor/Core/Inspectors/GameEditor.cs
@@ -0,0 +1,57 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomEditor(typeof(Game), true)]
+ public class GameEditor : UnityEditor.Editor
+ {
+ private Game Comp;
+ private string WorldName => Game.World != null ? Game.World.GetType().Name : "World Not Valid";
+ private string BridgeName => Game.Bridge != null ? Game.Bridge.GetType().Name : "GameBridge Not Valid";
+ private string ConfigName => Game.Config != null ? Game.Config.GetType().Name : "GameConfig Not Valid";
+ private IInspectorInfo[] InfoList;
+ private bool[] FoldoutList;
+
+ private void OnEnable()
+ {
+ Comp = (Game)target;
+ InfoList = Comp.GetAllInfo();
+ FoldoutList = new bool[InfoList.Length];
+ }
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+ EditorGUILayout.Space();
+ if (Comp != null)
+ {
+ EditorGUILayout.LabelField($"{WorldName} | {BridgeName} | {ConfigName}");
+ EditorGUILayout.LabelField($"GameStat: {Game.State}");
+ EditorGUILayout.LabelField($"----------------------------------------({InfoList.Length})----------------------------------------");
+ if (InfoList != null)
+ {
+ for (int i = 0; i < InfoList.Length; i++)
+ {
+ IInspectorInfo info = InfoList[i];
+ if (info == null)
+ continue;
+
+ FoldoutList[i] = EditorGUILayout.Foldout(FoldoutList[i], $"{i + 1}. {info.GetTitleInfo()}", true, EditorStyles.foldoutHeader);
+ if (FoldoutList[i])
+ {
+ GUIStyle style = new GUIStyle(EditorStyles.label);
+ style.wordWrap = true;
+ EditorGUILayout.LabelField(info.GetInfo(), style);
+ }
+ }
+ }
+
+ }
+ }
+
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/Editor/Core/Architecture/GameCompWindow.cs.meta b/Editor/Core/Inspectors/GameEditor.cs.meta
similarity index 100%
rename from Editor/Core/Architecture/GameCompWindow.cs.meta
rename to Editor/Core/Inspectors/GameEditor.cs.meta
diff --git a/Editor/Core/Inspectors/MonoBehaviourEditor.cs b/Editor/Core/Inspectors/MonoBehaviourEditor.cs
new file mode 100644
index 00000000..228d054d
--- /dev/null
+++ b/Editor/Core/Inspectors/MonoBehaviourEditor.cs
@@ -0,0 +1,15 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ ///
+ /// Required for the fetching of a default editor on MonoBehaviour objects.
+ ///
+ [CanEditMultipleObjects]
+ [CustomEditor(typeof(MonoBehaviour), true)]
+ public class MonoBehaviourEditor : UnityEditor.Editor
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/Inspectors/MonoBehaviourEditor.cs.meta b/Editor/Core/Inspectors/MonoBehaviourEditor.cs.meta
new file mode 100644
index 00000000..36acbb49
--- /dev/null
+++ b/Editor/Core/Inspectors/MonoBehaviourEditor.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 5d107c809858e504f9c8f63b13101d7c
\ No newline at end of file
diff --git a/Editor/Core/Inspectors/PrimitiveAssetEditor.cs b/Editor/Core/Inspectors/PrimitiveAssetEditor.cs
new file mode 100644
index 00000000..fe8ec347
--- /dev/null
+++ b/Editor/Core/Inspectors/PrimitiveAssetEditor.cs
@@ -0,0 +1,11 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ ///
+ /// Required for the fetching of a default editor on ScriptableObject objects.
+ ///
+ [CanEditMultipleObjects]
+ [CustomEditor(typeof(PrimitiveAsset), true)]
+ public class PrimitiveAssetEditor : UnityEditor.Editor { }
+}
\ No newline at end of file
diff --git a/Editor/Core/Inspectors/PrimitiveAssetEditor.cs.meta b/Editor/Core/Inspectors/PrimitiveAssetEditor.cs.meta
new file mode 100644
index 00000000..78ce2527
--- /dev/null
+++ b/Editor/Core/Inspectors/PrimitiveAssetEditor.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 9da63613ae73be84aac196a150fc3fa2
\ No newline at end of file
diff --git a/Editor/Core/Definitions/DataAssetEditor.cs b/Editor/Core/Inspectors/ScriptableObjectEditor.cs
similarity index 92%
rename from Editor/Core/Definitions/DataAssetEditor.cs
rename to Editor/Core/Inspectors/ScriptableObjectEditor.cs
index 2ee63d0b..c28f3177 100644
--- a/Editor/Core/Definitions/DataAssetEditor.cs
+++ b/Editor/Core/Inspectors/ScriptableObjectEditor.cs
@@ -1,10 +1,9 @@
-#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
namespace RealMethod.Editor
{
- public class DataAssetEditor : UnityEditor.Editor
+ public class ScriptableObjectEditor : UnityEditor.Editor
{
public static void DrawCompleteScriptableObjectEditor(string name, ref T settings, ref bool foldout, ref UnityEditor.Editor editor) where T : ScriptableObject
{
@@ -23,5 +22,4 @@ public static void DrawSubEditor (Object settings, ref bool foldout, ref UnityEd
}
}
}
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/Editor/Core/Definitions/DataAssetEditor.cs.meta b/Editor/Core/Inspectors/ScriptableObjectEditor.cs.meta
similarity index 100%
rename from Editor/Core/Definitions/DataAssetEditor.cs.meta
rename to Editor/Core/Inspectors/ScriptableObjectEditor.cs.meta
diff --git a/Editor/Core/MenuItem.meta b/Editor/Core/MenuItem.meta
new file mode 100644
index 00000000..0bb4c4dc
--- /dev/null
+++ b/Editor/Core/MenuItem.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ffc42bc08d097ab468267973c58637fd
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Core/MenuItem/CoreMenu.cs b/Editor/Core/MenuItem/CoreMenu.cs
new file mode 100644
index 00000000..3019d2c7
--- /dev/null
+++ b/Editor/Core/MenuItem/CoreMenu.cs
@@ -0,0 +1,115 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ class CoreMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Core;
+
+
+ ///////////// GameObject \\\\\\\\\\\\
+ [MenuItem(RM_Editor.GameObjectMenuItemPath + "PlayerStarter", false, 1)]
+ static void CreatePlayerStarter(MenuCommand menuCommand)
+ {
+ // Create a new GameObject
+ GameObject go = new GameObject("PlayerStarter");
+
+ // Optional: add components
+ go.AddComponent();
+
+ // Place it in the scene, parented if needed
+ GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
+
+ // Register the creation in Undo system (so Ctrl+Z works)
+ Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
+
+ // Select the new GameObject
+ Selection.activeObject = go;
+ }
+ [MenuItem(RM_Editor.GameObjectMenuItemPath + "World", false, 1)]
+ static void CreateWorld(MenuCommand menuCommand)
+ {
+ // Create a new GameObject
+ GameObject go = new GameObject("World");
+
+ // Optional: add components
+ go.AddComponent();
+
+ // Place it in the scene, parented if needed
+ GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
+
+ // Register the creation in Undo system (so Ctrl+Z works)
+ Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
+
+ // Select the new GameObject
+ Selection.activeObject = go;
+ }
+
+
+ ////////////// Scripts \\\\\\\\\\\\
+ // Essentials
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Essential/Game", false, RM_Editor.MenuOrder.Essential_Head)]
+ public static void CreateGameClass()
+ {
+ RM_Editor.CreateScriptTemplate("Game", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Essential/World", false, RM_Editor.MenuOrder.Essential_Body)]
+ public static void CreateWorld()
+ {
+ RM_Editor.CreateScriptTemplate("World", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Essential/GameBridge", false, RM_Editor.MenuOrder.Essential_Body)]
+ public static void CreateGameBridgeClass()
+ {
+ RM_Editor.CreateScriptTemplate("GameBridge", MenuLayer);
+ }
+ // Managers
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/EmptyManager", false, RM_Editor.MenuOrder.Manager_Head)]
+ public static void CreateManager()
+ {
+ RM_Editor.CreateScriptTemplate("Manager", MenuLayer);
+ }
+ // Services
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Service/EmptyService", false, RM_Editor.MenuOrder.Service_Head)]
+ public static void CreateService()
+ {
+ RM_Editor.CreateScriptTemplate("Service", MenuLayer);
+ }
+ // Assets
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Data/EmptyDataAsset", false, RM_Editor.MenuOrder.DataAsset_Head)]
+ public static void CreateDataAsset()
+ {
+ RM_Editor.CreateScriptTemplate("DataAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Clone/EmptyCloneAsset", false, RM_Editor.MenuOrder.CloneAsset_Head)]
+ public static void CreateCloneAsset()
+ {
+ RM_Editor.CreateScriptTemplate("CloneAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Unique/EmptyUniqueAsset", false, RM_Editor.MenuOrder.UniqueAsset_Head)]
+ public static void CreateUniqueAsset()
+ {
+ RM_Editor.CreateScriptTemplate("UniqueAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Config/EmptyConfigAsset", false, RM_Editor.MenuOrder.ConfigAsset_Head)]
+ public static void CreateConfigAsset()
+ {
+ RM_Editor.CreateScriptTemplate("ConfigAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Config/Game", false, RM_Editor.MenuOrder.ConfigAsset_Body)]
+ public static void CreateGameConfig()
+ {
+ RM_Editor.CreateScriptTemplate("GameConfig", MenuLayer);
+ }
+ // Editor
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Editor/CompileRule", false, RM_Editor.MenuOrder.Editor)]
+ public static void CreateCompileRule()
+ {
+ RM_Editor.CreateScriptTemplate("CompileRule", MenuLayer);
+ }
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/MenuItem/CoreMenu.cs.meta b/Editor/Core/MenuItem/CoreMenu.cs.meta
new file mode 100644
index 00000000..1c9ed7a0
--- /dev/null
+++ b/Editor/Core/MenuItem/CoreMenu.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: ca9b255b431903b41a6cad7b4423abe6
\ No newline at end of file
diff --git a/Editor/Core/Architecture/AutoWorldExecutionOrder.cs b/Editor/Core/MenuItem/FixupExecutionMenu.cs
similarity index 91%
rename from Editor/Core/Architecture/AutoWorldExecutionOrder.cs
rename to Editor/Core/MenuItem/FixupExecutionMenu.cs
index ab0e17c4..bc530f1b 100644
--- a/Editor/Core/Architecture/AutoWorldExecutionOrder.cs
+++ b/Editor/Core/MenuItem/FixupExecutionMenu.cs
@@ -6,10 +6,9 @@
namespace RealMethod.Editor
{
- //[InitializeOnLoad]
- public static class AutoWorldExecutionOrder
+ public static class FixupExecutionMenu
{
- [MenuItem("Tools/RealMethod/Core/ExecutionOrder" , priority = -1001)]
+ [MenuItem("Tools/RealMethod/Core/FixupExecutionOrder" , priority = -1001)]
static void ApplyExecutionOrder()
{
SetExecutionOrderForDerivedTypes(typeof(World), -18); // ← change base class and order here
diff --git a/Editor/Core/Architecture/AutoWorldExecutionOrder.cs.meta b/Editor/Core/MenuItem/FixupExecutionMenu.cs.meta
similarity index 100%
rename from Editor/Core/Architecture/AutoWorldExecutionOrder.cs.meta
rename to Editor/Core/MenuItem/FixupExecutionMenu.cs.meta
diff --git a/Editor/Core/ProjectSetting.meta b/Editor/Core/ProjectSetting.meta
index 9368b91a..3e26e471 100644
--- a/Editor/Core/ProjectSetting.meta
+++ b/Editor/Core/ProjectSetting.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 9b58be0a7cb56d449a05466c8d147894
+guid: 46009ab07d5815948a8a9bfd68b24f8b
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Editor/Core/ProjectSetting/ProjectSettingProvider.cs b/Editor/Core/ProjectSetting/ProjectSettingProvider.cs
new file mode 100644
index 00000000..373c6d97
--- /dev/null
+++ b/Editor/Core/ProjectSetting/ProjectSettingProvider.cs
@@ -0,0 +1,356 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ // Interface for call base method in ProjectSettingSection by RealMethodSetting
+ interface ISectionSetting
+ {
+ void FirstSelected(ProjectSettingAsset storage);
+ void Draw();
+ bool IsRuntime();
+ }
+ // Abstract base class for a settings section
+ public abstract class ProjectSettingSection : ISectionSetting
+ {
+ protected enum SectionType
+ {
+ Runtime,
+ Editor,
+ }
+ protected class TypeSelector
+ {
+ private SerializedProperty myProperty;
+ private string fieldName;
+ private List typeList;
+ private string[] displayNames;
+ private string[] assemblyNames;
+ private int selectedIndex = 0;
+ private int newIndex;
+
+
+ public TypeSelector(SerializedProperty TargetStringProperty, string displayName)
+ {
+ if (TargetStringProperty != null && displayName != string.Empty)
+ {
+ myProperty = TargetStringProperty;
+ fieldName = displayName;
+ }
+ else
+ {
+ Debug.LogWarning("TypeSelector Can't Create");
+ return;
+ }
+
+
+ typeList = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(a => a.GetTypes())
+ .Where(t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract)
+ .ToList();
+
+ displayNames = typeList.Select(t => $"{t.Namespace}.{t.Name}").ToArray(); // shown in UI
+ assemblyNames = typeList.Select(t => t.AssemblyQualifiedName).ToArray(); // stored
+ }
+
+ public void Draw()
+ {
+ selectedIndex = Array.IndexOf(assemblyNames, myProperty.stringValue);
+
+ newIndex = EditorGUILayout.Popup(fieldName, selectedIndex, displayNames);
+
+ if (newIndex >= 0 && newIndex < assemblyNames.Length)
+ {
+ myProperty.stringValue = assemblyNames[newIndex];
+ }
+ }
+ }
+ protected class ArrayTypeSelector
+ {
+ protected SerializedProperty myProperty;
+ private string fieldName;
+ private List typeList;
+ private string[] displayNames;
+ private string[] assemblyNames;
+ private int selectedIndex = 0;
+ private int newIndex;
+ private readonly int EnforceDisable = -1;
+
+
+ public ArrayTypeSelector(SerializedProperty TargetStringProperty, string displayName)
+ {
+ if (TargetStringProperty != null && displayName != string.Empty)
+ {
+ myProperty = TargetStringProperty;
+ fieldName = displayName;
+ }
+ else
+ {
+ Debug.LogWarning("TypeSelector Can't Create");
+ return;
+ }
+
+ typeList = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(a => a.GetTypes())
+ .Where(t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract)
+ .ToList();
+
+ displayNames = typeList.Select(t => $"{t.Namespace}.{t.Name}").ToArray(); // shown in UI
+ assemblyNames = typeList.Select(t => t.AssemblyQualifiedName).ToArray(); // stored
+
+ EnforceDisable = GetEnforceDisableIndex();
+ }
+ public void Draw()
+ {
+ if (!myProperty.isArray)
+ return;
+
+ if(myProperty.arraySize < EnforceDisable)
+ {
+ myProperty.ClearArray();
+ }
+
+ if(myProperty.arraySize == 0)
+ {
+ DefaultInitiation();
+ }
+
+ for (int i = 0; i < myProperty.arraySize; i++)
+ {
+ EditorGUILayout.BeginHorizontal();
+
+ SerializedProperty element = myProperty.GetArrayElementAtIndex(i);
+ selectedIndex = Array.IndexOf(assemblyNames, element.stringValue);
+
+ if (i < EnforceDisable)
+ GUI.enabled = false;
+
+ newIndex = EditorGUILayout.Popup(fieldName, selectedIndex, displayNames);
+ if (newIndex >= 0 && newIndex < assemblyNames.Length)
+ {
+ element.stringValue = assemblyNames[newIndex];
+ }
+
+ GUI.enabled = true;
+
+ // Prevent removing first two elements
+ if (i >= EnforceDisable)
+ {
+ if (GUILayout.Button("Remove", GUILayout.Width(70)))
+ {
+ myProperty.DeleteArrayElementAtIndex(i);
+ }
+ }
+ else
+ {
+ GUI.enabled = false;
+ GUILayout.Button("Locked", GUILayout.Width(70));
+ GUI.enabled = true;
+ }
+
+ EditorGUILayout.EndHorizontal();
+
+ }
+
+ GUILayout.Space(10);
+
+ if (GUILayout.Button("Add New"))
+ {
+ myProperty.InsertArrayElementAtIndex(myProperty.arraySize);
+ }
+
+ }
+
+
+ protected virtual int GetEnforceDisableIndex()
+ {
+ return -1;
+ }
+ protected virtual void DefaultInitiation()
+ {
+
+ }
+ }
+
+ private bool isReady = true;// Indicates whether the section is ready to render
+ private string message = string.Empty;// Error message to display if the section is not ready
+ private int errorid = 0;// Error ID to identify the type of error
+
+ public ProjectSettingSection()
+ {
+ Initialized();
+ }
+
+ // Implement ISectionSetting Interface
+ void ISectionSetting.FirstSelected(ProjectSettingAsset storage)
+ {
+ BeginRender(storage);
+ }
+ void ISectionSetting.Draw()
+ {
+ EditorGUILayout.Space();
+ EditorGUILayout.LabelField($"{GetTitle()} ({GetSectionType()})", EditorStyles.boldLabel); // Section Title
+
+ if (isReady)
+ {
+ // Render the section's content
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ UpdateRender();
+ EditorGUILayout.EndVertical();
+ }
+ else
+ {
+ // Display an error message if the section is not ready
+ EditorGUILayout.HelpBox(message, MessageType.Error);
+
+ // Provide a "Fix" button to resolve the error
+ if (GUILayout.Button("Fix"))
+ {
+ Fix(errorid);
+ }
+ }
+ }
+ bool ISectionSetting.IsRuntime()
+ {
+ return GetSectionType() == SectionType.Runtime;
+ }
+
+ // Abstract Method
+ protected abstract void Initialized();
+ protected abstract void BeginRender(ProjectSettingAsset Storage);
+ protected abstract void UpdateRender();
+ protected abstract string GetTitle();
+ protected abstract SectionType GetSectionType();
+ protected abstract void Fix(int Id);
+
+ // Protected Function
+ protected void Error(string Message, int Id = 0)
+ {
+ if (isReady)
+ {
+ isReady = false;
+ }
+ message = Message;
+ errorid = Id;
+ }
+ protected void ClearError()
+ {
+ message = string.Empty;
+ errorid = 0;
+ if (!isReady)
+ {
+ isReady = true;
+ }
+ UpdateRender();
+ }
+
+ }
+
+
+
+ // Project Setting
+ public static class ProjectSettingProvider
+ {
+ private static bool candraw = true;// Flag to determine if the UI can be drawn
+ private static ProjectSettingSection[] sections = new ProjectSettingSection[4] {
+ // Array of sections to be rendered in the settings UI
+ new InitializerSettingSection(),
+ new FolderStructureSection(),
+ new GameStatusSection(),
+ new CompileRuleSection(),
+ };
+
+
+ [SettingsProvider]
+ // Create a SettingsProvider for Unity's Project Settings
+ public static SettingsProvider CreateSettingsProvider()
+ {
+ var provider = new SettingsProvider("Project/RealMethod", SettingsScope.Project)
+ {
+ label = "RealMethod",
+
+ // Called when the settings tab is first selected
+ activateHandler = (searchContext, rootElement) =>
+ {
+ ProjectSettingAsset TargetStorage = null;
+
+ // Attempt to load the settings asset
+ if (!RM_Editor.TryGetSettingAsset(out TargetStorage))
+ {
+ if (Directory.Exists(Path.GetDirectoryName(RM_Editor.SetttingAssetPath)))
+ {
+ TargetStorage = CreateSettingStorage();
+ }
+ else
+ {
+ candraw = false;
+ }
+ }
+
+ // Initialize each section with the loaded settings
+ foreach (var item in sections)
+ {
+ ISectionSetting ptovider = item;
+ if (TargetStorage != null)
+ ptovider.FirstSelected(TargetStorage);
+ }
+ },
+
+
+ // Called to draw the UI elements
+ guiHandler = (searchContext) =>
+ {
+ if (candraw)
+ {
+ // Render each section
+ foreach (var item in sections)
+ {
+ ISectionSetting ptovider = item;
+ ptovider.Draw();
+ // Add a separator line
+ GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));
+ }
+ }
+ else
+ {
+ EditorGUILayout.HelpBox($"The Address is not valid {Path.GetDirectoryName(RM_Editor.SetttingAssetPath)}", MessageType.Error);
+ if (GUILayout.Button("Fix"))
+ {
+ if (!Directory.Exists("Assets/Resources"))
+ AssetDatabase.CreateFolder("Assets", "Resources");
+
+ if (!Directory.Exists("Assets/Resources/RealMethod"))
+ AssetDatabase.CreateFolder("Assets/Resources", "RealMethod");
+
+
+ ProjectSettingAsset TargetStorage = CreateSettingStorage();
+ foreach (var item in sections)
+ {
+ ISectionSetting ptovider = item;
+ if (TargetStorage != null)
+ ptovider.FirstSelected(TargetStorage);
+ }
+
+ candraw = true;
+ }
+ }
+ }
+ };
+
+ return provider;
+ }
+
+
+ private static ProjectSettingAsset CreateSettingStorage()
+ {
+ // Create a new settings asset at the specified path
+ ProjectSettingAsset settings = ScriptableObject.CreateInstance();
+ AssetDatabase.CreateAsset(settings, RM_Editor.SetttingAssetPath);
+ AssetDatabase.SaveAssets();
+ return settings;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/ProjectSettingWindow.cs.meta b/Editor/Core/ProjectSetting/ProjectSettingProvider.cs.meta
similarity index 100%
rename from Editor/Core/ProjectSetting/ProjectSettingWindow.cs.meta
rename to Editor/Core/ProjectSetting/ProjectSettingProvider.cs.meta
diff --git a/Editor/Core/ProjectSetting/ProjectSettingWindow.cs b/Editor/Core/ProjectSetting/ProjectSettingWindow.cs
deleted file mode 100644
index 6f1ebfef..00000000
--- a/Editor/Core/ProjectSetting/ProjectSettingWindow.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using UnityEditor;
-using UnityEngine;
-
-namespace RealMethod.Editor
-{
- public static class ProjectSettingWindow
- {
- private const string settingsPath = "Assets/Resources/RealMethod/RealMethodSetting.asset";
- private static bool candraw = true;// Flag to determine if the UI can be drawn
- private static ProjectSettingSection[] sections = new ProjectSettingSection[2] {
- // Array of sections to be rendered in the settings UI
- new InitializerSection(),
- new FolderSettingSection()
- };
-
-
- [SettingsProvider]// Create a SettingsProvider for Unity's Project Settings
- public static SettingsProvider CreateSettingsProvider()
- {
- var provider = new SettingsProvider("Project/Real Method", SettingsScope.Project)
- {
- label = "Real Method",
-
- // Called when the settings tab is first selected
- activateHandler = (searchContext, rootElement) =>
- {
- ProjectSettingAsset TargetStorage = null;
-
- // Attempt to load the settings asset
- if (!GetSettingStorage(out TargetStorage))
- {
- if (Directory.Exists(Path.GetDirectoryName(settingsPath)))
- {
- TargetStorage = CreateSettingStorage();
- }
- else
- {
- candraw = false;
- }
- }
-
- // Initialize each section with the loaded settings
- foreach (var item in sections)
- {
- if (TargetStorage != null)
- item.BeginRender(TargetStorage);
- }
- },
-
- // Called to draw the UI elements
- guiHandler = (searchContext) =>
- {
- if (candraw)
- {
- // Render each section
- foreach (var item in sections)
- {
- item.UpdateRender();
- // Add a separator line
- GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));
- }
- }
- else
- {
- EditorGUILayout.HelpBox($"The Address is not valid {Path.GetDirectoryName(settingsPath)}", MessageType.Error);
- if (GUILayout.Button("Fix"))
- {
- if (!Directory.Exists("Assets/Resources"))
- AssetDatabase.CreateFolder("Assets", "Resources");
-
- if (!Directory.Exists("Assets/Resources/RealMethod"))
- AssetDatabase.CreateFolder("Assets/Resources", "RealMethod");
-
-
- ProjectSettingAsset TargetStorage = CreateSettingStorage();
- foreach (var item in sections)
- {
- if (TargetStorage != null)
- item.BeginRender(TargetStorage);
- }
-
- candraw = true;
- }
- }
- }
- };
-
- return provider;
- }
-
-
- public static bool GetSettingStorage(out ProjectSettingAsset settings)
- {
- // Attempt to load the settings asset from the specified path
- settings = AssetDatabase.LoadAssetAtPath(settingsPath);
- return settings != null;
- }
- private static ProjectSettingAsset CreateSettingStorage()
- {
- // Create a new settings asset at the specified path
- ProjectSettingAsset settings = ScriptableObject.CreateInstance();
- AssetDatabase.CreateAsset(settings, settingsPath);
- AssetDatabase.SaveAssets();
- return settings;
- }
- }
-
-
- // Abstract base class for a settings section
- public abstract class ProjectSettingSection
- {
- protected class ClassType
- {
- private List TypeList;
- private string[] TypeName;
- private int selctedIndex = 0;
- private int newIndex;
-
- public ClassType()
- {
- // Get all available T types **only once**
- TypeList = AppDomain.CurrentDomain.GetAssemblies()
- .SelectMany(assembly => assembly.GetTypes())
- .Where(type => typeof(T).IsAssignableFrom(type) && !type.IsAbstract)
- .ToList();
-
- TypeName = TypeList.Select(t => t.FullName).ToArray();
- }
-
- public void Draw(SerializedObject projectSettings, string PropertyName, string DisplayName)
- {
- selctedIndex = System.Array.IndexOf(TypeName, projectSettings.FindProperty(PropertyName).stringValue);
- newIndex = EditorGUILayout.Popup(DisplayName, selctedIndex, TypeName);
- if (newIndex >= 0 && newIndex < TypeName.Length)
- {
- projectSettings.FindProperty(PropertyName).stringValue = TypeName[newIndex];
- }
- }
- }
- private bool isReady = true;// Indicates whether the section is ready to render
- private string message = string.Empty;// Error message to display if the section is not ready
- private int errorid = 0;// Error ID to identify the type of error
-
-
- public ProjectSettingSection()
- {
- Initialized();
- }
-
- public void BeginRender(ProjectSettingAsset storage)
- {
- FirstSelected(storage);
- }
- public void UpdateRender()
- {
- EditorGUILayout.Space();
- EditorGUILayout.LabelField(GetTitle(), EditorStyles.boldLabel); // Section Title
-
- if (isReady)
- {
- // Render the section's content
- Draw();
- }
- else
- {
- // Display an error message if the section is not ready
- EditorGUILayout.HelpBox(message, MessageType.Error);
-
- // Provide a "Fix" button to resolve the error
- if (GUILayout.Button("Fix"))
- {
- Fix(errorid);
- }
- }
- }
-
-
- protected abstract void Initialized();
- protected abstract void FirstSelected(ProjectSettingAsset Storage);
- protected abstract void Draw();
- protected abstract string GetTitle();
- protected abstract void Fix(int Id);
-
-
- protected void Error(string Message, int Id = 0)
- {
- if (isReady)
- {
- isReady = false;
- }
- message = Message;
- errorid = Id;
- }
- protected void ClearError()
- {
- message = string.Empty;
- errorid = 0;
- if (!isReady)
- {
- isReady = true;
- }
- UpdateRender();
- }
-
- }
-}
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/Sections/CompileRuleSection.cs b/Editor/Core/ProjectSetting/Sections/CompileRuleSection.cs
new file mode 100644
index 00000000..99959225
--- /dev/null
+++ b/Editor/Core/ProjectSetting/Sections/CompileRuleSection.cs
@@ -0,0 +1,85 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public class CompileRuleSection : ProjectSettingSection
+ {
+ private class RuleSelector : ArrayTypeSelector
+ {
+
+ public RuleSelector(SerializedProperty TargetStringProperty, string displayName) : base(TargetStringProperty, displayName)
+ {
+ }
+
+ protected override int GetEnforceDisableIndex()
+ {
+ return CompileGuard.DefaultRuls.Length;
+ }
+ protected override void DefaultInitiation()
+ {
+ foreach (var ruletype in CompileGuard.DefaultRuls)
+ {
+ int Index = myProperty.arraySize;
+ myProperty.InsertArrayElementAtIndex(Index);
+ SerializedProperty element = myProperty.GetArrayElementAtIndex(Index);
+ element.stringValue = ruletype.AssemblyQualifiedName;
+ Debug.LogWarning($"====> {ruletype}");
+ }
+ }
+ }
+
+ private SerializedProperty CompilingSerialized;
+ private ProjectSettingAsset SettingAsset;
+ private SerializedObject projectSettings;
+ private RuleSelector Rules;
+
+
+ // Implement ProjectSettingSection Methods
+ protected override void Initialized()
+ {
+ }
+ protected override string GetTitle()
+ {
+ return "CompileGuard";
+ }
+ protected override SectionType GetSectionType()
+ {
+ return SectionType.Editor;
+ }
+ protected override void BeginRender(ProjectSettingAsset Storage)
+ {
+ SettingAsset = Storage;
+ projectSettings = new SerializedObject(Storage);
+ CompilingSerialized = projectSettings.FindProperty("Compiling");
+ Rules = new RuleSelector(projectSettings.FindProperty("Rules"), "Rules");
+ }
+ protected override void UpdateRender()
+ {
+ if (projectSettings == null) return;
+
+ projectSettings.Update();
+ CompilingSerialized.boolValue = EditorGUILayout.Toggle("Enable", CompilingSerialized.boolValue, GUILayout.Width(100));
+
+ Rules.Draw();
+
+ if (GUI.changed)
+ {
+ projectSettings.ApplyModifiedProperties();
+ EditorUtility.SetDirty(SettingAsset); // Mark ScriptableObject dirty
+ AssetDatabase.SaveAssets(); // Optional: saves to disk immediately
+ AssetDatabase.Refresh();
+ }
+
+ projectSettings.ApplyModifiedProperties();
+
+ }
+
+
+ protected override void Fix(int Id)
+ {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/Sections/CompileRuleSection.cs.meta b/Editor/Core/ProjectSetting/Sections/CompileRuleSection.cs.meta
new file mode 100644
index 00000000..d771a57b
--- /dev/null
+++ b/Editor/Core/ProjectSetting/Sections/CompileRuleSection.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: de6204fe01936154fbd368730fc129c5
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/Sections/FolderSettingSection.cs b/Editor/Core/ProjectSetting/Sections/FolderStructureSection.cs
similarity index 72%
rename from Editor/Core/ProjectSetting/Sections/FolderSettingSection.cs
rename to Editor/Core/ProjectSetting/Sections/FolderStructureSection.cs
index 5396d8c6..9771a35f 100644
--- a/Editor/Core/ProjectSetting/Sections/FolderSettingSection.cs
+++ b/Editor/Core/ProjectSetting/Sections/FolderStructureSection.cs
@@ -3,37 +3,40 @@
namespace RealMethod.Editor
{
- public class FolderSettingSection : ProjectSettingSection
+ public class FolderStructureSection : ProjectSettingSection
{
private ProjectSettingAsset MyStorage;
private bool isPanelMaximize = false; // Add a toggle for minimizing the panel
- // Implement Abstraction Methods
+ // Implement ProjectSettingSection Methods
protected override void Initialized()
{
}
-
- protected override void FirstSelected(ProjectSettingAsset Storage)
+ protected override void BeginRender(ProjectSettingAsset Storage)
{
MyStorage = Storage;
}
-
- protected override void Draw()
+ protected override void UpdateRender()
{
+ if (!AssetDatabase.IsValidFolder("Assets/" + Application.productName))
+ {
+ AssetDatabase.CreateFolder("Assets", Application.productName);
+ }
+
// Add a toggle button for minimizing or expanding the panel
EditorGUILayout.BeginHorizontal();
isPanelMaximize = EditorGUILayout.Foldout(isPanelMaximize, "Folder List", true, EditorStyles.foldoutHeader);
if (GUILayout.Button("Create All", GUILayout.Width(80)))
{
- foreach (var address in MyStorage.ProjectStructure)
+ foreach (var address in MyStorage.FolderStructure)
{
- if (AssetDatabase.IsValidFolder(address.Path))
+ if (AssetDatabase.IsValidFolder(address.AssetPath))
{
Debug.Log($"Folder exists: {address}");
}
else
{
- string folderpath = address.Path;
+ string folderpath = address.GetFolderPath(MyStorage);
string FolderAddress = string.Join("/", folderpath.Split('/')[..^1]); // Remove the last segment of the path
string folderName = System.IO.Path.GetFileName(folderpath); // Get the last segment of the path
CreateFolder(FolderAddress, folderName); // Create the folder
@@ -49,26 +52,26 @@ protected override void Draw()
}
// Render the folder list
- for (int i = 0; i < MyStorage.ProjectStructure.Length; i++)
+ for (int i = 0; i < MyStorage.FolderStructure.Count; i++)
{
EditorGUILayout.BeginHorizontal(); // Start horizontal layout
// Display the folder path as a text field
- MyStorage.ProjectStructure[i].Path = EditorGUILayout.TextField($"{i + 1}.{MyStorage.ProjectStructure[i].Identity}", MyStorage.ProjectStructure[i].Path);
+ MyStorage.SetFolderAddressPath(i, EditorGUILayout.TextField($"{i + 1}.{MyStorage.FolderStructure[i].AssetType}", MyStorage.FolderStructure[i].AssetPath));
- string ButtonName = AssetDatabase.IsValidFolder(MyStorage.ProjectStructure[i].Path) ? "Check" : "Create";
+ string ButtonName = AssetDatabase.IsValidFolder(MyStorage.FolderStructure[i].AssetPath) ? "Check" : "Create";
// Add a button next to the text field
if (GUILayout.Button(ButtonName, GUILayout.Width(60)))
{
// Check if the folder exists
- if (AssetDatabase.IsValidFolder(MyStorage.ProjectStructure[i].Path))
+ if (AssetDatabase.IsValidFolder(MyStorage.FolderStructure[i].AssetPath))
{
- Debug.Log($"Folder exists: {MyStorage.ProjectStructure[i]}");
+ Debug.Log($"Folder exists: {MyStorage.FolderStructure[i]}");
}
else
{
- string folderpath = MyStorage.ProjectStructure[i].Path;
+ string folderpath = MyStorage.FolderStructure[i].GetFolderPath(MyStorage);
string FolderAddress = string.Join("/", folderpath.Split('/')[..^1]); // Remove the last segment of the path
string folderName = System.IO.Path.GetFileName(folderpath); // Get the last segment of the path
CreateFolder(FolderAddress, folderName); // Create the folder
@@ -78,16 +81,19 @@ protected override void Draw()
EditorGUILayout.EndHorizontal(); // End horizontal layout
}
}
-
protected override string GetTitle()
{
return "FolderStructure";
}
-
+ protected override SectionType GetSectionType()
+ {
+ return SectionType.Editor;
+ }
protected override void Fix(int Id)
{
}
+
private void CreateFolder(string parentFolder, string newFolderName)
{
string folderPath = System.IO.Path.Combine(parentFolder, newFolderName).Replace("\\", "/");
diff --git a/Editor/Core/ProjectSetting/Sections/FolderSettingSection.cs.meta b/Editor/Core/ProjectSetting/Sections/FolderStructureSection.cs.meta
similarity index 100%
rename from Editor/Core/ProjectSetting/Sections/FolderSettingSection.cs.meta
rename to Editor/Core/ProjectSetting/Sections/FolderStructureSection.cs.meta
diff --git a/Editor/Core/ProjectSetting/Sections/GameStatusSection.cs b/Editor/Core/ProjectSetting/Sections/GameStatusSection.cs
new file mode 100644
index 00000000..87b7dd32
--- /dev/null
+++ b/Editor/Core/ProjectSetting/Sections/GameStatusSection.cs
@@ -0,0 +1,103 @@
+
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public class GameStatusSection : ProjectSettingSection
+ {
+ private ProjectSettingAsset SettingAsset;
+ private SerializedObject projectSettings;
+ private List MyList
+ {
+ get
+ {
+ if (SettingAsset == null)
+ {
+ //Error("SettingAsset Can't find");
+ return new List(0);
+ }
+ return SettingAsset.Status;
+ }
+
+ set
+ {
+ if (SettingAsset != null)
+ {
+ SettingAsset.Status = value;
+ }
+ else
+ {
+ //Error("SettingAsset Can't find");
+ }
+ }
+ }
+
+
+ protected override string GetTitle()
+ {
+ return "GameStatus";
+ }
+ protected override SectionType GetSectionType()
+ {
+ return SectionType.Editor;
+ }
+ protected override void Initialized()
+ {
+
+ }
+ protected override void BeginRender(ProjectSettingAsset Storage)
+ {
+ SettingAsset = Storage;
+ projectSettings = new SerializedObject(Storage);
+ }
+ protected override void UpdateRender()
+ {
+ EditorGUI.BeginChangeCheck();
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.Space(5);
+ int newSize = Mathf.Max(0, EditorGUILayout.IntField("Size", MyList.Count));
+ EditorGUILayout.EndHorizontal();
+
+ while (MyList.Count < newSize)
+ MyList.Add("");
+
+ while (MyList.Count > newSize)
+ MyList.RemoveAt(MyList.Count - 1);
+
+ for (int i = 0; i < MyList.Count; i++)
+ {
+ MyList[i] = EditorGUILayout.TextField($"Element {i}", MyList[i]);
+ }
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ if (projectSettings != null)
+ {
+ Undo.RecordObject(SettingAsset, "Modify Game Status Names");
+ EditorUtility.SetDirty(SettingAsset);
+ }
+ }
+
+ if (GUI.changed)
+ {
+ projectSettings.ApplyModifiedProperties();
+ EditorUtility.SetDirty(SettingAsset); // Mark ScriptableObject dirty
+ AssetDatabase.SaveAssets(); // Optional: saves to disk immediately
+ AssetDatabase.Refresh();
+ }
+
+ projectSettings.ApplyModifiedProperties();
+
+ }
+
+ protected override void Fix(int Id)
+ {
+ ClearError();
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/Sections/GameStatusSection.cs.meta b/Editor/Core/ProjectSetting/Sections/GameStatusSection.cs.meta
new file mode 100644
index 00000000..0a82f4c1
--- /dev/null
+++ b/Editor/Core/ProjectSetting/Sections/GameStatusSection.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: a6ecf6e981d7ae74ea5bfab2e27f9523
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/Sections/InitializerSection.cs b/Editor/Core/ProjectSetting/Sections/InitializerSettingSection.cs
similarity index 62%
rename from Editor/Core/ProjectSetting/Sections/InitializerSection.cs
rename to Editor/Core/ProjectSetting/Sections/InitializerSettingSection.cs
index 477e7f76..5bcdfdae 100644
--- a/Editor/Core/ProjectSetting/Sections/InitializerSection.cs
+++ b/Editor/Core/ProjectSetting/Sections/InitializerSettingSection.cs
@@ -3,42 +3,48 @@
namespace RealMethod.Editor
{
- public class InitializerSection : ProjectSettingSection
+ public class InitializerSettingSection : ProjectSettingSection
{
- private ClassType gameClass;
- private ClassType gameService;
+ private TypeSelector gameClass;
+ private TypeSelector gameBridge;
private SerializedObject projectSettings;
private ProjectSettingAsset SettingAsset;
+ protected override string GetTitle()
+ {
+ return "Initializer";
+ }
+ protected override SectionType GetSectionType()
+ {
+ return SectionType.Runtime;
+ }
protected override void Initialized()
{
- gameClass = new ClassType();
- gameService = new ClassType();
+
}
- protected override void FirstSelected(ProjectSettingAsset Storage)
+ protected override void BeginRender(ProjectSettingAsset Storage)
{
SettingAsset = Storage;
projectSettings = new SerializedObject(Storage);
+ gameClass = new TypeSelector(projectSettings.FindProperty("GameClass"), "Game Class");
+ gameBridge = new TypeSelector(projectSettings.FindProperty("GameBridge"), "Game Bridge");
}
- protected override void Draw()
+ protected override void UpdateRender()
{
if (projectSettings == null) return;
projectSettings.Update();
// GameInstanceClass
- gameClass.Draw(projectSettings, "GameClass", "Game Class");
-
- // GameServiceClass
- gameService.Draw(projectSettings, "GameService", "Game Service");
-
+ gameClass.Draw();
+ // GameBridgeClass
+ gameBridge.Draw();
// GameSettingAsset
EditorGUILayout.PropertyField(projectSettings.FindProperty("GameConfig"), new GUIContent("Game Config"));
-
//GameInitialPrefabs
- EditorGUILayout.PropertyField(projectSettings.FindProperty("GamePrefab_1"), new GUIContent("Game Prefab (1)"));
- EditorGUILayout.PropertyField(projectSettings.FindProperty("GamePrefab_2"), new GUIContent("Game Prefab (2)"));
- EditorGUILayout.PropertyField(projectSettings.FindProperty("GamePrefab_3"), new GUIContent("Game Prefab (3)"));
+ EditorGUILayout.PropertyField(projectSettings.FindProperty("GamePrefab_1"), new GUIContent("GameScope (Runtime)"));
+ EditorGUILayout.PropertyField(projectSettings.FindProperty("GamePrefab_2"), new GUIContent("GameScope (Editor)"));
+ EditorGUILayout.PropertyField(projectSettings.FindProperty("GamePrefab_3"), new GUIContent("Dedicated Server"));
if (GUI.changed)
{
@@ -50,17 +56,11 @@ protected override void Draw()
projectSettings.ApplyModifiedProperties();
}
- protected override string GetTitle()
- {
- return "Initializer";
- }
protected override void Fix(int Id)
{
throw new System.NotImplementedException();
}
-
-
}
}
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/Sections/InitializerSection.cs.meta b/Editor/Core/ProjectSetting/Sections/InitializerSettingSection.cs.meta
similarity index 100%
rename from Editor/Core/ProjectSetting/Sections/InitializerSection.cs.meta
rename to Editor/Core/ProjectSetting/Sections/InitializerSettingSection.cs.meta
diff --git a/Editor/Core/ProjectSetting/UnityAsset_Postprocessor.cs b/Editor/Core/ProjectSetting/UnityAsset_Postprocessor.cs
deleted file mode 100644
index 95642d87..00000000
--- a/Editor/Core/ProjectSetting/UnityAsset_Postprocessor.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using UnityEditor;
-using UnityEngine;
-
-namespace RealMethod.Editor
-{
- public class UnityAsset_Postprocessor : AssetPostprocessor
- {
- static AssetHandeler[] AssetList = new AssetHandeler[5] {
- new WorldScene_UnityAsset(),
- new Table_UnityAsset(),
- new PCGResource_UnityAsset(),
- new PCGGeneration_UnityAsset(),
- new PCGCash_UnityAsset() };
-
- // private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
- // {
- // if (AssetList == null)
- // {
- // return;
- // }
-
- // foreach (var asset in AssetList)
- // {
- // foreach (string assetPath in importedAssets)
- // {
- // asset.OnAssetImported(assetPath);
- // }
- // foreach (string assetPath in deletedAssets)
- // {
- // asset.OnAssetDeleted(assetPath);
- // }
- // for (int i = 0; i < movedAssets.Length; i++)
- // {
- // asset.OnAssetMoved(movedAssets[i], movedFromAssetPaths[i]);
- // }
- // }
- // }
-
- [InitializeOnLoadMethod]
- private static void OnDoubleClickScriptableObject()
- {
- EditorApplication.projectWindowItemOnGUI += (guid, rect) =>
- {
- Event e = Event.current;
- if (e.type == EventType.MouseDown && e.clickCount == 2)
- {
- string assetPath = AssetDatabase.GUIDToAssetPath(guid);
- foreach (var asset in AssetList)
- {
- asset.OnAssetClick(assetPath, e);
- }
- }
- };
- }
- }
-
-
-
- public abstract class AssetHandeler
- {
- public AssetHandeler()
- {
- Initialized();
- }
-
- protected abstract void Initialized();
- public abstract void OnAssetImported(string AssetPath);
- public abstract void OnAssetDeleted(string AssetPath);
- public abstract void OnAssetMoved(string AssetPath, string FromPath);
- public abstract void OnAssetClick(string AssetPath, Event e);
- protected abstract string GetIconPath();
- }
-
- public abstract class AssetHandeler : AssetHandeler where T : Object
- {
- protected abstract void DoubleClick(T asset);
-
- public override void OnAssetImported(string AssetPath)
- {
- T loadedAsset;
- if (TryLoadAsset(AssetPath, out loadedAsset))
- {
- if (loadedAsset.GetType() == typeof(J))
- {
- // Load your icon from Resources (adjust the path as needed)
- Texture2D icon = Resources.Load(GetIconPath());
- if (icon != null)
- {
- EditorGUIUtility.SetIconForObject(loadedAsset, icon);
- }
- else
- {
- Debug.LogWarning("Custom icon not found. Please ensure the path and file are correct.");
- }
- }
- }
- else
- {
- Debug.LogWarning("Cant Load ");
- }
- }
- public override void OnAssetClick(string AssetPath, Event e)
- {
- var asset = AssetDatabase.LoadAssetAtPath(AssetPath);
-
- if (asset != null)
- {
- DoubleClick(asset);
- e.Use(); // Consume the event
- }
- }
-
- protected bool TryLoadAsset(string assetPath, out K asset) where K : Object
- {
- asset = AssetDatabase.LoadAssetAtPath(assetPath);
- return asset != null;
- }
- }
-
-
-
-
-}
\ No newline at end of file
diff --git a/Editor/Core/Utilities.meta b/Editor/Core/Utilities.meta
new file mode 100644
index 00000000..c92a9ecd
--- /dev/null
+++ b/Editor/Core/Utilities.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0bdf41dbd1061b64299b20780a85c8c7
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Core/Utilities/Editor_Library.cs b/Editor/Core/Utilities/Editor_Library.cs
new file mode 100644
index 00000000..d5802a7f
--- /dev/null
+++ b/Editor/Core/Utilities/Editor_Library.cs
@@ -0,0 +1,197 @@
+using System.IO;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public enum RealMethodLayer
+ {
+ Core,
+ Library,
+ Pattern,
+ ReadySet,
+ Toolkit
+ }
+
+ public static class RM_Editor
+ {
+ public static class MenuOrder
+ {
+ private const int starter = 80;
+ private const int space = 1;
+ private const int priorityjumps = 11;
+
+
+
+ public const int Essential_Head = starter;
+ public const int Essential_Body = Essential_Head;
+ public const int Manager_Head = Essential_Head + space;
+ public const int Manager_Body = Manager_Head + priorityjumps;
+ public const int Service_Head = Manager_Head + space;
+ public const int Service_Body = Service_Head + priorityjumps;
+ public const int DataAsset_Head = Service_Head + space;
+ public const int DataAsset_Body = DataAsset_Head + priorityjumps;
+ public const int CloneAsset_Head = DataAsset_Head + space;
+ public const int CloneAsset_Body = CloneAsset_Head + priorityjumps;
+ public const int UniqueAsset_Head = CloneAsset_Head + space;
+ public const int UniqueAsset_Body = UniqueAsset_Head + priorityjumps;
+ public const int ConfigAsset_Head = UniqueAsset_Head + space;
+ public const int ConfigAsset_Body = ConfigAsset_Head + priorityjumps;
+ public const int Method = ConfigAsset_Body + space;
+ public const int Toolkit = Method + space;
+ public const int Editor = Toolkit + space + priorityjumps;
+ }
+ public static string SetttingAssetPath = ProjectSettingAsset.Path;
+ public static string ScriptTemplatesPath => GetPackagePath("com.mustard.realmethod") + "/Reservoir/ScriptTemplates";
+ public static string PrefabTemplatePath => GetPackagePath("com.mustard.realmethod") + "/Reservoir/Prefabs";
+ public const string GameObjectMenuItemPath = "GameObject/RealMethod/";
+ public const string ScriptMenuItemPath = "Assets/Create/Scripting/RealMethod/";
+ public static string Documentation => GetPackagePath("com.mustard.realmethod") + "/Documentation/Information";
+ public static bool IsPlayMode
+ {
+ get
+ {
+ return EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode == false;
+ }
+ }
+
+
+
+
+ // Functions
+ public static bool TryGetSettingAsset(out ProjectSettingAsset settings)
+ {
+ // Attempt to load the settings asset from the specified path
+ settings = AssetDatabase.LoadAssetAtPath(SetttingAssetPath);
+ return settings != null;
+ }
+ private static string GetPackagePath(string packageName)
+ {
+ string[] guids = AssetDatabase.FindAssets("package", new[] { "Packages/" + packageName });
+ foreach (string guid in guids)
+ {
+ string path = AssetDatabase.GUIDToAssetPath(guid);
+ if (path.Contains(packageName))
+ {
+ string packagePath = Path.GetDirectoryName(path);
+ while (!string.IsNullOrEmpty(packagePath))
+ {
+ if (File.Exists(Path.Combine(packagePath, "package.json")))
+ return packagePath;
+
+ packagePath = Path.GetDirectoryName(packagePath);
+ }
+ }
+ }
+
+ Debug.LogError($"Could not find package path for: {packageName}");
+ return null;
+ }
+ public static void CreateScriptTemplate(string TemplateName, RealMethodLayer layer)
+ {
+ string NewFileName = $"My{TemplateName}.cs";
+ string TemplateFileName = $"{layer}\\{TemplateName}Template.txt";
+ string NewFilePath = CreateScriptTemplate(TemplateFileName, NewFileName);
+ }
+ public static GameObject CreatePrefabTemplate(string prefabName, bool UseProject = false)
+ {
+
+ string prefabPath = string.Empty;
+ if (UseProject)
+ {
+ ProjectSettingAsset ProjectSetting = AssetDatabase.LoadAssetAtPath(SetttingAssetPath);
+ prefabPath = Path.Combine(ProjectSetting.GetFolderPathByType(ProjectSettingAsset.AssetFormat.Prefab), prefabName);
+ }
+ else
+ {
+ prefabPath = Path.Combine(PrefabTemplatePath, prefabName);
+ }
+
+ // Load the prefab from the specified path
+ GameObject prefab = AssetDatabase.LoadAssetAtPath(prefabPath);
+
+ if (prefab != null)
+ {
+ // Create an instance of the prefab in the scene
+ GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
+
+ // Register the creation in the undo system
+ Undo.RegisterCreatedObjectUndo(instance, "Create " + instance.name);
+
+ // Select the newly created instance
+ Selection.activeObject = instance;
+ return instance;
+ }
+ else
+ {
+ Debug.LogError("Prefab not found at path: " + prefabPath);
+ return null;
+ }
+ }
+ public static string GetScenePathByName(string name)
+ {
+ foreach (var scene in EditorBuildSettings.scenes)
+ {
+ if (scene.path.Contains(name))
+ return scene.path;
+ }
+ return null;
+ }
+
+
+
+
+ // Methods
+ private static string CreateScriptTemplate(string templateFileName, string defaultName)
+ {
+ string templatePath = string.Empty;
+ if (Directory.Exists("Assets/RealDev/_General"))
+ {
+ Debug.LogWarning("When This Message show RealMetod using hardcode addres becuase find [Assets/RealDev/_General]");
+ templatePath = Path.Combine("Assets\\RealMethod\\Reservoir\\ScriptTemplates\\", templateFileName);
+ }
+ else
+ {
+ templatePath = Path.Combine(ScriptTemplatesPath, templateFileName);
+ }
+
+
+ if (!File.Exists(templatePath))
+ {
+ Debug.LogError($"Template file not found: {templatePath}");
+ return string.Empty;
+ }
+
+ string selectedPath = RM_Asset.GetSelectedAssetDirectory();
+ string newScriptPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(selectedPath, defaultName));
+
+ // Prompt user for script name before creating the file
+ string inputName = EditorUtility.SaveFilePanel(
+ "Create Script",
+ selectedPath,
+ Path.GetFileNameWithoutExtension(defaultName),
+ "cs"
+ );
+
+ if (string.IsNullOrEmpty(inputName))
+ return string.Empty;
+
+ // Ensure the path is relative to the Assets folder
+ if (inputName.StartsWith(Application.dataPath))
+ newScriptPath = "Assets" + inputName.Substring(Application.dataPath.Length);
+ else
+ newScriptPath = inputName;
+
+ string template = File.ReadAllText(templatePath);
+ template = template.Replace("#SCRIPTNAME#", Path.GetFileNameWithoutExtension(newScriptPath));
+ string projectName = Application.productName;
+ template = template.Replace("#PROJECTNAME#", projectName);
+
+ File.WriteAllText(newScriptPath, template);
+ AssetDatabase.Refresh();
+ Selection.activeObject = AssetDatabase.LoadAssetAtPath(newScriptPath);
+ return newScriptPath;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Library/Utilities/Core.cs.meta b/Editor/Core/Utilities/Editor_Library.cs.meta
similarity index 100%
rename from Editor/Library/Utilities/Core.cs.meta
rename to Editor/Core/Utilities/Editor_Library.cs.meta
diff --git a/Editor/Library/Drawers.meta b/Editor/Library/Drawers.meta
new file mode 100644
index 00000000..bfda2d7a
--- /dev/null
+++ b/Editor/Library/Drawers.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 09f6f3abd6dcd6748b7743fe122234a1
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Library/Vendor/SerializableDictionary/SerializableDictionaryPropertyDrawer.cs b/Editor/Library/Drawers/MapDrawer.cs
similarity index 96%
rename from Editor/Library/Vendor/SerializableDictionary/SerializableDictionaryPropertyDrawer.cs
rename to Editor/Library/Drawers/MapDrawer.cs
index 8e97de0f..4266dfd9 100644
--- a/Editor/Library/Vendor/SerializableDictionary/SerializableDictionaryPropertyDrawer.cs
+++ b/Editor/Library/Drawers/MapDrawer.cs
@@ -7,24 +7,12 @@
namespace RealMethod.Editor
{
- [CustomPropertyDrawer(typeof(SerializableDictionaryBase), true)]
+ [CustomPropertyDrawer(typeof(MapCore), true)]
#if NET_4_6 || NET_STANDARD_2_0
[CustomPropertyDrawer(typeof(SerializableHashSetBase), true)]
#endif
- public class SerializableDictionaryPropertyDrawer : PropertyDrawer
+ public class MapDrawer : PropertyDrawer
{
- const string KeysFieldName = "m_keys";
- const string ValuesFieldName = "m_values";
- protected const float IndentWidth = 15f;
-
- static GUIContent s_iconPlus = IconContent("Toolbar Plus", "Add entry");
- static GUIContent s_iconMinus = IconContent("Toolbar Minus", "Remove entry");
- static GUIContent s_warningIconConflict = IconContent("console.warnicon.sml", "Conflicting key, this entry will be lost");
- static GUIContent s_warningIconOther = IconContent("console.infoicon.sml", "Conflicting key");
- static GUIContent s_warningIconNull = IconContent("console.warnicon.sml", "Null key, this entry will be lost");
- static GUIStyle s_buttonStyle = GUIStyle.none;
- static GUIContent s_tempContent = new GUIContent();
-
class ConflictState
{
@@ -36,7 +24,6 @@ class ConflictState
public bool conflictValuePropertyExpanded = false;
public float conflictLineHeight = 0f;
}
-
struct PropertyIdentity
{
public PropertyIdentity(SerializedProperty property)
@@ -48,9 +35,19 @@ public PropertyIdentity(SerializedProperty property)
public UnityEngine.Object instance;
public string propertyPath;
}
+ struct EnumerationEntry
+ {
+ public SerializedProperty keyProperty;
+ public SerializedProperty valueProperty;
+ public int index;
- static Dictionary s_conflictStateDict = new Dictionary();
-
+ public EnumerationEntry(SerializedProperty keyProperty, SerializedProperty valueProperty, int index)
+ {
+ this.keyProperty = keyProperty;
+ this.valueProperty = valueProperty;
+ this.index = index;
+ }
+ }
enum Action
{
None,
@@ -58,166 +55,52 @@ enum Action
Remove
}
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- label = EditorGUI.BeginProperty(position, label, property);
-
- Action buttonAction = Action.None;
- int buttonActionIndex = 0;
-
- var keyArrayProperty = property.FindPropertyRelative(KeysFieldName);
- var valueArrayProperty = property.FindPropertyRelative(ValuesFieldName);
-
- ConflictState conflictState = GetConflictState(property);
-
- if (conflictState.conflictIndex != -1)
- {
- keyArrayProperty.InsertArrayElementAtIndex(conflictState.conflictIndex);
- var keyProperty = keyArrayProperty.GetArrayElementAtIndex(conflictState.conflictIndex);
- SetPropertyValue(keyProperty, conflictState.conflictKey);
- keyProperty.isExpanded = conflictState.conflictKeyPropertyExpanded;
-
- if (valueArrayProperty != null)
- {
- valueArrayProperty.InsertArrayElementAtIndex(conflictState.conflictIndex);
- var valueProperty = valueArrayProperty.GetArrayElementAtIndex(conflictState.conflictIndex);
- SetPropertyValue(valueProperty, conflictState.conflictValue);
- valueProperty.isExpanded = conflictState.conflictValuePropertyExpanded;
- }
- }
-
- var buttonWidth = s_buttonStyle.CalcSize(s_iconPlus).x;
-
- var labelPosition = position;
- labelPosition.height = EditorGUIUtility.singleLineHeight;
- if (property.isExpanded)
- labelPosition.xMax -= s_buttonStyle.CalcSize(s_iconPlus).x;
-
- EditorGUI.PropertyField(labelPosition, property, label, false);
- // property.isExpanded = EditorGUI.Foldout(labelPosition, property.isExpanded, label);
- if (property.isExpanded)
- {
- var buttonPosition = position;
- buttonPosition.xMin = buttonPosition.xMax - buttonWidth;
- buttonPosition.height = EditorGUIUtility.singleLineHeight;
- EditorGUI.BeginDisabledGroup(conflictState.conflictIndex != -1);
- if (GUI.Button(buttonPosition, s_iconPlus, s_buttonStyle))
- {
- buttonAction = Action.Add;
- buttonActionIndex = keyArrayProperty.arraySize;
- }
- EditorGUI.EndDisabledGroup();
-
- EditorGUI.indentLevel++;
- var linePosition = position;
- linePosition.y += EditorGUIUtility.singleLineHeight;
- linePosition.xMax -= buttonWidth;
-
- foreach (var entry in EnumerateEntries(keyArrayProperty, valueArrayProperty))
- {
- var keyProperty = entry.keyProperty;
- var valueProperty = entry.valueProperty;
- int i = entry.index;
-
- float lineHeight = DrawKeyValueLine(keyProperty, valueProperty, linePosition, i);
-
- buttonPosition = linePosition;
- buttonPosition.x = linePosition.xMax;
- buttonPosition.height = EditorGUIUtility.singleLineHeight;
- if (GUI.Button(buttonPosition, s_iconMinus, s_buttonStyle))
- {
- buttonAction = Action.Remove;
- buttonActionIndex = i;
- }
-
- if (i == conflictState.conflictIndex && conflictState.conflictOtherIndex == -1)
- {
- var iconPosition = linePosition;
- iconPosition.size = s_buttonStyle.CalcSize(s_warningIconNull);
- GUI.Label(iconPosition, s_warningIconNull);
- }
- else if (i == conflictState.conflictIndex)
- {
- var iconPosition = linePosition;
- iconPosition.size = s_buttonStyle.CalcSize(s_warningIconConflict);
- GUI.Label(iconPosition, s_warningIconConflict);
- }
- else if (i == conflictState.conflictOtherIndex)
- {
- var iconPosition = linePosition;
- iconPosition.size = s_buttonStyle.CalcSize(s_warningIconOther);
- GUI.Label(iconPosition, s_warningIconOther);
- }
-
-
- linePosition.y += lineHeight;
- }
+ const string KeysFieldName = "m_keys";
+ const string ValuesFieldName = "m_values";
+ protected const float IndentWidth = 15f;
- EditorGUI.indentLevel--;
- }
- if (buttonAction == Action.Add)
- {
- keyArrayProperty.InsertArrayElementAtIndex(buttonActionIndex);
- if (valueArrayProperty != null)
- valueArrayProperty.InsertArrayElementAtIndex(buttonActionIndex);
- }
- else if (buttonAction == Action.Remove)
- {
- DeleteArrayElementAtIndex(keyArrayProperty, buttonActionIndex);
- if (valueArrayProperty != null)
- DeleteArrayElementAtIndex(valueArrayProperty, buttonActionIndex);
- }
+ static MapDrawer()
+ {
+ Dictionary serializedPropertyValueAccessorsNameDict = new Dictionary() {
+ { SerializedPropertyType.Integer, "intValue" },
+ { SerializedPropertyType.Boolean, "boolValue" },
+ { SerializedPropertyType.Float, "floatValue" },
+ { SerializedPropertyType.String, "stringValue" },
+ { SerializedPropertyType.Color, "colorValue" },
+ { SerializedPropertyType.ObjectReference, "objectReferenceValue" },
+ { SerializedPropertyType.LayerMask, "intValue" },
+ { SerializedPropertyType.Enum, "intValue" },
+ { SerializedPropertyType.Vector2, "vector2Value" },
+ { SerializedPropertyType.Vector3, "vector3Value" },
+ { SerializedPropertyType.Vector4, "vector4Value" },
+ { SerializedPropertyType.Rect, "rectValue" },
+ { SerializedPropertyType.ArraySize, "intValue" },
+ { SerializedPropertyType.Character, "intValue" },
+ { SerializedPropertyType.AnimationCurve, "animationCurveValue" },
+ { SerializedPropertyType.Bounds, "boundsValue" },
+ { SerializedPropertyType.Quaternion, "quaternionValue" },
+ };
+ Type serializedPropertyType = typeof(SerializedProperty);
- conflictState.conflictKey = null;
- conflictState.conflictValue = null;
- conflictState.conflictIndex = -1;
- conflictState.conflictOtherIndex = -1;
- conflictState.conflictLineHeight = 0f;
- conflictState.conflictKeyPropertyExpanded = false;
- conflictState.conflictValuePropertyExpanded = false;
+ s_serializedPropertyValueAccessorsDict = new Dictionary();
+ BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
- foreach (var entry1 in EnumerateEntries(keyArrayProperty, valueArrayProperty))
+ foreach (var kvp in serializedPropertyValueAccessorsNameDict)
{
- var keyProperty1 = entry1.keyProperty;
- int i = entry1.index;
- object keyProperty1Value = GetPropertyValue(keyProperty1);
-
- if (keyProperty1Value == null)
- {
- var valueProperty1 = entry1.valueProperty;
- SaveProperty(keyProperty1, valueProperty1, i, -1, conflictState);
- DeleteArrayElementAtIndex(keyArrayProperty, i);
- if (valueArrayProperty != null)
- DeleteArrayElementAtIndex(valueArrayProperty, i);
-
- break;
- }
-
-
- foreach (var entry2 in EnumerateEntries(keyArrayProperty, valueArrayProperty, i + 1))
- {
- var keyProperty2 = entry2.keyProperty;
- int j = entry2.index;
- object keyProperty2Value = GetPropertyValue(keyProperty2);
-
- if (ComparePropertyValues(keyProperty1Value, keyProperty2Value))
- {
- var valueProperty2 = entry2.valueProperty;
- SaveProperty(keyProperty2, valueProperty2, j, i, conflictState);
- DeleteArrayElementAtIndex(keyArrayProperty, j);
- if (valueArrayProperty != null)
- DeleteArrayElementAtIndex(valueArrayProperty, j);
-
- goto breakLoops;
- }
- }
+ PropertyInfo propertyInfo = serializedPropertyType.GetProperty(kvp.Value, flags);
+ s_serializedPropertyValueAccessorsDict.Add(kvp.Key, propertyInfo);
}
- breakLoops:
-
- EditorGUI.EndProperty();
}
-
+ static GUIContent s_iconPlus = IconContent("Toolbar Plus", "Add entry");
+ static GUIContent s_iconMinus = IconContent("Toolbar Minus", "Remove entry");
+ static GUIContent s_warningIconConflict = IconContent("console.warnicon.sml", "Conflicting key, this entry will be lost");
+ static GUIContent s_warningIconOther = IconContent("console.infoicon.sml", "Conflicting key");
+ static GUIContent s_warningIconNull = IconContent("console.warnicon.sml", "Null key, this entry will be lost");
+ static GUIStyle s_buttonStyle = GUIStyle.none;
+ static GUIContent s_tempContent = new GUIContent();
+ static Dictionary s_conflictStateDict = new Dictionary();
+ static Dictionary s_serializedPropertyValueAccessorsDict;
static float DrawKeyValueLine(SerializedProperty keyProperty, SerializedProperty valueProperty, Rect linePosition, int index)
{
bool keyCanBeExpanded = CanPropertyBeExpanded(keyProperty);
@@ -250,7 +133,6 @@ static float DrawKeyValueLine(SerializedProperty keyProperty, SerializedProperty
}
}
}
-
static float DrawKeyValueLineSimple(SerializedProperty keyProperty, SerializedProperty valueProperty, string keyLabel, string valueLabel, Rect linePosition)
{
float labelWidth = EditorGUIUtility.labelWidth;
@@ -276,7 +158,6 @@ static float DrawKeyValueLineSimple(SerializedProperty keyProperty, SerializedPr
return Mathf.Max(keyPropertyHeight, valuePropertyHeight);
}
-
static float DrawKeyValueLineExpand(SerializedProperty keyProperty, SerializedProperty valueProperty, Rect linePosition)
{
float labelWidth = EditorGUIUtility.labelWidth;
@@ -296,7 +177,6 @@ static float DrawKeyValueLineExpand(SerializedProperty keyProperty, SerializedPr
return Mathf.Max(keyPropertyHeight, valuePropertyHeight);
}
-
static float DrawKeyLine(SerializedProperty keyProperty, Rect linePosition, string keyLabel)
{
float keyPropertyHeight = EditorGUI.GetPropertyHeight(keyProperty);
@@ -309,7 +189,6 @@ static float DrawKeyLine(SerializedProperty keyProperty, Rect linePosition, stri
return keyPropertyHeight;
}
-
static bool CanPropertyBeExpanded(SerializedProperty property)
{
switch (property.propertyType)
@@ -322,7 +201,6 @@ static bool CanPropertyBeExpanded(SerializedProperty property)
return false;
}
}
-
static void SaveProperty(SerializedProperty keyProperty, SerializedProperty valueProperty, int index, int otherIndex, ConflictState conflictState)
{
conflictState.conflictKey = GetPropertyValue(keyProperty);
@@ -336,37 +214,6 @@ static void SaveProperty(SerializedProperty keyProperty, SerializedProperty valu
conflictState.conflictKeyPropertyExpanded = keyProperty.isExpanded;
conflictState.conflictValuePropertyExpanded = valueProperty != null ? valueProperty.isExpanded : false;
}
-
- public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
- {
- float propertyHeight = EditorGUIUtility.singleLineHeight;
-
- if (property.isExpanded)
- {
- var keysProperty = property.FindPropertyRelative(KeysFieldName);
- var valuesProperty = property.FindPropertyRelative(ValuesFieldName);
-
- foreach (var entry in EnumerateEntries(keysProperty, valuesProperty))
- {
- var keyProperty = entry.keyProperty;
- var valueProperty = entry.valueProperty;
- float keyPropertyHeight = EditorGUI.GetPropertyHeight(keyProperty);
- float valuePropertyHeight = valueProperty != null ? EditorGUI.GetPropertyHeight(valueProperty) : 0f;
- float lineHeight = Mathf.Max(keyPropertyHeight, valuePropertyHeight);
- propertyHeight += lineHeight;
- }
-
- ConflictState conflictState = GetConflictState(property);
-
- if (conflictState.conflictIndex != -1)
- {
- propertyHeight += conflictState.conflictLineHeight;
- }
- }
-
- return propertyHeight;
- }
-
static ConflictState GetConflictState(SerializedProperty property)
{
ConflictState conflictState;
@@ -378,54 +225,16 @@ static ConflictState GetConflictState(SerializedProperty property)
}
return conflictState;
}
-
- static Dictionary s_serializedPropertyValueAccessorsDict;
-
- static SerializableDictionaryPropertyDrawer()
- {
- Dictionary serializedPropertyValueAccessorsNameDict = new Dictionary() {
- { SerializedPropertyType.Integer, "intValue" },
- { SerializedPropertyType.Boolean, "boolValue" },
- { SerializedPropertyType.Float, "floatValue" },
- { SerializedPropertyType.String, "stringValue" },
- { SerializedPropertyType.Color, "colorValue" },
- { SerializedPropertyType.ObjectReference, "objectReferenceValue" },
- { SerializedPropertyType.LayerMask, "intValue" },
- { SerializedPropertyType.Enum, "intValue" },
- { SerializedPropertyType.Vector2, "vector2Value" },
- { SerializedPropertyType.Vector3, "vector3Value" },
- { SerializedPropertyType.Vector4, "vector4Value" },
- { SerializedPropertyType.Rect, "rectValue" },
- { SerializedPropertyType.ArraySize, "intValue" },
- { SerializedPropertyType.Character, "intValue" },
- { SerializedPropertyType.AnimationCurve, "animationCurveValue" },
- { SerializedPropertyType.Bounds, "boundsValue" },
- { SerializedPropertyType.Quaternion, "quaternionValue" },
- };
- Type serializedPropertyType = typeof(SerializedProperty);
-
- s_serializedPropertyValueAccessorsDict = new Dictionary();
- BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
-
- foreach (var kvp in serializedPropertyValueAccessorsNameDict)
- {
- PropertyInfo propertyInfo = serializedPropertyType.GetProperty(kvp.Value, flags);
- s_serializedPropertyValueAccessorsDict.Add(kvp.Key, propertyInfo);
- }
- }
-
static GUIContent IconContent(string name, string tooltip)
{
var builtinIcon = EditorGUIUtility.IconContent(name);
return new GUIContent(builtinIcon.image, tooltip);
}
-
static GUIContent TempContent(string text)
{
s_tempContent.text = text;
return s_tempContent;
}
-
static void DeleteArrayElementAtIndex(SerializedProperty arrayProperty, int index)
{
var property = arrayProperty.GetArrayElementAtIndex(index);
@@ -437,7 +246,6 @@ static void DeleteArrayElementAtIndex(SerializedProperty arrayProperty, int inde
arrayProperty.DeleteArrayElementAtIndex(index);
}
-
public static object GetPropertyValue(SerializedProperty p)
{
PropertyInfo propertyInfo;
@@ -453,7 +261,6 @@ public static object GetPropertyValue(SerializedProperty p)
return GetPropertyValueGeneric(p);
}
}
-
static void SetPropertyValue(SerializedProperty p, object v)
{
PropertyInfo propertyInfo;
@@ -469,7 +276,6 @@ static void SetPropertyValue(SerializedProperty p, object v)
SetPropertyValueGeneric(p, v);
}
}
-
static object GetPropertyValueArray(SerializedProperty property)
{
object[] array = new object[property.arraySize];
@@ -480,7 +286,6 @@ static object GetPropertyValueArray(SerializedProperty property)
}
return array;
}
-
static object GetPropertyValueGeneric(SerializedProperty property)
{
Dictionary dict = new Dictionary();
@@ -497,7 +302,6 @@ static object GetPropertyValueGeneric(SerializedProperty property)
}
return dict;
}
-
static void SetPropertyValueArray(SerializedProperty property, object v)
{
object[] array = (object[])v;
@@ -508,7 +312,6 @@ static void SetPropertyValueArray(SerializedProperty property, object v)
SetPropertyValue(item, array[i]);
}
}
-
static void SetPropertyValueGeneric(SerializedProperty property, object v)
{
Dictionary dict = (Dictionary)v;
@@ -523,7 +326,6 @@ static void SetPropertyValueGeneric(SerializedProperty property, object v)
} while (iterator.Next(false) && iterator.propertyPath != end.propertyPath);
}
}
-
static bool ComparePropertyValues(object value1, object value2)
{
if (value1 is Dictionary && value2 is Dictionary)
@@ -537,7 +339,6 @@ static bool ComparePropertyValues(object value1, object value2)
return object.Equals(value1, value2);
}
}
-
static bool CompareDictionaries(Dictionary dict1, Dictionary dict2)
{
if (dict1.Count != dict2.Count)
@@ -558,21 +359,6 @@ static bool CompareDictionaries(Dictionary dict1, Dictionary EnumerateEntries(SerializedProperty keyArrayProperty, SerializedProperty valueArrayProperty, int startIndex = 0)
{
if (keyArrayProperty.arraySize > startIndex)
@@ -591,21 +377,200 @@ static IEnumerable EnumerateEntries(SerializedProperty keyArra
&& !SerializedProperty.EqualContents(keyProperty, endProperty));
}
}
- }
- [CustomPropertyDrawer(typeof(SerializableDictionaryBase.Storage), true)]
- public class SerializableDictionaryStoragePropertyDrawer : PropertyDrawer
- {
+
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
- property.Next(true);
- EditorGUI.PropertyField(position, property, label, true);
- }
+ label = EditorGUI.BeginProperty(position, label, property);
+
+ Action buttonAction = Action.None;
+ int buttonActionIndex = 0;
+
+ var keyArrayProperty = property.FindPropertyRelative(KeysFieldName);
+ var valueArrayProperty = property.FindPropertyRelative(ValuesFieldName);
+
+ ConflictState conflictState = GetConflictState(property);
+
+ if (conflictState.conflictIndex != -1)
+ {
+ keyArrayProperty.InsertArrayElementAtIndex(conflictState.conflictIndex);
+ var keyProperty = keyArrayProperty.GetArrayElementAtIndex(conflictState.conflictIndex);
+ SetPropertyValue(keyProperty, conflictState.conflictKey);
+ keyProperty.isExpanded = conflictState.conflictKeyPropertyExpanded;
+
+ if (valueArrayProperty != null)
+ {
+ valueArrayProperty.InsertArrayElementAtIndex(conflictState.conflictIndex);
+ var valueProperty = valueArrayProperty.GetArrayElementAtIndex(conflictState.conflictIndex);
+ SetPropertyValue(valueProperty, conflictState.conflictValue);
+ valueProperty.isExpanded = conflictState.conflictValuePropertyExpanded;
+ }
+ }
+
+ var buttonWidth = s_buttonStyle.CalcSize(s_iconPlus).x;
+
+ var labelPosition = position;
+ labelPosition.height = EditorGUIUtility.singleLineHeight;
+ if (property.isExpanded)
+ labelPosition.xMax -= s_buttonStyle.CalcSize(s_iconPlus).x;
+
+ // Modify label to include count
+ var newLabel = new GUIContent($"{label.text} ({keyArrayProperty.arraySize})");
+
+ EditorGUI.PropertyField(labelPosition, property, newLabel, false);
+ // property.isExpanded = EditorGUI.Foldout(labelPosition, property.isExpanded, label);
+ if (property.isExpanded)
+ {
+ var buttonPosition = position;
+ buttonPosition.xMin = buttonPosition.xMax - buttonWidth;
+ buttonPosition.height = EditorGUIUtility.singleLineHeight;
+ EditorGUI.BeginDisabledGroup(conflictState.conflictIndex != -1);
+ if (GUI.Button(buttonPosition, s_iconPlus, s_buttonStyle))
+ {
+ buttonAction = Action.Add;
+ buttonActionIndex = keyArrayProperty.arraySize;
+ }
+ EditorGUI.EndDisabledGroup();
+
+ EditorGUI.indentLevel++;
+ var linePosition = position;
+ linePosition.y += EditorGUIUtility.singleLineHeight;
+ linePosition.xMax -= buttonWidth;
+
+ foreach (var entry in EnumerateEntries(keyArrayProperty, valueArrayProperty))
+ {
+ var keyProperty = entry.keyProperty;
+ var valueProperty = entry.valueProperty;
+ int i = entry.index;
+
+ float lineHeight = DrawKeyValueLine(keyProperty, valueProperty, linePosition, i);
+
+ buttonPosition = linePosition;
+ buttonPosition.x = linePosition.xMax;
+ buttonPosition.height = EditorGUIUtility.singleLineHeight;
+ if (GUI.Button(buttonPosition, s_iconMinus, s_buttonStyle))
+ {
+ buttonAction = Action.Remove;
+ buttonActionIndex = i;
+ }
+
+ if (i == conflictState.conflictIndex && conflictState.conflictOtherIndex == -1)
+ {
+ var iconPosition = linePosition;
+ iconPosition.size = s_buttonStyle.CalcSize(s_warningIconNull);
+ GUI.Label(iconPosition, s_warningIconNull);
+ }
+ else if (i == conflictState.conflictIndex)
+ {
+ var iconPosition = linePosition;
+ iconPosition.size = s_buttonStyle.CalcSize(s_warningIconConflict);
+ GUI.Label(iconPosition, s_warningIconConflict);
+ }
+ else if (i == conflictState.conflictOtherIndex)
+ {
+ var iconPosition = linePosition;
+ iconPosition.size = s_buttonStyle.CalcSize(s_warningIconOther);
+ GUI.Label(iconPosition, s_warningIconOther);
+ }
+
+
+ linePosition.y += lineHeight;
+ }
+
+ EditorGUI.indentLevel--;
+ }
+
+ if (buttonAction == Action.Add)
+ {
+ keyArrayProperty.InsertArrayElementAtIndex(buttonActionIndex);
+ if (valueArrayProperty != null)
+ valueArrayProperty.InsertArrayElementAtIndex(buttonActionIndex);
+ }
+ else if (buttonAction == Action.Remove)
+ {
+ DeleteArrayElementAtIndex(keyArrayProperty, buttonActionIndex);
+ if (valueArrayProperty != null)
+ DeleteArrayElementAtIndex(valueArrayProperty, buttonActionIndex);
+ }
+
+ conflictState.conflictKey = null;
+ conflictState.conflictValue = null;
+ conflictState.conflictIndex = -1;
+ conflictState.conflictOtherIndex = -1;
+ conflictState.conflictLineHeight = 0f;
+ conflictState.conflictKeyPropertyExpanded = false;
+ conflictState.conflictValuePropertyExpanded = false;
+
+ foreach (var entry1 in EnumerateEntries(keyArrayProperty, valueArrayProperty))
+ {
+ var keyProperty1 = entry1.keyProperty;
+ int i = entry1.index;
+ object keyProperty1Value = GetPropertyValue(keyProperty1);
+ if (keyProperty1Value == null)
+ {
+ var valueProperty1 = entry1.valueProperty;
+ SaveProperty(keyProperty1, valueProperty1, i, -1, conflictState);
+ DeleteArrayElementAtIndex(keyArrayProperty, i);
+ if (valueArrayProperty != null)
+ DeleteArrayElementAtIndex(valueArrayProperty, i);
+
+ break;
+ }
+
+
+ foreach (var entry2 in EnumerateEntries(keyArrayProperty, valueArrayProperty, i + 1))
+ {
+ var keyProperty2 = entry2.keyProperty;
+ int j = entry2.index;
+ object keyProperty2Value = GetPropertyValue(keyProperty2);
+
+ if (ComparePropertyValues(keyProperty1Value, keyProperty2Value))
+ {
+ var valueProperty2 = entry2.valueProperty;
+ SaveProperty(keyProperty2, valueProperty2, j, i, conflictState);
+ DeleteArrayElementAtIndex(keyArrayProperty, j);
+ if (valueArrayProperty != null)
+ DeleteArrayElementAtIndex(valueArrayProperty, j);
+
+ goto breakLoops;
+ }
+ }
+ }
+ breakLoops:
+
+ EditorGUI.EndProperty();
+ }
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
- property.Next(true);
- return EditorGUI.GetPropertyHeight(property);
+ float propertyHeight = EditorGUIUtility.singleLineHeight;
+
+ if (property.isExpanded)
+ {
+ var keysProperty = property.FindPropertyRelative(KeysFieldName);
+ var valuesProperty = property.FindPropertyRelative(ValuesFieldName);
+
+ foreach (var entry in EnumerateEntries(keysProperty, valuesProperty))
+ {
+ var keyProperty = entry.keyProperty;
+ var valueProperty = entry.valueProperty;
+ float keyPropertyHeight = EditorGUI.GetPropertyHeight(keyProperty);
+ float valuePropertyHeight = valueProperty != null ? EditorGUI.GetPropertyHeight(valueProperty) : 0f;
+ float lineHeight = Mathf.Max(keyPropertyHeight, valuePropertyHeight);
+ propertyHeight += lineHeight;
+ }
+
+ ConflictState conflictState = GetConflictState(property);
+
+ if (conflictState.conflictIndex != -1)
+ {
+ propertyHeight += conflictState.conflictLineHeight;
+ }
+ }
+
+ return propertyHeight;
}
}
+
+
}
\ No newline at end of file
diff --git a/Editor/Library/Vendor/SerializableDictionary/SerializableDictionaryPropertyDrawer.cs.meta b/Editor/Library/Drawers/MapDrawer.cs.meta
similarity index 100%
rename from Editor/Library/Vendor/SerializableDictionary/SerializableDictionaryPropertyDrawer.cs.meta
rename to Editor/Library/Drawers/MapDrawer.cs.meta
diff --git a/Editor/Library/Drawers/MapStorageDrawer.cs b/Editor/Library/Drawers/MapStorageDrawer.cs
new file mode 100644
index 00000000..e40d60e3
--- /dev/null
+++ b/Editor/Library/Drawers/MapStorageDrawer.cs
@@ -0,0 +1,21 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomPropertyDrawer(typeof(MapCore.Storage), true)]
+ public class MapStorageDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ property.Next(true);
+ EditorGUI.PropertyField(position, property, label, true);
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ property.Next(true);
+ return EditorGUI.GetPropertyHeight(property);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Library/Drawers/MapStorageDrawer.cs.meta b/Editor/Library/Drawers/MapStorageDrawer.cs.meta
new file mode 100644
index 00000000..95b23ff6
--- /dev/null
+++ b/Editor/Library/Drawers/MapStorageDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 22efdf0df2df5bf44a89841c2078e044
\ No newline at end of file
diff --git a/Editor/Library/MenuItem.meta b/Editor/Library/MenuItem.meta
new file mode 100644
index 00000000..528bfd28
--- /dev/null
+++ b/Editor/Library/MenuItem.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c42de7ea7ccb8124c81a1cca94b15c47
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Library/Vendor/UnityEditorIcons/EditorIcons.cs b/Editor/Library/MenuItem/EditorIconsMenu.cs
similarity index 99%
rename from Editor/Library/Vendor/UnityEditorIcons/EditorIcons.cs
rename to Editor/Library/MenuItem/EditorIconsMenu.cs
index 8c72e7e4..bd071a80 100644
--- a/Editor/Library/Vendor/UnityEditorIcons/EditorIcons.cs
+++ b/Editor/Library/MenuItem/EditorIconsMenu.cs
@@ -10,7 +10,7 @@ namespace RealMethod.Editor
{
#if UNITY_EDITOR
- public class EditorIcons : EditorWindow
+ public class EditorIconsMenu : EditorWindow
{
[MenuItem("Tools/RealMethod/Vendor/EditorIcons")]
public static void EditorIconsOpen()
@@ -18,7 +18,7 @@ public static void EditorIconsOpen()
#if UNITY_2018
var w = GetWindow("Editor Icons");
#else
- var w = CreateWindow("Editor Icons");
+ var w = CreateWindow("Editor Icons");
#endif
w.ShowUtility();
w.minSize = new Vector2(320, 450);
diff --git a/Editor/Library/Vendor/UnityEditorIcons/EditorIcons.cs.meta b/Editor/Library/MenuItem/EditorIconsMenu.cs.meta
similarity index 100%
rename from Editor/Library/Vendor/UnityEditorIcons/EditorIcons.cs.meta
rename to Editor/Library/MenuItem/EditorIconsMenu.cs.meta
diff --git a/Editor/Library/SharedScripts/Classes/EditorProperty.cs b/Editor/Library/SharedScripts/Classes/EditorProperty.cs
index 22cba318..2228ac59 100644
--- a/Editor/Library/SharedScripts/Classes/EditorProperty.cs
+++ b/Editor/Library/SharedScripts/Classes/EditorProperty.cs
@@ -3,16 +3,39 @@
using System.Collections.Generic;
using System.Reflection;
+
namespace RealMethod.Editor
{
- // Base EditorProperty Class
- // This class is used to create custom editor properties that can be rendered in the Unity Editor.
+ ///
+ /// Base class responsible for rendering a property in the Unity Editor
+ /// and handling potential validation errors with optional fix actions.
+ ///
public abstract class EditorProperty
{
- protected Object Owner;
+ ///
+ /// Holds the current error state for this property.
+ /// If not null, the property will render an error instead of its normal UI.
+ ///
+ private ErrorAction PropertyError;
+
+
+ ///
+ /// The Unity object that owns this property.
+ /// Usually a MonoBehaviour, ScriptableObject, or other UnityEngine.Object.
+ ///
+ public Object Owner { get; private set; }
+ ///
+ /// Name of the property being rendered.
+ /// Used for identification and debugging.
+ ///
public string PropertyName { get; private set; }
- private ErrorAction PropertyError = null;
+
+ ///
+ /// Creates a new editor property renderer.
+ ///
+ /// Name of the property.
+ /// Object that owns the property.
public EditorProperty(string _Name, Object _Owner)
{
PropertyName = _Name;
@@ -24,9 +47,17 @@ public EditorProperty(string _Name, Object _Owner)
}
}
+
+ ///
+ /// Renders the property in the inspector.
+ /// If the property has an error, the error UI is rendered instead.
+ ///
+ ///
+ /// A byte result defined by the implementation (usually used for change flags or state).
+ ///
public byte Render()
{
- if (PropertyError == null)
+ if (!PropertyError.IsValid)
{
return UpdateRender();
}
@@ -36,38 +67,144 @@ public byte Render()
return 0;
}
}
-
+ ///
+ /// Registers an error for this property and provides a fix callback.
+ /// When an error exists, normal rendering is replaced with an error UI.
+ ///
+ /// Error message shown in the inspector.
+ /// Identifier used to determine which fix action to apply.
protected void Error(string message, int id)
{
- PropertyError = new ErrorAction(message, id, FixError);
+ PropertyError.Create(message, id, FixError);
}
+
+ ///
+ /// Implemented by derived classes to render the property UI.
+ /// Called only when no error is active.
+ ///
protected abstract byte UpdateRender();
+ ///
+ /// Called when the user activates the fix action from an error message.
+ ///
+ /// Identifier of the error that should be fixed.
protected abstract void FixError(int Id);
}
+ ///
+ /// Generic editor property wrapper that stores and manages a value of type .
+ ///
+ /// This class extends and adds value storage,
+ /// comparison operators, and implicit conversion for easier usage in editor code.
+ ///
+ /// It is typically used by custom inspector systems to track a property's
+ /// current value and optionally compare against a cached value to detect changes.
+ ///
+ /// Type of the property value.
public abstract class EditorProperty : EditorProperty
{
+ ///
+ /// Returns true if the current value is valid (not null).
+ /// Mainly useful for reference types.
+ ///
public bool isvalid => CurrentValue != null;
+ ///
+ /// Current value of the property.
+ /// This is the active value used by the editor UI.
+ ///
protected T CurrentValue;
+ ///
+ /// Cached value used for change tracking or restoring previous state.
+ /// (Likely intended as "CacheValue".)
+ ///
protected T CashValue;
+ ///
+ /// Creates a new property without assigning a default value.
+ ///
+ /// Name of the property.
+ /// Owner Unity object.
public EditorProperty(string Name, Object other) : base(Name, other)
{
}
+ ///
+ /// Creates a new property with a default value.
+ /// The default is applied to both the current and cached values.
+ ///
+ /// Name of the property.
+ /// Owner Unity object.
+ /// Initial value assigned to the property.
public EditorProperty(string Name, Object other, T DefaultValue) : base(Name, other)
{
CurrentValue = DefaultValue;
CashValue = DefaultValue;
}
+ ///
+ /// Returns the current value of the property.
+ ///
public T GetValue()
{
return CurrentValue;
}
+ ///
+ /// Updates the current value of the property.
+ ///
+ /// New value to assign.
public void SetValue(T NewValue)
{
CurrentValue = NewValue;
}
+ // Operators
+ public static implicit operator T(EditorProperty property)
+ {
+ return property != null ? property.CurrentValue : default;
+ }
+ public static bool operator ==(EditorProperty a, EditorProperty b)
+ {
+ if (ReferenceEquals(a, b))
+ return true;
+
+ if (a is null || b is null)
+ return false;
+
+ return EqualityComparer.Default.Equals(a.CurrentValue, b.CurrentValue);
+ }
+ public static bool operator !=(EditorProperty a, EditorProperty b)
+ {
+ return !(a == b);
+ }
+ public static bool operator ==(EditorProperty a, T b)
+ {
+ if (a is null)
+ return false;
+
+ return EqualityComparer.Default.Equals(a.CurrentValue, b);
+ }
+ public static bool operator !=(EditorProperty a, T b)
+ {
+ return !(a == b);
+ }
+
+ // Overrides
+ ///
+ /// Determines equality between this property and another object.
+ /// Supports comparison with both EditorProperty<T> and raw values of type T.
+ ///
+ public override bool Equals(object obj)
+ {
+ if (obj is EditorProperty other)
+ return EqualityComparer.Default.Equals(CurrentValue, other.CurrentValue);
+
+ if (obj is T value)
+ return EqualityComparer.Default.Equals(CurrentValue, value);
+
+ return false;
+ }
+ public override int GetHashCode()
+ {
+ return CurrentValue?.GetHashCode() ?? 0;
+ }
+
}
public abstract class EditorPropertyList : EditorProperty
{
@@ -317,7 +454,7 @@ public EP_Dropdown(string Name, string[] options, Object other) : base(Name, oth
protected override byte UpdateRender()
{
- CashValue = EditorGUILayout.Popup("Ability Effect", CurrentValue, Options);
+ CashValue = EditorGUILayout.Popup($"{PropertyName}:", CurrentValue, Options);
if (CashValue == CurrentValue)
{
return 0; // No change
@@ -333,9 +470,9 @@ protected override void FixError(int Id)
throw new System.NotImplementedException();
}
}
- public class EP_ScriptableObject : EditorProperty where T : ScriptableObject
+ public class EP_Asset : EditorProperty where T : PrimitiveAsset
{
- public EP_ScriptableObject(string Name, Object other) : base(Name, other)
+ public EP_Asset(string Name, Object other) : base(Name, other)
{
CurrentValue = null;
CashValue = null;
@@ -359,9 +496,9 @@ protected override void FixError(int Id)
}
}
- public class EP_Class : EditorProperty where T : class
+ public class EP_Variable : EditorProperty where T : class
{
- public EP_Class(string Name, Object other) : base(Name, other)
+ public EP_Variable(string Name, Object other) : base(Name, other)
{
}
@@ -524,7 +661,6 @@ protected override void FixError(int Id)
}
-
// Storeable
// EditorProperty that can be stored in the MetaData
public abstract class EP_Storeable : EditorProperty
@@ -616,9 +752,9 @@ public List GetList()
}
/// Sample EP_Storeable
- public class EPS_ScriptableObjectList : EP_StoreableList where T : ScriptableObject
+ public class EPS_AssetList : EP_StoreableList where T : PrimitiveAsset
{
- public EPS_ScriptableObjectList(UnityEditor.Editor other, string Name) : base(other, Name)
+ public EPS_AssetList(UnityEditor.Editor other, string Name) : base(other, Name)
{
}
@@ -715,9 +851,6 @@ private string GetTargetPath(T Target)
return AssetDatabase.GetAssetPath(Target);
}
-
-
-
}
public class EPS_Enum : EP_Storeable where T : System.Enum
{
@@ -770,9 +903,9 @@ protected override void FixError(int Id)
{
}
}
- public class EPS_ScriptableObject : EP_Storeable where T : ScriptableObject
+ public class EPS_Asset : EP_Storeable where T : PrimitiveAsset
{
- public EPS_ScriptableObject(UnityEditor.Editor other, string Name) : base(other, Name)
+ public EPS_Asset(UnityEditor.Editor other, string Name) : base(other, Name)
{
}
diff --git a/Editor/Library/SharedScripts/Structs.meta b/Editor/Library/SharedScripts/Structs.meta
new file mode 100644
index 00000000..cf19f97d
--- /dev/null
+++ b/Editor/Library/SharedScripts/Structs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8f6e53f4684bb6f42bf96ae27ac86bb8
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Library/SharedScripts/Classes/ErrorAction.cs b/Editor/Library/SharedScripts/Structs/ErrorAction.cs
similarity index 70%
rename from Editor/Library/SharedScripts/Classes/ErrorAction.cs
rename to Editor/Library/SharedScripts/Structs/ErrorAction.cs
index d42bf7f2..316550af 100644
--- a/Editor/Library/SharedScripts/Classes/ErrorAction.cs
+++ b/Editor/Library/SharedScripts/Structs/ErrorAction.cs
@@ -4,13 +4,15 @@
namespace RealMethod.Editor
{
- public class ErrorAction
+ public struct ErrorAction
{
+ public bool IsValid => string.IsNullOrEmpty(ErrorMessage);
public string ErrorMessage { get; private set; }
private Action OnFixed;
- private int ID = 0;
+ private int ID;
- public ErrorAction(string message, int id, Action callback)
+
+ public void Create(string message, int id, Action callback)
{
ErrorMessage = message;
ID = id;
@@ -23,6 +25,7 @@ public void RenderError()
if (GUILayout.Button("Fix Issue"))
{
+ ErrorMessage = string.Empty;
OnFixed?.Invoke(ID);
}
}
diff --git a/Editor/Library/SharedScripts/Classes/ErrorAction.cs.meta b/Editor/Library/SharedScripts/Structs/ErrorAction.cs.meta
similarity index 100%
rename from Editor/Library/SharedScripts/Classes/ErrorAction.cs.meta
rename to Editor/Library/SharedScripts/Structs/ErrorAction.cs.meta
diff --git a/Editor/Library/Utilities/Assets.cs b/Editor/Library/Utilities/AssetsLibrary.cs
similarity index 85%
rename from Editor/Library/Utilities/Assets.cs
rename to Editor/Library/Utilities/AssetsLibrary.cs
index 4ac66790..77674045 100644
--- a/Editor/Library/Utilities/Assets.cs
+++ b/Editor/Library/Utilities/AssetsLibrary.cs
@@ -4,9 +4,9 @@
namespace RealMethod.Editor
{
- public class RM_Assets
+ public static class RM_Asset
{
- public static string GetSelectedAssetPath()
+ public static string GetSelectedAssetDirectory()
{
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
if (string.IsNullOrEmpty(path)) return "Assets";
diff --git a/Editor/Library/Utilities/Assets.cs.meta b/Editor/Library/Utilities/AssetsLibrary.cs.meta
similarity index 100%
rename from Editor/Library/Utilities/Assets.cs.meta
rename to Editor/Library/Utilities/AssetsLibrary.cs.meta
diff --git a/Editor/Library/Utilities/CSV.cs b/Editor/Library/Utilities/CSVLibrary.cs
similarity index 99%
rename from Editor/Library/Utilities/CSV.cs
rename to Editor/Library/Utilities/CSVLibrary.cs
index 834e05a2..63988eb6 100644
--- a/Editor/Library/Utilities/CSV.cs
+++ b/Editor/Library/Utilities/CSVLibrary.cs
@@ -10,7 +10,6 @@ public static string[] ParseCSVRow(string csvLine)
{
return ParseSingleLine(csvLine).ToArray();
}
-
public static List ParseCSV(string csvText)
{
List rows = new List();
@@ -24,7 +23,6 @@ public static List ParseCSV(string csvText)
return rows;
}
-
public static string[] ParseCSVToFlatArray(string csvText)
{
List cells = new List();
@@ -37,7 +35,6 @@ public static string[] ParseCSVToFlatArray(string csvText)
return cells.ToArray();
}
-
// This method parses a single line of CSV text and returns a list of strings.
private static List ParseSingleLine(string csvLine)
{
diff --git a/Editor/Library/Utilities/CSV.cs.meta b/Editor/Library/Utilities/CSVLibrary.cs.meta
similarity index 100%
rename from Editor/Library/Utilities/CSV.cs.meta
rename to Editor/Library/Utilities/CSVLibrary.cs.meta
diff --git a/Editor/Library/Utilities/Core.cs b/Editor/Library/Utilities/Core.cs
deleted file mode 100644
index e41574f2..00000000
--- a/Editor/Library/Utilities/Core.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.IO;
-using UnityEditor;
-using UnityEngine;
-
-namespace RealMethod.Editor
-{
- public static class RM_CoreEditor
- {
- public const string SetttingAssetPath = "Assets/Resources/RealMethod/RealMethodSetting.asset";
- public static string ScriptTemplatesPath => GetPackagePath("com.mustard.realmethod") + "/Reservoir/ScriptTemplates";
- public static string PrefabTemplatePath => GetPackagePath("com.mustard.realmethod") + "/Reservoir/Prefabs";
-
- private static string GetPackagePath(string packageName)
- {
- string[] guids = AssetDatabase.FindAssets("package", new[] { "Packages/" + packageName });
- foreach (string guid in guids)
- {
- string path = AssetDatabase.GUIDToAssetPath(guid);
- if (path.Contains(packageName))
- {
- string packagePath = Path.GetDirectoryName(path);
- while (!string.IsNullOrEmpty(packagePath))
- {
- if (File.Exists(Path.Combine(packagePath, "package.json")))
- return packagePath;
-
- packagePath = Path.GetDirectoryName(packagePath);
- }
- }
- }
-
- Debug.LogError($"Could not find package path for: {packageName}");
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Library/Utilities/Create.cs b/Editor/Library/Utilities/Create.cs
deleted file mode 100644
index 012366e5..00000000
--- a/Editor/Library/Utilities/Create.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using UnityEditor;
-using UnityEngine;
-using System.IO;
-
-namespace RealMethod.Editor
-{
- public static class RM_Create
- {
- public static string Script(string templateFileName, string defaultName, bool UseProject = false)
- {
- string templatePath = string.Empty;
- if (UseProject)
- {
- ProjectSettingAsset ProjectSetting = AssetDatabase.LoadAssetAtPath(RM_CoreEditor.SetttingAssetPath);
- templatePath = Path.Combine(ProjectSetting.FindAddres(ProjectSettingAsset.IdentityAsset.ScriptTemplate).Path, templateFileName);
- }
- else
- {
- templatePath = Path.Combine(RM_CoreEditor.ScriptTemplatesPath, templateFileName);
- }
-
-
- if (!File.Exists(templatePath))
- {
- Debug.LogError($"Template file not found: {templatePath}");
- return string.Empty;
- }
-
- string selectedPath = RM_Assets.GetSelectedAssetPath();
- string newScriptPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(selectedPath, defaultName));
-
- // Prompt user for script name before creating the file
- string inputName = EditorUtility.SaveFilePanel(
- "Create Script",
- selectedPath,
- Path.GetFileNameWithoutExtension(defaultName),
- "cs"
- );
-
- if (string.IsNullOrEmpty(inputName))
- return string.Empty;
-
- // Ensure the path is relative to the Assets folder
- if (inputName.StartsWith(Application.dataPath))
- newScriptPath = "Assets" + inputName.Substring(Application.dataPath.Length);
- else
- newScriptPath = inputName;
-
- string template = File.ReadAllText(templatePath);
- template = template.Replace("#SCRIPTNAME#", Path.GetFileNameWithoutExtension(newScriptPath));
- string projectName = Application.productName;
- template = template.Replace("#PROJECTNAME#", projectName);
-
- File.WriteAllText(newScriptPath, template);
- AssetDatabase.Refresh();
- Selection.activeObject = AssetDatabase.LoadAssetAtPath(newScriptPath);
- return newScriptPath;
- }
- public static GameObject Prefab(string prefabName, bool UseProject = false)
- {
-
- string prefabPath = string.Empty;
- if (UseProject)
- {
- ProjectSettingAsset ProjectSetting = AssetDatabase.LoadAssetAtPath(RM_CoreEditor.SetttingAssetPath);
- prefabPath = Path.Combine(ProjectSetting.FindAddres(ProjectSettingAsset.IdentityAsset.PrefabTemplate).Path, prefabName);
- }
- else
- {
- prefabPath = Path.Combine(RM_CoreEditor.PrefabTemplatePath, prefabName);
- }
-
- // Load the prefab from the specified path
- GameObject prefab = AssetDatabase.LoadAssetAtPath(prefabPath);
-
- if (prefab != null)
- {
- // Create an instance of the prefab in the scene
- GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
-
- // Register the creation in the undo system
- Undo.RegisterCreatedObjectUndo(instance, "Create " + instance.name);
-
- // Select the newly created instance
- Selection.activeObject = instance;
- return instance;
- }
- else
- {
- Debug.LogError("Prefab not found at path: " + prefabPath);
- return null;
- }
- }
- public static void GameObjectInScene(string Name = "GameObject") where T : Component
- {
- GameObject instance = new GameObject(Name);
- // Register the creation in the undo system
- Undo.RegisterCreatedObjectUndo(instance, "Create " + instance.name);
- instance.AddComponent();
- // Select the newly created instance
- Selection.activeObject = instance;
- }
- public static T ScriptableObj(string path) where T : ScriptableObject
- {
- // Create an instance of the ScriptableObject
- T asset = ScriptableObject.CreateInstance();
-
- // Ensure the directory exists
- string directory = System.IO.Path.GetDirectoryName(path);
- if (!System.IO.Directory.Exists(directory))
- {
- System.IO.Directory.CreateDirectory(directory);
- }
-
- // Save the asset
- AssetDatabase.CreateAsset(asset, path);
- AssetDatabase.SaveAssets();
-
- // Focus on the newly created asset in the Project window
- EditorUtility.FocusProjectWindow();
- Selection.activeObject = asset;
-
- Debug.Log($"ScriptableObject of type {typeof(T).Name} created and saved at: {path}");
-
- // Return the created asset
- return asset;
- }
- }
-}
-
diff --git a/Editor/Library/Utilities/CreateLibrary.cs b/Editor/Library/Utilities/CreateLibrary.cs
new file mode 100644
index 00000000..e938f9c6
--- /dev/null
+++ b/Editor/Library/Utilities/CreateLibrary.cs
@@ -0,0 +1,45 @@
+using UnityEditor;
+using UnityEngine;
+using System.IO;
+
+namespace RealMethod.Editor
+{
+ public static class RM_Create
+ {
+ public static void GameObject(string Name = "GameObject") where T : Component
+ {
+ GameObject instance = new GameObject(Name);
+ // Register the creation in the undo system
+ Undo.RegisterCreatedObjectUndo(instance, "Create " + instance.name);
+ instance.AddComponent();
+ // Select the newly created instance
+ Selection.activeObject = instance;
+ }
+ public static T Asset(string path) where T : PrimitiveAsset
+ {
+ // Create an instance of the PrimitiveAsset
+ T asset = ScriptableObject.CreateInstance();
+
+ // Ensure the directory exists
+ string directory = Path.GetDirectoryName(path);
+ if (!Directory.Exists(directory))
+ {
+ Directory.CreateDirectory(directory);
+ }
+
+ // Save the asset
+ AssetDatabase.CreateAsset(asset, path);
+ AssetDatabase.SaveAssets();
+
+ // Focus on the newly created asset in the Project window
+ EditorUtility.FocusProjectWindow();
+ Selection.activeObject = asset;
+
+ Debug.Log($"PrimitiveAsset of type {typeof(T).Name} created and saved at: {path}");
+
+ // Return the created asset
+ return asset;
+ }
+ }
+}
+
diff --git a/Editor/Library/Utilities/Create.cs.meta b/Editor/Library/Utilities/CreateLibrary.cs.meta
similarity index 100%
rename from Editor/Library/Utilities/Create.cs.meta
rename to Editor/Library/Utilities/CreateLibrary.cs.meta
diff --git a/Editor/Library/Utilities/MetaDataHandler.cs b/Editor/Library/Utilities/MetaDataLibrary.cs
similarity index 90%
rename from Editor/Library/Utilities/MetaDataHandler.cs
rename to Editor/Library/Utilities/MetaDataLibrary.cs
index b6fc635c..caf091b5 100644
--- a/Editor/Library/Utilities/MetaDataHandler.cs
+++ b/Editor/Library/Utilities/MetaDataLibrary.cs
@@ -9,7 +9,7 @@ public static class RM_MetaData
{
private static string GetMetaFilePath(string assetPath) => assetPath + ".meta";
- // 🔹 Automatically determines the mode (Text in Editor, Binary in Play Mode)
+ //Automatically determines the mode (Text in Editor, Binary in Play Mode)
private static bool UseBinaryMode
{
get
@@ -18,7 +18,7 @@ private static bool UseBinaryMode
}
}
- // 🔹 Save metadata (Auto-Switch)
+ //Save metadata (Auto-Switch)
public static void SaveCustomMetadata(string assetPath, string key, string value)
{
string metaFilePath = GetMetaFilePath(assetPath);
@@ -35,7 +35,7 @@ public static void SaveCustomMetadata(string assetPath, string key, string value
SaveTextMetadata(metaFilePath, key, value);
}
- // 🔹 Load metadata (Auto-Switch)
+ //Load metadata (Auto-Switch)
public static string LoadCustomMetadata(string assetPath, string key)
{
string metaFilePath = GetMetaFilePath(assetPath);
@@ -48,14 +48,14 @@ public static string LoadCustomMetadata(string assetPath, string key)
return UseBinaryMode ? LoadBinaryMetadata(metaFilePath, key) : LoadTextMetadata(metaFilePath, key);
}
- // 🔹 Check if metadata exists
+ //Check if metadata exists
public static bool HasMetadata(string assetPath, string key)
{
string metaFilePath = GetMetaFilePath(assetPath);
return File.Exists(metaFilePath) && File.ReadAllText(metaFilePath).Contains($"{key}:");
}
- // 🔹 Delete metadata entry
+ //Delete metadata entry
public static void DeleteMetadata(string assetPath, string key)
{
string metaFilePath = GetMetaFilePath(assetPath);
@@ -65,7 +65,7 @@ public static void DeleteMetadata(string assetPath, string key)
File.WriteAllLines(metaFilePath, Array.FindAll(lines, line => !line.StartsWith($"{key}:")));
}
- // 🔹 Save Text Metadata
+ //Save Text Metadata
private static void SaveTextMetadata(string metaFilePath, string key, string value)
{
string[] lines = File.ReadAllLines(metaFilePath);
@@ -85,7 +85,7 @@ private static void SaveTextMetadata(string metaFilePath, string key, string val
else File.WriteAllLines(metaFilePath, lines);
}
- // 🔹 Load Text Metadata
+ //Load Text Metadata
private static string LoadTextMetadata(string metaFilePath, string key)
{
foreach (string line in File.ReadAllLines(metaFilePath))
@@ -96,7 +96,7 @@ private static string LoadTextMetadata(string metaFilePath, string key)
return null;
}
- // 🔹 Save Binary Metadata
+ //Save Binary Metadata
private static void SaveBinaryMetadata(string metaFilePath, string key, string value)
{
using (BinaryWriter writer = new BinaryWriter(File.Open(metaFilePath, FileMode.Append)))
@@ -106,7 +106,7 @@ private static void SaveBinaryMetadata(string metaFilePath, string key, string v
}
}
- // 🔹 Load Binary Metadata
+ //Load Binary Metadata
private static string LoadBinaryMetadata(string metaFilePath, string key)
{
using (BinaryReader reader = new BinaryReader(File.Open(metaFilePath, FileMode.Open)))
diff --git a/Editor/Library/Utilities/MetaDataHandler.cs.meta b/Editor/Library/Utilities/MetaDataLibrary.cs.meta
similarity index 100%
rename from Editor/Library/Utilities/MetaDataHandler.cs.meta
rename to Editor/Library/Utilities/MetaDataLibrary.cs.meta
diff --git a/Editor/Library/Vendor/UnityEditorIcons.meta b/Editor/Library/Vendor/UnityEditorIcons.meta
deleted file mode 100644
index 5a74db56..00000000
--- a/Editor/Library/Vendor/UnityEditorIcons.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: b053aa00d882df041a089f1bd0dffd26
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Editor/Pattern/DataAssets.meta b/Editor/Pattern/DataAssets.meta
deleted file mode 100644
index 9b782dc5..00000000
--- a/Editor/Pattern/DataAssets.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 8353593eea5c6884ea594f163d264236
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Editor/Pattern/Inspectors.meta b/Editor/Pattern/Inspectors.meta
new file mode 100644
index 00000000..04fcdba6
--- /dev/null
+++ b/Editor/Pattern/Inspectors.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8e1de2e7481e79942ad4d69f21a3c713
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Pattern/Manager/CompositManagerCompWindow.cs b/Editor/Pattern/Inspectors/CompositManagerEditor.cs
similarity index 95%
rename from Editor/Pattern/Manager/CompositManagerCompWindow.cs
rename to Editor/Pattern/Inspectors/CompositManagerEditor.cs
index 7f44592c..6bcfc77a 100644
--- a/Editor/Pattern/Manager/CompositManagerCompWindow.cs
+++ b/Editor/Pattern/Inspectors/CompositManagerEditor.cs
@@ -1,10 +1,10 @@
using UnityEditor;
using UnityEngine;
-namespace RealMethod
+namespace RealMethod.Editor
{
[CustomEditor(typeof(CompositManager), true)]
- public class CompositManagerCompWindow : UnityEditor.Editor
+ public class CompositManagerEditor : UnityEditor.Editor
{
private CompositManager BaseComponent;
diff --git a/Editor/Pattern/Manager/CompositManagerCompWindow.cs.meta b/Editor/Pattern/Inspectors/CompositManagerEditor.cs.meta
similarity index 100%
rename from Editor/Pattern/Manager/CompositManagerCompWindow.cs.meta
rename to Editor/Pattern/Inspectors/CompositManagerEditor.cs.meta
diff --git a/Editor/Pattern/Inspectors/DeveloperManagerEditor.cs b/Editor/Pattern/Inspectors/DeveloperManagerEditor.cs
new file mode 100644
index 00000000..33a2b4aa
--- /dev/null
+++ b/Editor/Pattern/Inspectors/DeveloperManagerEditor.cs
@@ -0,0 +1,39 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomEditor(typeof(DeveloperManager), true)]
+ public class DeveloperManagerEditor : UnityEditor.Editor
+ {
+ private DeveloperManager Comp;
+ private void OnEnable()
+ {
+ Comp = (DeveloperManager)target;
+ }
+
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+ EditorGUILayout.Space();
+ EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
+ EditorGUILayout.BeginHorizontal();
+ if (GUILayout.Button("Open"))
+ {
+ Comp.Open();
+ }
+ if (GUILayout.Button("Close"))
+ {
+ Comp.Close();
+ }
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.LabelField($"Status: {IsOpen()}");
+ }
+
+
+ private string IsOpen()
+ {
+ return Comp.IsOpen ? "Open" : "Close";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Pattern/Inspectors/DeveloperManagerEditor.cs.meta b/Editor/Pattern/Inspectors/DeveloperManagerEditor.cs.meta
new file mode 100644
index 00000000..f86534d1
--- /dev/null
+++ b/Editor/Pattern/Inspectors/DeveloperManagerEditor.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 0d75ebb150273ea4c8884e5b7438b491
\ No newline at end of file
diff --git a/Editor/Pattern/DataAssets/FactoryEditor.cs b/Editor/Pattern/Inspectors/FactoryAssetEditor.cs
similarity index 96%
rename from Editor/Pattern/DataAssets/FactoryEditor.cs
rename to Editor/Pattern/Inspectors/FactoryAssetEditor.cs
index 5d29cdaa..ac749a84 100644
--- a/Editor/Pattern/DataAssets/FactoryEditor.cs
+++ b/Editor/Pattern/Inspectors/FactoryAssetEditor.cs
@@ -5,7 +5,7 @@
namespace RealMethod.Editor
{
[CustomEditor(typeof(FactoryAsset), true)]
- public class FactoryEditor : UnityEditor.Editor
+ public class FactoryAssetEditor : UnityEditor.Editor
{
private FactoryAsset TargetAsset;
private string[] actionNames;
diff --git a/Editor/Pattern/DataAssets/FactoryEditor.cs.meta b/Editor/Pattern/Inspectors/FactoryAssetEditor.cs.meta
similarity index 100%
rename from Editor/Pattern/DataAssets/FactoryEditor.cs.meta
rename to Editor/Pattern/Inspectors/FactoryAssetEditor.cs.meta
diff --git a/Editor/Pattern/DataAssets/ResourcEditor.cs b/Editor/Pattern/Inspectors/ResourcAssetEditor.cs
similarity index 97%
rename from Editor/Pattern/DataAssets/ResourcEditor.cs
rename to Editor/Pattern/Inspectors/ResourcAssetEditor.cs
index c578f720..55b8d1ad 100644
--- a/Editor/Pattern/DataAssets/ResourcEditor.cs
+++ b/Editor/Pattern/Inspectors/ResourcAssetEditor.cs
@@ -4,7 +4,7 @@
namespace RealMethod.Editor
{
[CustomEditor(typeof(ResourcAsset<>), true)]
- public class ResourcEditor : UnityEditor.Editor
+ public class ResourcAssetEditor : UnityEditor.Editor
{
private object baseComponent;
private System.Type targetType;
diff --git a/Editor/Pattern/DataAssets/ResourcEditor.cs.meta b/Editor/Pattern/Inspectors/ResourcAssetEditor.cs.meta
similarity index 100%
rename from Editor/Pattern/DataAssets/ResourcEditor.cs.meta
rename to Editor/Pattern/Inspectors/ResourcAssetEditor.cs.meta
diff --git a/Editor/Pattern/Inspectors/SaveManagerEditor.cs b/Editor/Pattern/Inspectors/SaveManagerEditor.cs
new file mode 100644
index 00000000..bf3653c3
--- /dev/null
+++ b/Editor/Pattern/Inspectors/SaveManagerEditor.cs
@@ -0,0 +1,43 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomEditor(typeof(SaveManager), true)]
+ public class SaveManagerEditor : UnityEditor.Editor
+ {
+ private SaveManager Component;
+ private bool IsShowLoadedFile = true;
+
+ private void OnEnable()
+ {
+ Component = (SaveManager)target;
+ }
+
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+ if (!Component.IsInSingleFile)
+ {
+ EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
+ IsShowLoadedFile = EditorGUILayout.Foldout(IsShowLoadedFile, "Files", true, EditorStyles.foldoutHeader);
+ if (IsShowLoadedFile)
+ {
+ IFile[] files = Component.GetAllFiles();
+ if (Component != null)
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ EditorGUILayout.LabelField($"{i}.[{files[i].FileName}]: {files[i].Self.GetType()}");
+ }
+ }
+ EditorGUILayout.Space();
+ EditorGUILayout.LabelField($"Total: {files.Length}");
+ }
+ }
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/Editor/Pattern/Manager/DataManagerCompWindow.cs.meta b/Editor/Pattern/Inspectors/SaveManagerEditor.cs.meta
similarity index 100%
rename from Editor/Pattern/Manager/DataManagerCompWindow.cs.meta
rename to Editor/Pattern/Inspectors/SaveManagerEditor.cs.meta
diff --git a/Editor/Pattern/Inspectors/TaskManagerEditor.cs b/Editor/Pattern/Inspectors/TaskManagerEditor.cs
new file mode 100644
index 00000000..9595a7c8
--- /dev/null
+++ b/Editor/Pattern/Inspectors/TaskManagerEditor.cs
@@ -0,0 +1,53 @@
+using System.Collections;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomEditor(typeof(TaskManager), true)]
+ public class TaskManagerEditor : UnityEditor.Editor
+ {
+ private TaskManager BaseComponent;
+ FieldInfo tasksField;
+
+ private void OnEnable()
+ {
+ BaseComponent = (TaskManager)target;
+ tasksField = target.GetType().GetField(
+ "Tasks",
+ BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public
+
+ );
+
+ }
+
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+ EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
+ if (BaseComponent != null)
+ {
+ if (BaseComponent.Count > 0)
+ {
+ IList tasks = tasksField.GetValue(target) as IList;
+ for (int i = 0; i < tasks.Count; i++)
+ {
+ object task = tasks[i];
+ if (task == null)
+ continue;
+ EditorGUILayout.LabelField($"{i}.{task.GetType().Name}", EditorStyles.boldLabel);
+ }
+ EditorGUILayout.Space();
+ EditorGUILayout.LabelField($"Total: {BaseComponent.Count}");
+ }
+
+ }
+
+
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/Editor/Pattern/Manager/TaskManagerCompWindow.cs.meta b/Editor/Pattern/Inspectors/TaskManagerEditor.cs.meta
similarity index 100%
rename from Editor/Pattern/Manager/TaskManagerCompWindow.cs.meta
rename to Editor/Pattern/Inspectors/TaskManagerEditor.cs.meta
diff --git a/Editor/Pattern/Manager.meta b/Editor/Pattern/Manager.meta
deleted file mode 100644
index f5bedd28..00000000
--- a/Editor/Pattern/Manager.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 9536b0ab30e69e9409f6c9e050b38995
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Editor/Pattern/Manager/DataManagerCompWindow.cs b/Editor/Pattern/Manager/DataManagerCompWindow.cs
deleted file mode 100644
index 28709107..00000000
--- a/Editor/Pattern/Manager/DataManagerCompWindow.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod
-{
- [CustomEditor(typeof(DataManager), true)]
- public class DataManagerCompWindow : UnityEditor.Editor
- {
- private DataManager BaseComponent;
-
- private void OnEnable()
- {
- BaseComponent = (DataManager)target;
- }
-
- public override void OnInspectorGUI()
- {
- base.OnInspectorGUI();
- EditorGUILayout.Space();
- EditorGUILayout.LabelField(" ----------------- History ----------------- ");
- if (BaseComponent != null)
- {
- if (BaseComponent.DataLog != null && BaseComponent.DataLog.Length > 0)
- {
- foreach (var item in BaseComponent.DataLog)
- {
- if (item != string.Empty)
- {
- EditorGUILayout.LabelField(item);
- }
- }
- }
- EditorGUILayout.Space();
- EditorGUILayout.LabelField($"TotalLog: {BaseComponent.Logindex}");
- }
-
-
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Pattern/Manager/TaskManagerCompWindow.cs b/Editor/Pattern/Manager/TaskManagerCompWindow.cs
deleted file mode 100644
index cd8e5427..00000000
--- a/Editor/Pattern/Manager/TaskManagerCompWindow.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using UnityEditor;
-
-namespace RealMethod
-{
- [CustomEditor(typeof(TaskManager), true)]
- public class TaskManagerCompWindow : UnityEditor.Editor
- {
- private TaskManager BaseComponent;
-
- private void OnEnable()
- {
- BaseComponent = (TaskManager)target;
- }
-
- public override void OnInspectorGUI()
- {
- base.OnInspectorGUI();
- EditorGUILayout.Space();
- EditorGUILayout.LabelField(" ----------------- Tasks ----------------- ");
- if (BaseComponent != null)
- {
- if (BaseComponent.Count > 0)
- {
- ITask[] tasks = BaseComponent.GetAllTasks();
- foreach (var task in tasks)
- {
- EditorGUILayout.LabelField($"{task}");
- }
- EditorGUILayout.Space();
- EditorGUILayout.LabelField($"Total: {tasks.Length}");
- }
-
- }
-
-
- }
- }
-
-
- [CustomEditor(typeof(TaskAsset), true)]
- public class TaskAssetCompWindow : UnityEditor.Editor
- {
- private TaskAsset BaseAsset;
-
- private void OnEnable()
- {
- BaseAsset = (TaskAsset)target;
- }
-
- public override void OnInspectorGUI()
- {
- base.OnInspectorGUI();
- EditorGUILayout.Space();
- EditorGUILayout.LabelField("Debug.... ");
- if (BaseAsset != null)
- {
- EditorGUILayout.LabelField($"Status: {CheckStatus(BaseAsset)}");
- if (BaseAsset is TaskBehaviour provider)
- {
- if (provider.IsInfinit)
- {
- EditorGUILayout.LabelField($"Time: Infinit");
- }
- else
- {
- EditorGUILayout.LabelField($"Time: {Math.Round(provider.ElapsedTime, 2)} ({Math.Round((1 - provider.NormalizedTime) * 100, 2)}%)");
- }
- }
-
- }
- }
-
-
- private string CheckStatus(TaskAsset task)
- {
- return task.IsEnable ? "Enable" : "Disable";
- }
- }
-
-
-
-
-}
\ No newline at end of file
diff --git a/Editor/Pattern/MenuItem.meta b/Editor/Pattern/MenuItem.meta
new file mode 100644
index 00000000..b13b520d
--- /dev/null
+++ b/Editor/Pattern/MenuItem.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2267a5fc0c3695047931a476d844fa6d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Pattern/MenuItem/PatternMenu.cs b/Editor/Pattern/MenuItem/PatternMenu.cs
new file mode 100644
index 00000000..8402b5ab
--- /dev/null
+++ b/Editor/Pattern/MenuItem/PatternMenu.cs
@@ -0,0 +1,149 @@
+
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class PatternMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Pattern;
+
+
+ ////////////// Scripts \\\\\\\\\\\\
+ // Managers
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/AudioManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateAudioManager()
+ {
+ RM_Editor.CreateScriptTemplate("AudioManager", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/CompositManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateCompositManager()
+ {
+ RM_Editor.CreateScriptTemplate("CompositManager", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/SaveManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateSaveManager()
+ {
+ RM_Editor.CreateScriptTemplate("SaveManager", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/GizmoManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateGizmoManager()
+ {
+ RM_Editor.CreateScriptTemplate("GizmoManager", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/UIManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateUIManager()
+ {
+ RM_Editor.CreateScriptTemplate("UIManager", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/MixerManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateMixerManager()
+ {
+ RM_Editor.CreateScriptTemplate("MixerManager", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/HapticManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateHapticManager()
+ {
+ RM_Editor.CreateScriptTemplate("HapticManager", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Manager/TickManager", false, RM_Editor.MenuOrder.Manager_Body)]
+ public static void CreateTickManager()
+ {
+ RM_Editor.CreateScriptTemplate("TickManager", MenuLayer);
+ }
+
+ // Services
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Service/StateService", false, RM_Editor.MenuOrder.Service_Body)]
+ public static void CreateStateService()
+ {
+ RM_Editor.CreateScriptTemplate("StateService", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Service/RuleService", false, RM_Editor.MenuOrder.Service_Body)]
+ public static void CreateRuleService()
+ {
+ RM_Editor.CreateScriptTemplate("RuleService", MenuLayer);
+ }
+
+ // Assets
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Data/Table", false, RM_Editor.MenuOrder.DataAsset_Body)]
+ public static void CreateTableAsset()
+ {
+ RM_Editor.CreateScriptTemplate("TableAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Data/Task", false, RM_Editor.MenuOrder.DataAsset_Body)]
+ public static void CreateTaskAsset()
+ {
+ RM_Editor.CreateScriptTemplate("TaskAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Config/Item", false, RM_Editor.MenuOrder.ConfigAsset_Body)]
+ public static void CreateItemConfig()
+ {
+ RM_Editor.CreateScriptTemplate("ItemConfig", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Config/Haptic", false, RM_Editor.MenuOrder.ConfigAsset_Body)]
+ public static void CreateHapticConfig()
+ {
+ RM_Editor.CreateScriptTemplate("HapticConfig", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/File/EmptyFileAsset", false, RM_Editor.MenuOrder.UniqueAsset_Body)]
+ public static void CreateFileAsset()
+ {
+ RM_Editor.CreateScriptTemplate("FileAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/File/Save", false, RM_Editor.MenuOrder.UniqueAsset_Body)]
+ public static void CreateSaveFile()
+ {
+ RM_Editor.CreateScriptTemplate("SaveFile", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/File/GameSetting", false, RM_Editor.MenuOrder.UniqueAsset_Body)]
+ public static void CreateGameSettingFile()
+ {
+ RM_Editor.CreateScriptTemplate("GameSettingFile", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Unique/SharedRootAsset", false, RM_Editor.MenuOrder.UniqueAsset_Body)]
+ public static void CreateSharedRootAsset()
+ {
+ RM_Editor.CreateScriptTemplate("SharedRootAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Asset/Unique/PoolAsset", false, RM_Editor.MenuOrder.UniqueAsset_Body)]
+ public static void CreatePoolAsset()
+ {
+ RM_Editor.CreateScriptTemplate("PoolAsset", MenuLayer);
+ }
+
+
+ // UI
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Method/UI/Widget", false, RM_Editor.MenuOrder.Method)]
+ public static void CreateWidget()
+ {
+ RM_Editor.CreateScriptTemplate("Widget", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Method/UI/WidgetToolkit", false, RM_Editor.MenuOrder.Method)]
+ public static void CreateWidgetToolkit()
+ {
+ RM_Editor.CreateScriptTemplate("WidgetToolkit", MenuLayer);
+ }
+
+ // Command
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Method/Command", false, RM_Editor.MenuOrder.Method)]
+ public static void CreateCommand()
+ {
+ RM_Editor.CreateScriptTemplate("Command", MenuLayer);
+ }
+
+ // Trigger
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Method/Trigger/Trigger3D", false, RM_Editor.MenuOrder.Method)]
+ public static void CreateTrigger3D()
+ {
+ RM_Editor.CreateScriptTemplate("Trigger3D", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Method/Trigger/Trigger2D", false, RM_Editor.MenuOrder.Method)]
+ public static void CreateTrigger2D()
+ {
+ RM_Editor.CreateScriptTemplate("Trigger2D", MenuLayer);
+ }
+
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Pattern/MenuItem/PatternMenu.cs.meta b/Editor/Pattern/MenuItem/PatternMenu.cs.meta
new file mode 100644
index 00000000..a00391b5
--- /dev/null
+++ b/Editor/Pattern/MenuItem/PatternMenu.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: b0e82e6f28f685a4481da01a36af2169
\ No newline at end of file
diff --git a/Editor/Pattern/Scripts.meta b/Editor/Pattern/Scripts.meta
new file mode 100644
index 00000000..e2c4f1f1
--- /dev/null
+++ b/Editor/Pattern/Scripts.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f5cd3bfd4d154e541a2b99bc9161a185
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Pattern/Scripts/AssetProcess.cs b/Editor/Pattern/Scripts/AssetProcess.cs
new file mode 100644
index 00000000..85393ee9
--- /dev/null
+++ b/Editor/Pattern/Scripts/AssetProcess.cs
@@ -0,0 +1,67 @@
+using UnityEngine;
+using UnityEditor;
+
+
+namespace RealMethod.Editor
+{
+ public abstract class AssetProcess
+ {
+ public AssetProcess()
+ {
+ Initialized();
+ }
+
+ protected abstract void Initialized();
+ public abstract void OnAssetImported(string AssetPath);
+ public abstract void OnAssetDeleted(string AssetPath);
+ public abstract void OnAssetMoved(string AssetPath, string FromPath);
+ public abstract void OnAssetClick(string AssetPath, Event e);
+ protected abstract string GetIconPath();
+ }
+ public abstract class AssetProcess : AssetProcess where T : Object
+ {
+ protected abstract void DoubleClick(T asset);
+
+ public override void OnAssetImported(string AssetPath)
+ {
+ T loadedAsset;
+ if (TryLoadAsset(AssetPath, out loadedAsset))
+ {
+ if (loadedAsset.GetType() == typeof(J))
+ {
+ // Load your icon from Resources (adjust the path as needed)
+ Texture2D icon = Resources.Load(GetIconPath());
+ if (icon != null)
+ {
+ EditorGUIUtility.SetIconForObject(loadedAsset, icon);
+ }
+ else
+ {
+ Debug.LogWarning("Custom icon not found. Please ensure the path and file are correct.");
+ }
+ }
+ }
+ else
+ {
+ Debug.LogWarning("Cant Load ");
+ }
+ }
+ public override void OnAssetClick(string AssetPath, Event e)
+ {
+ var asset = AssetDatabase.LoadAssetAtPath(AssetPath);
+
+ if (asset != null)
+ {
+ DoubleClick(asset);
+ e.Use(); // Consume the event
+ }
+ }
+
+ protected bool TryLoadAsset(string assetPath, out K asset) where K : Object
+ {
+ asset = AssetDatabase.LoadAssetAtPath(assetPath);
+ return asset != null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Editor/Pattern/Scripts/AssetProcess.cs.meta b/Editor/Pattern/Scripts/AssetProcess.cs.meta
new file mode 100644
index 00000000..0dc6766b
--- /dev/null
+++ b/Editor/Pattern/Scripts/AssetProcess.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 060b9dbad7dba424b9f55475deb3b39d
\ No newline at end of file
diff --git a/Editor/Pattern/Windows.meta b/Editor/Pattern/Windows.meta
new file mode 100644
index 00000000..66b6dc52
--- /dev/null
+++ b/Editor/Pattern/Windows.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 77cc5644be719ee4b8d874ef041e74a5
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Pattern/DataAssets/TableViewerWindow.cs b/Editor/Pattern/Windows/TableViewerWindow.cs
similarity index 100%
rename from Editor/Pattern/DataAssets/TableViewerWindow.cs
rename to Editor/Pattern/Windows/TableViewerWindow.cs
diff --git a/Editor/Pattern/DataAssets/TableViewerWindow.cs.meta b/Editor/Pattern/Windows/TableViewerWindow.cs.meta
similarity index 100%
rename from Editor/Pattern/DataAssets/TableViewerWindow.cs.meta
rename to Editor/Pattern/Windows/TableViewerWindow.cs.meta
diff --git a/Editor/ReadySet/Content/RealMethod_Prefab.cs b/Editor/ReadySet/Content/RealMethod_Prefab.cs
index 5227ed62..54cfc8b8 100644
--- a/Editor/ReadySet/Content/RealMethod_Prefab.cs
+++ b/Editor/ReadySet/Content/RealMethod_Prefab.cs
@@ -1,7 +1,7 @@
using RealMethod.Editor;
using UnityEditor;
-namespace RealMethod
+namespace RealMethod.Editor
{
class RealMethodPrefab
{
diff --git a/Editor/ReadySet/Content/RealMethod_ScriptTemplate.cs b/Editor/ReadySet/Content/RealMethod_ScriptTemplate.cs
deleted file mode 100644
index 5c017994..00000000
--- a/Editor/ReadySet/Content/RealMethod_ScriptTemplate.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class RealMethodScriptTemplate
- {
- // Essential
- [MenuItem("Assets/Create/Scripting/RealMethod/Essential/Game", false, 80)]
- public static void CreateGameClass()
- {
- string Path = RM_Create.Script("GameTemplate.txt", "MyGame.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Essential/World", false, 80)]
- public static void CreateWorld()
- {
- string Path = RM_Create.Script("WorldTemplate.txt", "MyWorld.cs");
- }
-
- // Managers
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/BaseManager", false, 80)]
- public static void CreateManager()
- {
- string Path = RM_Create.Script("ManagerTemplate.txt", "MyManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/AudioManager", false, 80)]
- public static void CreateAudioManager()
- {
- string Path = RM_Create.Script("AudioManagerTemplater.txt", "MyAudioManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/CompositManager", false, 80)]
- public static void CreateCompositManager()
- {
- string Path = RM_Create.Script("CompositManagerTemplate.txt", "MyCompositManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/DataManager", false, 80)]
- public static void CreateDataManager()
- {
- string Path = RM_Create.Script("DataManagerTemplate.txt", "MyDataManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/GizmoManager", false, 80)]
- public static void CreateGizmoManager()
- {
- string Path = RM_Create.Script("GizmoManagerTemplate.txt", "MyGizmoManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/UIManager", false, 80)]
- public static void CreateUIManager()
- {
- string Path = RM_Create.Script("UIManagerTemplate.txt", "MyUIManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/MixerManager", false, 80)]
- public static void CreateMixerManager()
- {
- string Path = RM_Create.Script("MixerManagerTemplate.txt", "MyMixerManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/HapticManager", false, 80)]
- public static void CreateHapticManager()
- {
- string Path = RM_Create.Script("HapticManagerTemplate.txt", "MyHapticManager.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Manager/TickManager", false, 80)]
- public static void CreateTickManager()
- {
- string Path = RM_Create.Script("TickManagerTemplate.txt", "MyTickManager.cs");
- }
-
-
- // Service
- [MenuItem("Assets/Create/Scripting/RealMethod/Service/BaseService", false, 80)]
- public static void CreateService()
- {
- string Path = RM_Create.Script("ServiceTemplate.txt", "MyServicec.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Service/GameService", false, 80)]
- public static void CreateGameServiceClass()
- {
- string Path = RM_Create.Script("GameServiceTemplate.txt", "MyGameService.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Service/StateService", false, 80)]
- public static void CreateStateService()
- {
- string Path = RM_Create.Script("StateServiceTemplate.txt", "MyStateService.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Service/RuleService", false, 80)]
- public static void CreateRuleService()
- {
- string Path = RM_Create.Script("RuleServiceTemplate.txt", "MyRuleService.cs");
- }
-
-
-
- // Assets
- // // Data
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Data/BaseData", false, 80)]
- public static void CreateDataAsset()
- {
- string Path = RM_Create.Script("DataAssetTemplate.txt", "MyDataAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Data/ItemAsset", false, 80)]
- public static void CreateItemAsset()
- {
- string Path = RM_Create.Script("ItemAssetTemplate.txt", "MyItemAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Data/TableAsset", false, 80)]
- public static void CreateTableAsset()
- {
- string Path = RM_Create.Script("TableTemplate.txt", "MyTableAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Data/Task", false, 80)]
- public static void CreateTaskAsset()
- {
- string Path = RM_Create.Script("TaskAssetTemplate.txt", "MyTaskAsset.cs");
- }
- // // Config
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Config/BaseConfig", false, 80)]
- public static void CreateConfigAsset()
- {
- string Path = RM_Create.Script("ConfigAssetTemplate.txt", "MyConfigAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Config/ItemConfig", false, 80)]
- public static void CreateItemConfig()
- {
- string Path = RM_Create.Script("ItemConfigTemplate.txt", "MyItemConfig.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Config/GameConfig", false, 80)]
- public static void CreateGameConfig()
- {
- string Path = RM_Create.Script("GameConfigTemplate.txt", "MyGameConfig.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Config/HapticConfig", false, 80)]
- public static void CreateHapticConfig()
- {
- string Path = RM_Create.Script("HapticConfigTemplate.txt", "MyHaptic.cs");
- }
- // // Files
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/File/BaseFile", false, 80)]
- public static void CreateFileAsset()
- {
- string Path = RM_Create.Script("FileAssetTemplate.txt", "MyFileAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/File/SaveFile", false, 80)]
- public static void CreateSaveFile()
- {
- string Path = RM_Create.Script("SaveFileTemplate.txt", "MySaveFile.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/File/GameSetting", false, 80)]
- public static void CreateGameSettingFile()
- {
- string Path = RM_Create.Script("GameSettingFileTemplate.txt", "GameSettingFile.cs");
- }
- // // Unique
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Unique/BaseUnique", false, 80)]
- public static void CreateUniqueAsset()
- {
- string Path = RM_Create.Script("UniqueAssetTemplate.txt", "MyFileAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Unique/SharedRootAsset", false, 80)]
- public static void CreateSharedRootAsset()
- {
- string Path = RM_Create.Script("SharedRootAssetTemplate.txt", "MySharedRootAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Asset/Unique/PoolAsset", false, 80)]
- public static void CreatePoolAsset()
- {
- string Path = RM_Create.Script("PoolAssetTemplate.txt", "MyPoolAsset.cs");
- }
-
- // General
- // // UI
- [MenuItem("Assets/Create/Scripting/RealMethod/General/UI/Widget", false, 80)]
- public static void CreateWidget()
- {
- string Path = RM_Create.Script("WidgetTemplate.txt", "MyWidget.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/General/UI/WidgetToolkit", false, 80)]
- public static void CreateWidgetToolkit()
- {
- string Path = RM_Create.Script("WidgetToolkitTemplate.txt", "MyWidgetToolkit.cs");
- }
- // // Command
- [MenuItem("Assets/Create/Scripting/RealMethod/General/Command", false, 80)]
- public static void CreateCommand()
- {
- string Path = RM_Create.Script("CommandTemplate.txt", "MyCommand.cs");
- }
- // // Trigger
- [MenuItem("Assets/Create/Scripting/RealMethod/General/Trigger/Trigger3D", false, 80)]
- public static void CreateTrigger3D()
- {
- string Path = RM_Create.Script("Trigger3DTemplate.txt", "MyTrigger.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/General/Trigger/Trigger2D", false, 80)]
- public static void CreateTrigger2D()
- {
- string Path = RM_Create.Script("Trigger2DTemplate.txt", "MyTrigger.cs");
- }
-
-
- // Editor
- [MenuItem("Assets/Create/Scripting/RealMethod/Editor/SettingSection", false, 80)]
- public static void CreateSettingSection()
- {
- string Path = RM_Create.Script("SettingSectionTemplate.txt", "MySection.cs");
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-}
\ No newline at end of file
diff --git a/Editor/ReadySet/Content/RealMethod_ScriptTemplate.cs.meta b/Editor/ReadySet/Content/RealMethod_ScriptTemplate.cs.meta
deleted file mode 100644
index 66206723..00000000
--- a/Editor/ReadySet/Content/RealMethod_ScriptTemplate.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: a58e933f91efb7f4192f2e164c491a85
\ No newline at end of file
diff --git a/Editor/ReadySet/Content/RealMethod_UnityAsset.cs b/Editor/ReadySet/Content/RealMethod_UnityAsset.cs
index 48c1cdee..635a67f9 100644
--- a/Editor/ReadySet/Content/RealMethod_UnityAsset.cs
+++ b/Editor/ReadySet/Content/RealMethod_UnityAsset.cs
@@ -2,7 +2,7 @@
namespace RealMethod.Editor
{
- public class Table_UnityAsset : AssetHandeler
+ public class Table_UnityAsset : AssetProcess
{
protected override void Initialized()
{
@@ -26,7 +26,7 @@ protected override void DoubleClick(TableAsset asset)
TableViewerWindow.OpenWindow(asset);
}
}
- public class WorldScene_UnityAsset : AssetHandeler
+ public class WorldAsset_UnityAsset : AssetProcess
{
protected override void Initialized()
{
@@ -44,12 +44,12 @@ protected override string GetIconPath()
{
return "Icons/Core/WorldSceneAsset";
}
- protected override void DoubleClick(WorldSceneConfig asset)
+ protected override void DoubleClick(WorldAsset asset)
{
asset.OnAssetClick();
}
}
- public class Game_UnityAsset : AssetHandeler
+ public class Game_UnityAsset : AssetProcess
{
protected override void Initialized()
{
@@ -69,7 +69,7 @@ protected override string GetIconPath()
}
protected override void DoubleClick(MonoScript asset)
{
-
+
}
}
diff --git a/Editor/ReadySet/Content/UnityAsset_Postprocessor.cs b/Editor/ReadySet/Content/UnityAsset_Postprocessor.cs
new file mode 100644
index 00000000..173e2a34
--- /dev/null
+++ b/Editor/ReadySet/Content/UnityAsset_Postprocessor.cs
@@ -0,0 +1,58 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public class UnityAsset_Postprocessor : AssetPostprocessor
+ {
+ private static AssetProcess[] AssetList = new AssetProcess[5]
+ {
+ new WorldAsset_UnityAsset(),
+ new Table_UnityAsset(),
+ new PCGResource_UnityAsset(),
+ new PCGGeneration_UnityAsset(),
+ new PCGCash_UnityAsset()
+ };
+
+ [InitializeOnLoadMethod]
+ private static void OnDoubleClickScriptableObject()
+ {
+ EditorApplication.projectWindowItemOnGUI += (guid, rect) =>
+ {
+ Event e = Event.current;
+ if (e.type == EventType.MouseDown && e.clickCount == 2)
+ {
+ string assetPath = AssetDatabase.GUIDToAssetPath(guid);
+ foreach (var asset in AssetList)
+ {
+ asset.OnAssetClick(assetPath, e);
+ }
+ }
+ };
+ }
+
+ // private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
+ // {
+ // if (AssetList == null)
+ // {
+ // return;
+ // }
+
+ // foreach (var asset in AssetList)
+ // {
+ // foreach (string assetPath in importedAssets)
+ // {
+ // asset.OnAssetImported(assetPath);
+ // }
+ // foreach (string assetPath in deletedAssets)
+ // {
+ // asset.OnAssetDeleted(assetPath);
+ // }
+ // for (int i = 0; i < movedAssets.Length; i++)
+ // {
+ // asset.OnAssetMoved(movedAssets[i], movedFromAssetPaths[i]);
+ // }
+ // }
+ // }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Core/ProjectSetting/UnityAsset_Postprocessor.cs.meta b/Editor/ReadySet/Content/UnityAsset_Postprocessor.cs.meta
similarity index 100%
rename from Editor/Core/ProjectSetting/UnityAsset_Postprocessor.cs.meta
rename to Editor/ReadySet/Content/UnityAsset_Postprocessor.cs.meta
diff --git a/Editor/ReadySet/Inspectors.meta b/Editor/ReadySet/Inspectors.meta
new file mode 100644
index 00000000..232a6b04
--- /dev/null
+++ b/Editor/ReadySet/Inspectors.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: dfdfee6ded1444748b9cf7cbeaa31b5d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/ReadySet/Inspectors/MotionAssetEditor.cs b/Editor/ReadySet/Inspectors/MotionAssetEditor.cs
new file mode 100644
index 00000000..eb9dfb69
--- /dev/null
+++ b/Editor/ReadySet/Inspectors/MotionAssetEditor.cs
@@ -0,0 +1,46 @@
+using System;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ [CustomEditor(typeof(MotionAsset), true)]
+ public class TaskAssetCompWindow : UnityEditor.Editor
+ {
+ private MotionAsset BaseAsset;
+
+ private void OnEnable()
+ {
+ BaseAsset = (MotionAsset)target;
+ }
+
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+ EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
+ EditorGUILayout.LabelField("Debug.... ");
+ if (BaseAsset != null)
+ {
+ EditorGUILayout.LabelField($"Status: {CheckStatus(BaseAsset)}");
+ if (BaseAsset is IHandleBehaviourAction provider)
+ {
+ if (provider.IsInfinit)
+ {
+ EditorGUILayout.LabelField($"Time: Infinit");
+ }
+ else
+ {
+ EditorGUILayout.LabelField($"Time: {Math.Round(provider.ElapsedTime, 2)} ({Math.Round((1 - provider.NormalizedTime) * 100, 2)}%)");
+ }
+ }
+
+ }
+ }
+
+
+ private string CheckStatus(MotionAsset task)
+ {
+ return task.IsEnable ? "Enable" : "Disable";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/ReadySet/Inspectors/MotionAssetEditor.cs.meta b/Editor/ReadySet/Inspectors/MotionAssetEditor.cs.meta
new file mode 100644
index 00000000..5043f2e5
--- /dev/null
+++ b/Editor/ReadySet/Inspectors/MotionAssetEditor.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 3cd743d5832d4f94a943b7e8e19a2042
\ No newline at end of file
diff --git a/Editor/ReadySet/Tools/AnimatorScriptGenerator.cs b/Editor/ReadySet/Tools/AnimatorScriptGenerator.cs
index b5d512fc..5c03c5c2 100644
--- a/Editor/ReadySet/Tools/AnimatorScriptGenerator.cs
+++ b/Editor/ReadySet/Tools/AnimatorScriptGenerator.cs
@@ -14,9 +14,9 @@ public class AnimatorScriptGenerator
public static void GenerateScriptsFromAnimators()
{
ProjectSettingAsset TargetStorage;
- if (ProjectSettingWindow.GetSettingStorage(out TargetStorage))
+ if (RM_Editor.TryGetSettingAsset(out TargetStorage))
{
- outputFolder = TargetStorage.FindAddres(ProjectSettingAsset.IdentityAsset.AnimatorParam).Path;
+ outputFolder = TargetStorage.GetFolderPathByType(ProjectSettingAsset.AssetFormat.Script) + "/General/AnimatorParam";
}
else
{
diff --git a/Editor/ReadySet/Tools/ClassViewerWindow.cs b/Editor/ReadySet/Tools/ClassViewerWindow.cs
new file mode 100644
index 00000000..f1cc3d76
--- /dev/null
+++ b/Editor/ReadySet/Tools/ClassViewerWindow.cs
@@ -0,0 +1,635 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.Reflection;
+using System.Text;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public class ClassViewerWindow : EditorWindow
+ {
+ private class FieldModule
+ {
+ private ClassViewerWindow MyOwner;
+ private MonoScript MyScript = null;
+ private List MyChilds = new List();
+ private string MyName = string.Empty;
+
+
+ public string Title
+ {
+ get
+ {
+ if (MyScript != null)
+ {
+ Type targetclass = MyScript.GetClass();
+ if (targetclass != null)
+ {
+ return MyScript.GetClass().Name;
+ }
+ else
+ {
+ return MyScript.name;
+ }
+ }
+ else
+ {
+ return MyName;
+ }
+ }
+ }
+ public bool HasFile => MyScript != null;
+ public MonoScript ScriptFile => MyScript;
+ public bool IsExpand { get; private set; } = false;
+
+
+ public FieldModule(ClassViewerWindow owner, string Name)
+ {
+ MyOwner = owner;
+ MyName = Name;
+ }
+ public FieldModule(ClassViewerWindow owner, MonoScript script)
+ {
+ MyOwner = owner;
+ MyScript = script;
+ }
+
+
+ public void Draw()
+ {
+ if (MyScript != null)
+ {
+ if (MyScript.GetClass() == null)
+ return;
+ }
+
+ EditorGUILayout.BeginHorizontal();
+ DrawField();
+ EditorGUILayout.EndHorizontal();
+ if (IsExpand)
+ {
+ EditorGUI.indentLevel++;
+ foreach (var child in MyChilds)
+ {
+ child.Draw();
+ }
+ EditorGUI.indentLevel--;
+ }
+ }
+ public void AddChild(FieldModule ChildModule)
+ {
+ if (ChildModule == null)
+ {
+ Print("ChildModule is not valid!");
+ return;
+ }
+ MyChilds.Add(ChildModule);
+ }
+ public void AddChild(MonoScript File)
+ {
+ Type NewType = File.GetClass();
+ if (NewType == null || NewType.Namespace == null)
+ {
+ Print($"MonoScript does't have have any 'MainClass'or'NameSpace' for Child[{File.name}]");
+ return;
+ }
+
+ FieldModule NewModule = new FieldModule(MyOwner, File);
+ FieldModule ParentField = TraverseHierarchy(File.GetClass(), true);
+
+ if (ParentField.TryFindField(NewModule.Title, out FieldModule result))
+ {
+ if (!result.HasFile)
+ {
+ result.SetFileScript(File);
+ }
+ }
+ else
+ {
+ ParentField.AddChild(NewModule);
+ }
+
+ }
+ public void Expand()
+ {
+ IsExpand = true;
+ for (int i = 2; i < MyChilds.Count; i++)
+ {
+ MyChilds[i].SortChild();
+ }
+ }
+
+
+ private void DrawField()
+ {
+ Color old = GUI.color;
+ if (!HasFile)
+ {
+ GUI.color = new Color(0.9f, 0.9f, 0.9f);
+ }
+
+ // Write Name as Label or Foldout
+ if (MyChilds.Count == 0)
+ {
+ EditorGUILayout.LabelField(Title, GUILayout.Width(300));
+ IsExpand = false;
+ }
+ else
+ {
+ IsExpand = EditorGUILayout.Foldout(IsExpand, Title, true);
+ }
+
+ // Add Button
+ if (MyScript)
+ {
+ if (GUILayout.Button("INFO ", EditorStyles.linkLabel))
+ {
+ MyOwner.SelectedScript = MyScript;
+ }
+ if (MyScript != null)
+ {
+ if (GUILayout.Button("OpenFile ", EditorStyles.linkLabel))
+ {
+ AssetDatabase.OpenAsset(MyScript);
+ }
+ }
+ }
+ GUI.color = old;
+ }
+ private FieldModule TraverseHierarchy(Type Target, bool ReturnParent = false)
+ {
+ FieldModule ParentField = null;
+ Type ParentChildType = Target.BaseType;
+ if (ParentChildType != null)
+ {
+ if (ParentChildType.Namespace == Target.Namespace)
+ {
+ //Recursive
+ ParentField = TraverseHierarchy(ParentChildType);
+ }
+ }
+ if (ParentField == null)
+ {
+ ParentField = GetOrCreateField(Target.Namespace, true);
+ if (Target.IsInterface)
+ {
+ ParentField = ParentField.GetOrCreateField("");
+ }
+ if (Target.IsValueType && !Target.IsEnum)
+ {
+ ParentField = ParentField.GetOrCreateField("");
+ }
+ }
+ return ReturnParent ? ParentField : ParentField.GetOrCreateField(Target.Name);
+ }
+ private void SetFileScript(MonoScript File)
+ {
+ MyScript = File;
+ }
+ private FieldModule GetOrCreateField(string title, bool IsNameSpace = false)
+ {
+ FieldModule Result = FindField(title);
+ if (Result == null)
+ {
+ Result = new FieldModule(MyOwner, title);
+ MyChilds.Add(Result);
+ if (IsNameSpace)
+ {
+ Result.AddChild(new FieldModule(MyOwner, ""));
+ Result.AddChild(new FieldModule(MyOwner, ""));
+ }
+ }
+ return Result;
+ }
+ private FieldModule FindField(string title)
+ {
+ foreach (var child in MyChilds)
+ {
+ if (child.Title == title)
+ { return child; }
+ }
+ return null;
+ }
+ private bool TryFindField(string title, out FieldModule module)
+ {
+ foreach (var child in MyChilds)
+ {
+ if (child.Title == title)
+ {
+ module = child;
+ return true;
+ }
+ }
+ module = null;
+ return false;
+ }
+ private void SortChild()
+ {
+ int fixedCount = 2;
+
+ var sortablePart = MyChilds.GetRange(fixedCount, MyChilds.Count - fixedCount);
+
+ sortablePart.Sort((a, b) => string.Compare(a.Title, b.Title, StringComparison.OrdinalIgnoreCase));
+
+ for (int i = 0; i < sortablePart.Count; i++)
+ {
+ MyChilds[fixedCount + i] = sortablePart[i];
+ }
+ }
+ private void Print(string message)
+ {
+ Debug.Log($"[{Title}]: {message}");
+ }
+ }
+ public class Ceckbox : EditorProperty
+ {
+ public Ceckbox(string Name, UnityEngine.Object other) : base(Name, other)
+ {
+ }
+
+
+ protected override byte UpdateRender()
+ {
+ CashValue = GUILayout.Toggle(CurrentValue, GUIContent.none, GUILayout.Width(18));
+ if (CashValue == CurrentValue)
+ {
+ return 0;
+ }
+ else
+ {
+ SetValue(CashValue);
+ return 1;
+ }
+ }
+ protected override void FixError(int Id)
+ {
+ }
+
+ }
+ private class ComboBox : EditorProperty where T : Enum
+ {
+ public ComboBox(string Name, UnityEngine.Object other) : base(Name, other)
+ {
+ }
+
+ protected override byte UpdateRender()
+ {
+ CashValue = (T)EditorGUILayout.EnumPopup(CurrentValue, GUI.skin.FindStyle("ToolbarPopup"), GUILayout.Width(120));
+ if (EqualityComparer.Default.Equals(CashValue, CurrentValue))
+ {
+ return 0; // No change
+ }
+ else
+ {
+ SetValue(CashValue);
+ return 1; // Changed
+ }
+ }
+ protected override void FixError(int Id)
+ {
+
+ }
+
+ }
+ private enum FilterType
+ {
+ All,
+ MonoBehaviour,
+ ScriptableObject,
+ Editor
+ }
+
+
+ private Vector2 scroll;
+ private MonoScript[] ProjectScripts;
+ private FieldModule Root;
+ private string search = string.Empty;
+ private ComboBox filter;
+ private Ceckbox AdvanceSerach;
+ private MonoScript SelectedScript;
+
+ public bool IsSearching
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(search))
+ return true;
+
+ if (filter.GetValue() != FilterType.All)
+ return true;
+
+ return false;
+ }
+ }
+
+
+ [MenuItem("Tools/RealMethod/Viewer/ClassViewer")]
+ public static void Open()
+ {
+ GetWindow("Class Viewer");
+ }
+ private void OnEnable()
+ {
+ filter = new ComboBox("Filter", this);
+ AdvanceSerach = new Ceckbox("Checkbox", this);
+ ProjectScripts = LoadScripts();
+ Preper();
+ }
+ private void OnGUI()
+ {
+ DrawToolbar();
+ scroll = EditorGUILayout.BeginScrollView(scroll);
+ if (IsSearching)
+ {
+ DrawScriptList();
+ }
+ else
+ {
+ Root.Draw();
+ }
+ EditorGUILayout.EndScrollView();
+ if (SelectedScript != null)
+ {
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ EditorGUILayout.BeginHorizontal();
+ GUILayout.Label($"{SelectedScript.name}.cs");
+ if (GUILayout.Button(GUIContent.none, GUI.skin.FindStyle("ToolbarSearchCancelButton")))
+ {
+ SelectedScript = null;
+ }
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.TextArea(Analyze(SelectedScript), GUILayout.ExpandHeight(true));
+ EditorGUILayout.EndVertical();
+ }
+ EditorGUILayout.HelpBox(
+ " Note: This inspector uses reflection and can only detect the primary type in this script and its nested types. " +
+ "Additional classes, structs, enums, or interfaces declared outside the main type in the same file will not appear.",
+ MessageType.Info);
+ }
+
+
+
+ private void DrawToolbar()
+ {
+ EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
+
+ AdvanceSerach.Render();
+
+ search = GUILayout.TextField(
+ search,
+ GUI.skin.FindStyle("ToolbarSearchTextField"),
+ GUILayout.ExpandWidth(true)
+ );
+
+ if (GUILayout.Button(
+ GUIContent.none,
+ GUI.skin.FindStyle("ToolbarSearchCancelButton")))
+ {
+ search = "";
+ GUI.FocusControl(null);
+ }
+
+ filter.Render();
+
+ if (GUILayout.Button("Refresh", EditorStyles.toolbarButton, GUILayout.Width(70)))
+ {
+ search = "";
+ filter.SetValue(FilterType.All);
+ Root = null;
+ ProjectScripts = LoadScripts();
+ SelectedScript = null;
+ Preper();
+ }
+
+ EditorGUILayout.EndHorizontal();
+ }
+ private void DrawScriptList()
+ {
+ foreach (var script in ProjectScripts)
+ {
+ if (!PassSearch(script)) continue;
+ if (!PassFilter(script)) continue;
+
+ DrawScript(script);
+ }
+ }
+ private void DrawScript(MonoScript script)
+ {
+ Vector2 scroller = Vector2.zero;
+ Type type = script.GetClass();
+ string namespaceName = type?.Namespace ?? "No Namespace";
+
+ EditorGUILayout.BeginHorizontal();
+
+ GUILayout.Label($"{script.name}({namespaceName})", GUILayout.Width(400));
+
+ if (GUILayout.Button("INFO ", EditorStyles.linkLabel))
+ {
+ SelectedScript = script;
+ }
+
+ if (GUILayout.Button("OpenFile ", EditorStyles.linkLabel))
+ {
+ AssetDatabase.OpenAsset(script);
+ }
+
+ EditorGUILayout.EndHorizontal();
+ }
+ private bool PassSearch(MonoScript script)
+ {
+ if (string.IsNullOrEmpty(search)) return true;
+
+ string Result = string.Empty;
+ if (AdvanceSerach.GetValue())
+ {
+ Result = GetScriptInfo(script);
+ }
+ else
+ {
+ string type = script.GetClass() != null ? script.GetClass().Name : string.Empty;
+ Result = $"{script.name},{type}";
+ }
+
+ return Result.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0;
+
+ }
+ private bool PassFilter(MonoScript script)
+ {
+ Type type = script.GetClass();
+ if (type == null) return false;
+
+ return filter.GetValue() switch
+ {
+ FilterType.MonoBehaviour => type.IsSubclassOf(typeof(MonoBehaviour)),
+ FilterType.ScriptableObject => type.IsSubclassOf(typeof(ScriptableObject)),
+ FilterType.Editor => type.IsSubclassOf(typeof(UnityEditor.Editor)),
+ _ => true
+ };
+ }
+ private string GetScriptInfo(MonoScript script)
+ {
+ if (script == null) return "";
+
+ Type type = script.GetClass();
+ if (type == null) return script.name;
+
+ string result =
+ script.name + "," +
+ type.Name + "," +
+ type.Namespace + "," +
+ (type.BaseType != null ? type.BaseType.Name : "");
+
+ var nestedTypes = type.GetNestedTypes(
+ BindingFlags.Public | BindingFlags.NonPublic);
+
+ foreach (var nested in nestedTypes)
+ {
+ result += "," + nested.Name;
+ }
+
+ return result;
+ }
+ private MonoScript[] LoadScripts()
+ {
+ List scripts = new List();
+
+ string[] guids = AssetDatabase.FindAssets("t:MonoScript");
+
+ foreach (string guid in guids)
+ {
+ string path = AssetDatabase.GUIDToAssetPath(guid);
+ MonoScript script = AssetDatabase.LoadAssetAtPath(path);
+
+ scripts.Add(script);
+ }
+
+ scripts.Sort((a, b) => a.name.CompareTo(b.name));
+
+ return scripts.ToArray();
+ }
+ private string Analyze(MonoScript script)
+ {
+ if (script == null)
+ {
+ return "No script selected.";
+ }
+
+ Type type = script.GetClass();
+
+ if (type == null)
+ {
+ return "Could not find class in script.";
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("=== SCRIPT INFO ===");
+ sb.AppendLine($"Namespace: {type.Namespace}");
+ sb.AppendLine($"Class: {type.Name}");
+ sb.AppendLine($"Abstract: {type.IsAbstract}");
+ sb.AppendLine($"Sealed: {type.IsSealed}");
+ sb.AppendLine($"Static: {type.IsAbstract && type.IsSealed}");
+ sb.AppendLine("");
+
+ BindingFlags flags =
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.Static |
+ BindingFlags.DeclaredOnly;
+
+ // Fields
+ sb.AppendLine("=== FIELDS ===");
+ foreach (var field in type.GetFields(flags))
+ {
+ sb.AppendLine($"{GetAccess(field)} {field.FieldType.Name} {field.Name}");
+ }
+
+ sb.AppendLine("");
+
+ // Properties
+ sb.AppendLine("=== PROPERTIES ===");
+ foreach (var prop in type.GetProperties(flags))
+ {
+ sb.AppendLine($"{prop.PropertyType.Name} {prop.Name}");
+ }
+
+ sb.AppendLine("");
+
+ // Methods
+ sb.AppendLine("=== METHODS ===");
+ foreach (var method in type.GetMethods(flags))
+ {
+ if (method.IsSpecialName) continue;
+
+ sb.Append($"{GetAccess(method)} {method.ReturnType.Name} {method.Name}(");
+
+ var parameters = method.GetParameters();
+
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ sb.Append($"{parameters[i].ParameterType.Name} {parameters[i].Name}");
+
+ if (i < parameters.Length - 1)
+ sb.Append(", ");
+ }
+
+ sb.AppendLine(")");
+ }
+
+ return sb.ToString();
+ }
+ private string GetAccess(FieldInfo field)
+ {
+ if (field.IsPublic) return "public";
+ if (field.IsPrivate) return "private";
+ if (field.IsFamily) return "protected";
+ if (field.IsAssembly) return "internal";
+ return "";
+ }
+ private string GetAccess(MethodInfo method)
+ {
+ if (method.IsPublic) return "public";
+ if (method.IsPrivate) return "private";
+ if (method.IsFamily) return "protected";
+ if (method.IsAssembly) return "internal";
+ return "";
+ }
+ private void Preper()
+ {
+ Root = new FieldModule(this, "Root");
+ FieldModule NoneNamespace = new FieldModule(this, " (No Namespace)");
+ FieldModule NoneClass = new FieldModule(this, " (No Type)");
+ Root.AddChild(NoneNamespace);
+ Root.AddChild(NoneClass);
+
+ foreach (var script in ProjectScripts)
+ {
+ if (script != null)
+ {
+ Type ScriptType = script.GetClass();
+ if (ScriptType != null)
+ {
+ if (ScriptType.Namespace != null)
+ {
+ Root.AddChild(script);
+ }
+ else
+ {
+ NoneNamespace.AddChild(new FieldModule(this, script));
+ }
+ }
+ else
+ {
+ NoneClass.AddChild(new FieldModule(this, script));
+ }
+
+ }
+ }
+
+ Root.Expand();
+ }
+ }
+}
diff --git a/Editor/ReadySet/Tools/ClassViewerWindow.cs.meta b/Editor/ReadySet/Tools/ClassViewerWindow.cs.meta
new file mode 100644
index 00000000..7d84b2ca
--- /dev/null
+++ b/Editor/ReadySet/Tools/ClassViewerWindow.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: cd4da7ba3d8b8fe4ea12071681b3d0ac
\ No newline at end of file
diff --git a/Editor/ReadySet/Tools/HelpWindow.cs b/Editor/ReadySet/Tools/HelpWindow.cs
new file mode 100644
index 00000000..0a1cc81e
--- /dev/null
+++ b/Editor/ReadySet/Tools/HelpWindow.cs
@@ -0,0 +1,264 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.IO;
+
+namespace RealMethod.Editor
+{
+ [System.Serializable]
+ public class HelpNode
+ {
+ public string name;
+ public string toturial; // text after ->
+ public string link; // text afeter https
+ public List children = new List();
+ }
+
+ public class HelpWindow : EditorWindow
+ {
+ private List rootNodes = new List();
+ private Dictionary foldoutStates = new Dictionary();
+
+ private TextAsset textFile;
+ private Vector2 scrollPos;
+ private string searchQuery = "";
+
+ [MenuItem("Tools/RealMethod/Help")]
+ public static void Open()
+ {
+ GetWindow("Help");
+ }
+
+ // Unity Methods
+ private void OnEnable()
+ {
+ string ClassViewPath = "Assets/Realmethod/Documentation/Information/Help.txt"; // Just for Test
+ // string ClassViewPath = Path.Combine(RM_CoreEditor.Documentation, "Help.txt");
+ if (!File.Exists(ClassViewPath))
+ {
+ Debug.LogError($"ClassView file not found: {ClassViewPath}");
+ Close();
+ }
+ string ClassFile = File.ReadAllText(ClassViewPath);
+ LoadFromText(ClassFile);
+ }
+ private void OnGUI()
+ {
+ EditorGUILayout.BeginHorizontal();
+ if (GUILayout.Button("Collaps"))
+ {
+ foreach (var node in rootNodes)
+ {
+ FoldLine(node, false);
+ }
+ }
+ if (GUILayout.Button("Expanded"))
+ {
+ foreach (var node in rootNodes)
+ {
+ FoldLine(node, true);
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.Space();
+ searchQuery = EditorGUILayout.TextField("Search", searchQuery);
+
+ EditorGUILayout.Space();
+
+ // 🔽 Scroll View
+ scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
+
+ foreach (var node in rootNodes)
+ {
+ DrawNodeWithSearch(node, 0);
+ }
+
+ EditorGUILayout.EndScrollView();
+ // 🔼 Scroll View
+ }
+
+ private void LoadFromText(string text)
+ {
+ rootNodes.Clear();
+ foldoutStates.Clear();
+
+ string[] lines = text.Split('\n');
+ Stack stack = new Stack();
+
+ foreach (string rawLine in lines)
+ {
+ if (string.IsNullOrWhiteSpace(rawLine))
+ continue;
+
+ int indent = CountIndent(rawLine);
+ string trimmed = rawLine.Trim();
+
+ string nodeName = trimmed;
+ string endText = null;
+ string linkText = null;
+
+ // 🔹 Parse "-> End Text"
+ string middleText = null;
+ int arrowIndex = trimmed.IndexOf("->");
+ if (arrowIndex >= 0)
+ {
+ nodeName = trimmed.Substring(0, arrowIndex).Trim();
+ middleText = trimmed.Substring(arrowIndex + 2).Trim();
+ }
+
+ if (middleText != null)
+ {
+ int linkindex = middleText.IndexOf("https");
+ if (linkindex >= 0)
+ {
+ endText = middleText.Substring(0, linkindex).Trim();
+ linkText = middleText.Substring(linkindex).Trim();
+ }
+ else
+ {
+ endText = middleText;
+ }
+ }
+
+ HelpNode node = new HelpNode
+ {
+ name = nodeName,
+ toturial = endText,
+ link = linkText
+ };
+
+ if (indent == 0)
+ {
+ rootNodes.Add(node);
+ stack.Clear();
+ stack.Push(node);
+ }
+ else
+ {
+ while (stack.Count > indent)
+ stack.Pop();
+
+ stack.Peek().children.Add(node);
+ stack.Push(node);
+ }
+ }
+ }
+ private int CountIndent(string line)
+ {
+ int spaces = 0;
+ foreach (char c in line)
+ {
+ if (c == ' ')
+ spaces++;
+ else
+ break;
+ }
+ return spaces / 2; // 2 spaces = 1 level
+ }
+
+ private bool DrawNodeWithSearch(HelpNode node, int indent)
+ {
+ // Check if node matches search
+ bool nodeMatches = string.IsNullOrEmpty(searchQuery) ||
+ node.name.ToLower().Contains(searchQuery.ToLower()) ||
+ node.toturial?.ToLower().Contains(searchQuery.ToLower()) == true;
+
+ // Check if any child matches
+ bool anyChildMatches = false;
+ foreach (var child in node.children)
+ {
+ if (NodeOrChildrenMatchSearch(child))
+ {
+ anyChildMatches = true;
+ break;
+ }
+ }
+
+ // If nothing matches, skip
+ if (!nodeMatches && !anyChildMatches)
+ return false;
+
+ // Draw parent node
+ if (!foldoutStates.ContainsKey(node))
+ foldoutStates[node] = true;
+
+ EditorGUILayout.BeginHorizontal();
+ GUILayout.Space(indent * 20);
+ foldoutStates[node] =
+ EditorGUILayout.Foldout(foldoutStates[node], node.name, true);
+ EditorGUILayout.EndHorizontal();
+
+ // Show endText as link if expanded
+ if (foldoutStates[node] && !string.IsNullOrEmpty(node.toturial))
+ {
+ EditorGUILayout.BeginHorizontal();
+ GUILayout.Space(indent * 20);
+ EditorGUILayout.BeginVertical("box");
+ GUIStyle richLabel = new GUIStyle(EditorStyles.wordWrappedLabel);
+ richLabel.richText = true;
+ GUILayout.Label(node.toturial, richLabel);
+ //GUILayout.Label(node.toturial, new GUIStyle(EditorStyles.wordWrappedLabel));
+ if (!string.IsNullOrEmpty(node.link))
+ {
+ if (GUILayout.Button("Link", EditorStyles.linkLabel))
+ {
+ OnEndTextClicked(node);
+ }
+ }
+ EditorGUILayout.EndVertical();
+ EditorGUILayout.EndHorizontal();
+ }
+
+
+
+ // Draw children recursively only if expanded
+ if (foldoutStates[node])
+ {
+ foreach (var child in node.children)
+ {
+ DrawNodeWithSearch(child, indent + 1);
+ }
+ }
+
+ return true;
+ }
+ // Helper: check recursively if a node or any child matches search
+ private bool NodeOrChildrenMatchSearch(HelpNode node)
+ {
+ bool match = string.IsNullOrEmpty(searchQuery) ||
+ node.name.ToLower().Contains(searchQuery.ToLower()) ||
+ node.toturial?.ToLower().Contains(searchQuery.ToLower()) == true;
+
+ if (match)
+ return true;
+
+ foreach (var child in node.children)
+ {
+ if (NodeOrChildrenMatchSearch(child))
+ return true;
+ }
+
+ return false;
+ }
+ private void FoldLine(HelpNode node, bool result)
+ {
+ foldoutStates[node] = result;
+ if (foldoutStates[node])
+ {
+ foreach (var child in node.children)
+ FoldLine(child, result);
+ }
+ }
+ private void OnEndTextClicked(HelpNode node)
+ {
+ if (EditorUtility.DisplayDialog("OpenLink", node.link, "Open", "Cancel"))
+ {
+ // 3️⃣ OR open URL (if endText is a URL)
+ Application.OpenURL(node.link);
+ }
+ // 2️⃣ OR ping asset
+ // EditorGUIUtility.PingObject(yourObject);
+ }
+
+ }
+}
diff --git a/Editor/ReadySet/Tools/HelpWindow.cs.meta b/Editor/ReadySet/Tools/HelpWindow.cs.meta
new file mode 100644
index 00000000..4a309112
--- /dev/null
+++ b/Editor/ReadySet/Tools/HelpWindow.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 15438cb6b5774124f90a5a787acca4c8
\ No newline at end of file
diff --git a/Editor/ReadySet/Tools/LibraryViewerWindow.cs b/Editor/ReadySet/Tools/LibraryViewerWindow.cs
new file mode 100644
index 00000000..aec57fc7
--- /dev/null
+++ b/Editor/ReadySet/Tools/LibraryViewerWindow.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using UnityEditor;
+using UnityEngine;
+
+namespace RealMethod.Editor
+{
+ public class LibraryViewerWindow : EditorWindow
+ {
+ private class FieldModule
+ {
+ //private Vector2 scroll;
+ private MonoScript File;
+
+
+ public Type Class { get; private set; }
+ public MethodInfo TargetMethod { get; private set; }
+ public string Title
+ {
+ get
+ {
+ return $"{Class.Name}.{TargetMethod.Name}";
+ }
+ }
+ public bool IsExpand { get; private set; } = false;
+ public bool isStatic => Class.IsAbstract && Class.IsSealed;
+
+ public FieldModule(MonoScript script, MethodInfo method)
+ {
+ File = script;
+
+ if (method == null)
+ Print("Method is not valid!");
+ TargetMethod = method;
+
+ Type ClassType = script.GetClass();
+ if (ClassType == null)
+ Print("Class is not valid!");
+ Class = ClassType;
+ }
+
+ public void Render()
+ {
+ EditorGUILayout.BeginHorizontal();
+ IsExpand = EditorGUILayout.Foldout(IsExpand, $"{Title}({TargetMethod.GetParameters().Length})", true);
+ if (GUILayout.Button("OpenFile ", EditorStyles.linkLabel))
+ {
+ Debug.Log("sdsdsd");
+ AssetDatabase.OpenAsset(File);
+ }
+ EditorGUILayout.EndHorizontal();
+ if (IsExpand)
+ {
+ //EditorGUI.BeginDisabledGroup(true);
+ //scroll = EditorGUILayout.BeginScrollView(scroll, GUILayout.Height(800));
+ EditorGUILayout.TextArea(GetMethodBody(File, TargetMethod));
+ //EditorGUILayout.EndScrollView();
+ //EditorGUI.EndDisabledGroup();
+ }
+
+ }
+
+ private string GetMethodBody(MonoScript script, MethodInfo method)
+ {
+ string path = AssetDatabase.GetAssetPath(script);
+ if (string.IsNullOrEmpty(path))
+ {
+ return "Invalid script path.";
+ }
+ string[] lines = System.IO.File.ReadAllLines(path);
+
+ StringBuilder sb = new StringBuilder();
+
+ int MethodLineNumber = -1;
+ for (int i = 0; i < lines.Length; i++)
+ {
+ if (lines[i].Contains(method.Name))
+ {
+ MethodLineNumber = i;
+ break;
+ }
+ }
+
+ if (MethodLineNumber == -1)
+ {
+ return "Something wrong!";
+ }
+
+ for (int i = MethodLineNumber; i < MethodLineNumber + 10; i++)
+ {
+ sb.AppendLine(lines[i]);
+ }
+ return sb.ToString();
+ }
+ private void Print(string message)
+ {
+ Debug.Log($"[{Title}]: {message}");
+ }
+ }
+ private class Dropdown : EditorProperty
+ {
+ private string[] Options;
+ public string CurrentOption => Options[GetValue()];
+
+ public Dropdown(string Name, string[] options, UnityEngine.Object other) : base(Name, other)
+ {
+ Options = options;
+ }
+
+ protected override byte UpdateRender()
+ {
+ CashValue = EditorGUILayout.Popup(string.Empty, CurrentValue, Options, GUI.skin.FindStyle("ToolbarPopup"), GUILayout.Width(120));
+ if (CashValue == CurrentValue)
+ {
+ return 0; // No change
+ }
+ else
+ {
+ SetValue(CashValue);
+ return 1; // Changed
+ }
+ }
+ protected override void FixError(int Id)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+
+ private Vector2 scroll;
+ private Dropdown NameSpace_Filter;
+ private MonoScript[] Scripts;
+ private List Fields = new List(0);
+ private string search = string.Empty;
+
+
+ [MenuItem("Tools/RealMethod/Viewer/LibraryViewer")]
+ public static void Open()
+ {
+ GetWindow("LibraryViewer");
+ }
+ private void OnEnable()
+ {
+
+ Scripts = LoadScripts();
+ CreateNameSpaceList();
+ ReSetField();
+ }
+ private void OnGUI()
+ {
+ DrawToolbar();
+ scroll = EditorGUILayout.BeginScrollView(scroll);
+ foreach (var field in Fields)
+ {
+ if (!PassSearch(field)) continue;
+ if (!PassFilter(field)) continue;
+
+ field.Render();
+ }
+ EditorGUILayout.EndScrollView();
+ EditorGUILayout.HelpBox(
+ " Note: This inspector uses reflection and can only detect the primary type in this script and its nested types. " +
+ "Additional classes, structs, enums, or interfaces declared outside the main type in the same file will not appear.",
+ MessageType.Info);
+ }
+
+
+ private void ReSetField()
+ {
+ Fields.Clear();
+
+
+ foreach (var script in Scripts)
+ {
+ Type mainType = script.GetClass();
+ if (mainType == null)
+ continue;
+
+ if (mainType.IsAbstract && mainType.IsSealed)
+ {
+ DrawField(script,mainType);
+ Type[] nestedTypes = mainType.GetNestedTypes(BindingFlags.Public);
+ foreach (var classtype in nestedTypes)
+ {
+ DrawField(script,classtype);
+ }
+ }
+
+ }
+ }
+ private void DrawField(MonoScript script, Type mainType)
+ {
+ BindingFlags flags =
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.Static |
+ BindingFlags.DeclaredOnly;
+
+ foreach (var method in mainType.GetMethods(flags))
+ {
+ if (method.IsSpecialName) continue;
+
+ if (!method.IsPublic) continue;
+
+ if (!method.IsStatic) continue;
+
+ if (method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false)) continue;
+
+ Fields.Add(new FieldModule(script, method));
+ }
+ }
+ private void DrawToolbar()
+ {
+ EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
+
+ search = GUILayout.TextField(search, GUI.skin.FindStyle("ToolbarSearchTextField"), GUILayout.ExpandWidth(true));
+
+ if (GUILayout.Button(GUIContent.none, GUI.skin.FindStyle("ToolbarSearchCancelButton")))
+ {
+ search = "";
+ GUI.FocusControl(null);
+ }
+
+ if (NameSpace_Filter.Render() == 1)
+ ReSetField();
+
+ if (GUILayout.Button("Refresh", EditorStyles.toolbarButton, GUILayout.Width(70)))
+ {
+ search = "";
+ Scripts = LoadScripts();
+ CreateNameSpaceList();
+ ReSetField();
+ }
+
+ EditorGUILayout.EndHorizontal();
+ }
+ private bool PassSearch(FieldModule Field)
+ {
+ if (string.IsNullOrEmpty(search)) return true;
+
+ return Field.Title.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0;
+ }
+ private bool PassFilter(FieldModule Field)
+ {
+ if (NameSpace_Filter.GetValue() == 0)
+ return true;
+
+ if (Field.Class.Namespace == NameSpace_Filter.CurrentOption)
+ return true;
+
+ return false;
+ }
+ private void CreateNameSpaceList()
+ {
+ int RealMethodIndex = 0;
+ HashSet NameSpaceList = new HashSet() { "All" };
+ foreach (var script in Scripts)
+ {
+ if (script == null)
+ continue;
+
+ Type ClassType = script.GetClass();
+ if (ClassType != null)
+ {
+ if (!string.IsNullOrEmpty(ClassType.Namespace))
+ {
+ if (NameSpaceList.Add(ClassType.Namespace))
+ {
+ if (ClassType.Namespace == "RealMethod")
+ {
+ RealMethodIndex = NameSpaceList.Count - 1;
+ }
+ }
+ }
+ }
+ }
+ // Set NameSpace Lisst to Dropdown box
+ NameSpace_Filter = new Dropdown("Filter", NameSpaceList.ToArray(), this);
+ NameSpace_Filter.SetValue(RealMethodIndex);
+ }
+ private MonoScript[] LoadScripts()
+ {
+ List scripts = new List();
+
+ string[] guids = AssetDatabase.FindAssets("t:MonoScript");
+
+ foreach (string guid in guids)
+ {
+ string path = AssetDatabase.GUIDToAssetPath(guid);
+ MonoScript script = AssetDatabase.LoadAssetAtPath(path);
+
+ scripts.Add(script);
+ }
+
+ scripts.Sort((a, b) => a.name.CompareTo(b.name));
+
+ return scripts.ToArray();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/ReadySet/Tools/LibraryViewerWindow.cs.meta b/Editor/ReadySet/Tools/LibraryViewerWindow.cs.meta
new file mode 100644
index 00000000..890bcc2c
--- /dev/null
+++ b/Editor/ReadySet/Tools/LibraryViewerWindow.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 5ff9e75fbed2b884b83172d51263511a
\ No newline at end of file
diff --git a/Editor/Toolkit/Ability/AbilityControllerEditor.cs b/Editor/Toolkit/Ability/AbilityControllerEditor.cs
index 9f15cb55..8d0b736e 100644
--- a/Editor/Toolkit/Ability/AbilityControllerEditor.cs
+++ b/Editor/Toolkit/Ability/AbilityControllerEditor.cs
@@ -23,7 +23,7 @@ public override void OnInspectorGUI()
EditorGUILayout.LabelField($"Debug ({MyController.Count})", EditorStyles.boldLabel);
for (int i = 0; i < MyController.Count; i++)
{
- EditorGUILayout.LabelField($"{MyController.GetAbility(i).NameID}: {IsReady(MyController.GetAbility(i))}");
+ EditorGUILayout.LabelField($"{MyController.GetAbility(i).Self}: {IsReady(MyController.GetAbility(i))}");
}
}
diff --git a/Editor/Toolkit/Ability/AbilityMenu.cs b/Editor/Toolkit/Ability/AbilityMenu.cs
new file mode 100644
index 00000000..c21b344b
--- /dev/null
+++ b/Editor/Toolkit/Ability/AbilityMenu.cs
@@ -0,0 +1,27 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class AbilityMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Ability/AbilityAsset", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateAbilityAsset()
+ {
+ RM_Editor.CreateScriptTemplate("AbilityAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Ability/AbilityActionAsset", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateAbilityAction()
+ {
+ RM_Editor.CreateScriptTemplate("AbilityActionAsset", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Ability/Effect", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateEffect()
+ {
+ RM_Editor.CreateScriptTemplate("AbilityEffect", MenuLayer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/Ability/Ability_ScriptTemplate.cs.meta b/Editor/Toolkit/Ability/AbilityMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/Ability/Ability_ScriptTemplate.cs.meta
rename to Editor/Toolkit/Ability/AbilityMenu.cs.meta
diff --git a/Editor/Toolkit/Ability/Ability_ScriptTemplate.cs b/Editor/Toolkit/Ability/Ability_ScriptTemplate.cs
deleted file mode 100644
index 9c3c07f3..00000000
--- a/Editor/Toolkit/Ability/Ability_ScriptTemplate.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class Ability_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Ability/AbilityAsset", false, 80)]
- public static void CreateAbilityAsset()
- {
- string Path = RM_Create.Script("AbilityAssetTemplate.txt", "MyAbility.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Ability/AbilityActionAsset", false, 80)]
- public static void CreateAbilityAction()
- {
- string Path = RM_Create.Script("AbilityActionAssetTemplate.txt", "MyAbilityAction.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Ability/Effect", false, 80)]
- public static void CreateEffect()
- {
- string Path = RM_Create.Script("AbilityEffectTemplate.txt", "MyEffect.cs");
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Toolkit/Actor/ActorMenu.cs b/Editor/Toolkit/Actor/ActorMenu.cs
new file mode 100644
index 00000000..0b357075
--- /dev/null
+++ b/Editor/Toolkit/Actor/ActorMenu.cs
@@ -0,0 +1,16 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class ActorMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Actor/Act", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateActCommand()
+ {
+ RM_Editor.CreateScriptTemplate("Act", MenuLayer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/Actor/Actor_ScriptTemplate.cs.meta b/Editor/Toolkit/Actor/ActorMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/Actor/Actor_ScriptTemplate.cs.meta
rename to Editor/Toolkit/Actor/ActorMenu.cs.meta
diff --git a/Editor/Toolkit/Actor/Actor_ScriptTemplate.cs b/Editor/Toolkit/Actor/Actor_ScriptTemplate.cs
deleted file mode 100644
index d1c971e2..00000000
--- a/Editor/Toolkit/Actor/Actor_ScriptTemplate.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class Actor_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Actor/Act", false, 80)]
- public static void CreateActCommand()
- {
- string Path = RM_Create.Script("ActTemplate.txt", "MyAct.cs");
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Toolkit/CSVFile/CSVFileEditor.cs b/Editor/Toolkit/CSVFile/CSVFileEditor.cs
index c368931b..905e4eed 100644
--- a/Editor/Toolkit/CSVFile/CSVFileEditor.cs
+++ b/Editor/Toolkit/CSVFile/CSVFileEditor.cs
@@ -10,7 +10,7 @@ namespace RealMethod.Editor
[CustomEditor(typeof(TextAsset))]
public class CSVFileEditor : UnityEditor.Editor
{
- class CustomList : EPS_ScriptableObjectList where T : ScriptableObject
+ class CustomList : EPS_AssetList where T : PrimitiveAsset
{
Color originalColor = GUI.backgroundColor;
@@ -52,7 +52,7 @@ enum SheetType
private string assetPath;
private EPS_Enum ReadStyle;
private SheetViewer TabelGUI;
- private CustomList ObjectsPart;
+ private CustomList ObjectsPart;
private EPS_Date LastUpdate;
private EPS_Enum OnlineSheetType;
private EPS_string SheetID;
@@ -74,7 +74,7 @@ private void OnEnable()
// Load the file content
TabelGUI = new SheetViewer(textAsset);
ReadStyle = new EPS_Enum(this, "ReadType");
- ObjectsPart = new CustomList(this, "SObjects");
+ ObjectsPart = new CustomList(this, "SObjects");
LastUpdate = new EPS_Date(this, "LastUpdate");
SheetID = new EPS_string(this, "SheetID");
OnlineSheetType = new EPS_Enum(this, "SheetType");
diff --git a/Editor/Toolkit/Inventory/InventoryEditor.cs b/Editor/Toolkit/Inventory/InventoryEditor.cs
index d67918b2..79422425 100644
--- a/Editor/Toolkit/Inventory/InventoryEditor.cs
+++ b/Editor/Toolkit/Inventory/InventoryEditor.cs
@@ -26,7 +26,7 @@ public override void OnInspectorGUI()
{
//EditorGUILayout.BeginHorizontal();
int ItemQuantity = BaseComponent.GetQuantity(item);
- EditorGUILayout.LabelField($"Name: {item.NameID}({item.NameID}) - Quantity: {ItemQuantity} ");
+ EditorGUILayout.LabelField($"Name: {item.SelfName}({item.SelfName}) - Quantity: {ItemQuantity} ");
total += ItemQuantity;
//EditorGUILayout.EndHorizontal();
}
diff --git a/Editor/Toolkit/Inventory/InventoryMenu.cs b/Editor/Toolkit/Inventory/InventoryMenu.cs
new file mode 100644
index 00000000..83f1a090
--- /dev/null
+++ b/Editor/Toolkit/Inventory/InventoryMenu.cs
@@ -0,0 +1,17 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class InventoryMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Inventory/Item", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateItem()
+ {
+ RM_Editor.CreateScriptTemplate("InventoryItem", MenuLayer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/Inventory/Inventory_ScriptTemplate.cs.meta b/Editor/Toolkit/Inventory/InventoryMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/Inventory/Inventory_ScriptTemplate.cs.meta
rename to Editor/Toolkit/Inventory/InventoryMenu.cs.meta
diff --git a/Editor/Toolkit/Inventory/Inventory_ScriptTemplate.cs b/Editor/Toolkit/Inventory/Inventory_ScriptTemplate.cs
deleted file mode 100644
index 8f3da799..00000000
--- a/Editor/Toolkit/Inventory/Inventory_ScriptTemplate.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class Inventory_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Inventory/Item", false, 80)]
- public static void CreateItem()
- {
- string Path = RM_Create.Script("InventoryItemTemplate.txt", "MyItem.cs");
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Toolkit/PCG/PCGEditorWindow.cs b/Editor/Toolkit/PCG/PCGEditorWindow.cs
index a558103c..96f84d01 100644
--- a/Editor/Toolkit/PCG/PCGEditorWindow.cs
+++ b/Editor/Toolkit/PCG/PCGEditorWindow.cs
@@ -63,9 +63,9 @@ private enum PCGExportType
}
// Fields
- private EP_ScriptableObject Resurce;
- private EP_ScriptableObject Genration;
- private EP_ScriptableObject Cash;
+ private EP_Asset Resurce;
+ private EP_Asset Genration;
+ private EP_Asset Cash;
private EP_List SelectedData;
private EP_String CashAddress;
private EP_String PrefabAddress;
@@ -102,14 +102,14 @@ private void OnEnable()
Debug.LogError("ProjectSettingAsset is missing from Resources folder!");
}
- Resurce = new EP_ScriptableObject("Resurce", this);
- Genration = new EP_ScriptableObject("Genration", this);
- Cash = new EP_ScriptableObject("Cash", this);
+ Resurce = new EP_Asset("Resurce", this);
+ Genration = new EP_Asset("Genration", this);
+ Cash = new EP_Asset("Cash", this);
SelectedData = new EP_List("Data", this);
CashAddress = new EP_String("Address", this);
- CashAddress.SetValue(ProjectSetting.FindAddres(ProjectSettingAsset.IdentityAsset.PCG).Path + "/PCGCashAsset.asset");
+ CashAddress.SetValue(ProjectSetting.GetFolderPathByType(ProjectSettingAsset.AssetFormat.ScriptableObject) + "/PCGCashAsset.asset");
PrefabAddress = new EP_String("Address", this);
- PrefabAddress.SetValue(ProjectSetting.FindAddres(ProjectSettingAsset.IdentityAsset.Prefab).Path + "/PCG.prefab");
+ PrefabAddress.SetValue(ProjectSetting.GetFolderAddressByType(ProjectSettingAsset.AssetFormat.Prefab).AssetPath + "/PCG.prefab");
ExportType = new EP_Enum("ExportType", this);
// Subscribe to the selectionChanged event
@@ -391,7 +391,7 @@ private void CashPanel()
Cash.Render();
if (GUILayout.Button("CreateCash"))
{
- Cash.SetValue(RM_Create.ScriptableObj(CashAddress.GetValue()));
+ Cash.SetValue(RM_Create.Asset(CashAddress.GetValue()));
}
EditorGUILayout.EndHorizontal();
}
diff --git a/Editor/Toolkit/PCG/PCGMenu.cs b/Editor/Toolkit/PCG/PCGMenu.cs
new file mode 100644
index 00000000..3c97e9eb
--- /dev/null
+++ b/Editor/Toolkit/PCG/PCGMenu.cs
@@ -0,0 +1,15 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class PCGMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/PCG/Request", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreatePCGRequest()
+ {
+ RM_Editor.CreateScriptTemplate("PCGRequest", MenuLayer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/PCG/PCG_ScriptTemplate.cs.meta b/Editor/Toolkit/PCG/PCGMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/PCG/PCG_ScriptTemplate.cs.meta
rename to Editor/Toolkit/PCG/PCGMenu.cs.meta
diff --git a/Editor/Toolkit/PCG/PCG_ScriptTemplate.cs b/Editor/Toolkit/PCG/PCG_ScriptTemplate.cs
deleted file mode 100644
index ade88096..00000000
--- a/Editor/Toolkit/PCG/PCG_ScriptTemplate.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class PCG_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/PCG/Request", false, 80)]
- public static void CreatePCGRequest()
- {
- string Path = RM_Create.Script("PCGRequestTamplate.txt", "MyRequest.cs");
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Toolkit/PCG/PCG_UnityAsset.cs b/Editor/Toolkit/PCG/PCG_UnityAsset.cs
index 1a976e3a..01de736f 100644
--- a/Editor/Toolkit/PCG/PCG_UnityAsset.cs
+++ b/Editor/Toolkit/PCG/PCG_UnityAsset.cs
@@ -1,6 +1,6 @@
namespace RealMethod.Editor
{
- public class PCGResource_UnityAsset : AssetHandeler
+ public class PCGResource_UnityAsset : AssetProcess
{
protected override void Initialized()
{
@@ -24,7 +24,7 @@ protected override void DoubleClick(PCGResourceConfig asset)
}
}
- public class PCGGeneration_UnityAsset : AssetHandeler
+ public class PCGGeneration_UnityAsset : AssetProcess
{
protected override void Initialized()
{
@@ -48,7 +48,7 @@ protected override void DoubleClick(PCGGenerationAsset asset)
}
}
- public class PCGCash_UnityAsset : AssetHandeler
+ public class PCGCash_UnityAsset : AssetProcess
{
protected override void Initialized()
{
diff --git a/Editor/Toolkit/Pickup/PickupMenu.cs b/Editor/Toolkit/Pickup/PickupMenu.cs
new file mode 100644
index 00000000..27716487
--- /dev/null
+++ b/Editor/Toolkit/Pickup/PickupMenu.cs
@@ -0,0 +1,21 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class PickupMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Pickup/Pickup3D", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreatePickup3D()
+ {
+ RM_Editor.CreateScriptTemplate("Pickup3D", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Pickup/Pickup2D", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreatePickup2D()
+ {
+ RM_Editor.CreateScriptTemplate("Pickup2D", MenuLayer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/Pickup/Pickup_ScriptTemplate.cs.meta b/Editor/Toolkit/Pickup/PickupMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/Pickup/Pickup_ScriptTemplate.cs.meta
rename to Editor/Toolkit/Pickup/PickupMenu.cs.meta
diff --git a/Editor/Toolkit/Pickup/Pickup_ScriptTemplate.cs b/Editor/Toolkit/Pickup/Pickup_ScriptTemplate.cs
deleted file mode 100644
index 2f3809ff..00000000
--- a/Editor/Toolkit/Pickup/Pickup_ScriptTemplate.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class Pickup_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Pickup/Pickup3D", false, 80)]
- public static void CreatePickup3D()
- {
- string Path = RM_Create.Script("Pickup3DTemplate.txt", "MyPickup.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Pickup/Pickup2D", false, 80)]
- public static void CreatePickup2D()
- {
- string Path = RM_Create.Script("Pickup2DTemplate.txt", "MyPickup.cs");
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Toolkit/RPG/RPGMenu.cs b/Editor/Toolkit/RPG/RPGMenu.cs
new file mode 100644
index 00000000..527d00a7
--- /dev/null
+++ b/Editor/Toolkit/RPG/RPGMenu.cs
@@ -0,0 +1,33 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class RPGMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/RPG/StatDefinition", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateStatDefinition()
+ {
+ RM_Editor.CreateScriptTemplate("StatDefinition", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/RPG/StatProfile", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateStatProfile()
+ {
+ RM_Editor.CreateScriptTemplate("StatProfile", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/RPG/StatBuff", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateBuffConfig()
+ {
+ RM_Editor.CreateScriptTemplate("BuffConfig", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/RPG/ResourceData", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateResourceData()
+ {
+ RM_Editor.CreateScriptTemplate("ResourceData", MenuLayer);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/RPG/RPG_ScriptTemplate.cs.meta b/Editor/Toolkit/RPG/RPGMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/RPG/RPG_ScriptTemplate.cs.meta
rename to Editor/Toolkit/RPG/RPGMenu.cs.meta
diff --git a/Editor/Toolkit/RPG/RPG_ScriptTemplate.cs b/Editor/Toolkit/RPG/RPG_ScriptTemplate.cs
deleted file mode 100644
index 956250cc..00000000
--- a/Editor/Toolkit/RPG/RPG_ScriptTemplate.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class RPG_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/RPG/StatDefinition", false, 80)]
- public static void CreateStatDefinition()
- {
- string Path = RM_Create.Script("StatDefinitionTemplate.txt", "StatDefinition.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/RPG/StatProfile", false, 80)]
- public static void CreateStatProfile()
- {
- string Path = RM_Create.Script("StatProfileTemplate.txt", "MyProfile.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/RPG/StatBuff", false, 80)]
- public static void CreateBuffConfig()
- {
- string Path = RM_Create.Script("BuffConfigTemplate.txt", "MyBuff.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/RPG/ResourceData", false, 80)]
- public static void CreateResourceData()
- {
- string Path = RM_Create.Script("ResourceDataTemplate.txt", "MyResource.cs");
- }
-
- }
-}
\ No newline at end of file
diff --git a/Editor/Toolkit/TerrainTools/TerrainEditor.cs b/Editor/Toolkit/TerrainTools/TerrainEditor.cs
index cf50fcce..72a9462d 100644
--- a/Editor/Toolkit/TerrainTools/TerrainEditor.cs
+++ b/Editor/Toolkit/TerrainTools/TerrainEditor.cs
@@ -71,7 +71,7 @@ private int GetTreeCount()
// If You Remove PCG Kit Just Remove ExportTreeData from this code.
public class ExportTreeData : Object
{
- private EP_ScriptableObject CashFile;
+ private EP_Asset CashFile;
private EP_String CashAddress;
private ProjectSettingAsset ProjectSetting;
private Terrain OwnerTerrain;
@@ -92,9 +92,9 @@ public ExportTreeData(Terrain owner, UnityEditor.Editor editor)
return;
}
- CashFile = new EP_ScriptableObject("Cash", editor);
+ CashFile = new EP_Asset("Cash", editor);
CashAddress = new EP_String("Address", editor);
- CashAddress.SetValue(ProjectSetting.FindAddres(ProjectSettingAsset.IdentityAsset.PCG).Path + "/TerrainCash.asset");
+ CashAddress.SetValue(ProjectSetting.GetFolderPathByType(ProjectSettingAsset.AssetFormat.ScriptableObject) + "/TerrainCash.asset");
}
public void OnRender()
@@ -138,8 +138,8 @@ public void OnRender()
if (GUILayout.Button("CreateCash"))
{
string directoryfile = Path.GetDirectoryName(CashAddress.GetValue());
- PCGResourceConfig ResurcePack = RM_Create.ScriptableObj(directoryfile + "/TerrainResource.asset");
- PCGCashAsset Temporery = RM_Create.ScriptableObj(CashAddress.GetValue());
+ PCGResourceConfig ResurcePack = RM_Create.Asset(directoryfile + "/TerrainResource.asset");
+ PCGCashAsset Temporery = RM_Create.Asset(CashAddress.GetValue());
TerrainData Data = OwnerTerrain.terrainData;
PCGSource[] TerrainSource = new PCGSource[Data.treePrototypes.Length];
TreeInstance[] trees = OwnerTerrain.terrainData.treeInstances;
diff --git a/Editor/Toolkit/Tutorial/TutorialMenu.cs b/Editor/Toolkit/Tutorial/TutorialMenu.cs
new file mode 100644
index 00000000..6ced5b67
--- /dev/null
+++ b/Editor/Toolkit/Tutorial/TutorialMenu.cs
@@ -0,0 +1,26 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class TutorialMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Tutorial/Screen", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateTutorialScreen()
+ {
+ RM_Editor.CreateScriptTemplate("TutorialScreen", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Tutorial/UIunit", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateTutorialMessage()
+ {
+ RM_Editor.CreateScriptTemplate("TutorialUnit", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Tutorial/Config", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateTutorialConfig()
+ {
+ RM_Editor.CreateScriptTemplate("TutorialConfig", MenuLayer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/Tutorial/Tutorial_ScriptTemplate.cs.meta b/Editor/Toolkit/Tutorial/TutorialMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/Tutorial/Tutorial_ScriptTemplate.cs.meta
rename to Editor/Toolkit/Tutorial/TutorialMenu.cs.meta
diff --git a/Editor/Toolkit/Tutorial/Tutorial_ScriptTemplate.cs b/Editor/Toolkit/Tutorial/Tutorial_ScriptTemplate.cs
deleted file mode 100644
index e5f76533..00000000
--- a/Editor/Toolkit/Tutorial/Tutorial_ScriptTemplate.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class Tutorial_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Tutorial/ScreenWidget", false, 80)]
- public static void CreateTutorialScreen()
- {
- string Path = RM_Create.Script("TutorialScreenTemplate.txt", "MyTutorialScreen.cs");
- }
-
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Tutorial/UIunit", false, 80)]
- public static void CreateTutorialMessage()
- {
- string Path = RM_Create.Script("TutorialUnitTemplate.txt", "MyTutorialUnit.cs");
- }
-
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Tutorial/Config", false, 80)]
- public static void CreateTutorialConfig()
- {
- string Path = RM_Create.Script("TutorialConfigTemplate.txt", "MyTutorialConfig.cs");
- }
- }
-}
\ No newline at end of file
diff --git a/Editor/Toolkit/Upgrade/UpgradeMenu.cs b/Editor/Toolkit/Upgrade/UpgradeMenu.cs
new file mode 100644
index 00000000..bffe6af1
--- /dev/null
+++ b/Editor/Toolkit/Upgrade/UpgradeMenu.cs
@@ -0,0 +1,22 @@
+using UnityEditor;
+
+namespace RealMethod.Editor
+{
+ class UpgradeMenu
+ {
+ private const RealMethodLayer MenuLayer = RealMethodLayer.Toolkit;
+
+
+
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Upgrade/Item", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateItem()
+ {
+ RM_Editor.CreateScriptTemplate("UpgradeItem", MenuLayer);
+ }
+ [MenuItem(RM_Editor.ScriptMenuItemPath + "Toolkit/Upgrade/Map", false, RM_Editor.MenuOrder.Toolkit)]
+ public static void CreateConfig()
+ {
+ RM_Editor.CreateScriptTemplate("UpgradeConfig", MenuLayer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolkit/Upgrade/Upgrade_ScriptTemplate.cs.meta b/Editor/Toolkit/Upgrade/UpgradeMenu.cs.meta
similarity index 100%
rename from Editor/Toolkit/Upgrade/Upgrade_ScriptTemplate.cs.meta
rename to Editor/Toolkit/Upgrade/UpgradeMenu.cs.meta
diff --git a/Editor/Toolkit/Upgrade/Upgrade_ScriptTemplate.cs b/Editor/Toolkit/Upgrade/Upgrade_ScriptTemplate.cs
deleted file mode 100644
index 063f71a8..00000000
--- a/Editor/Toolkit/Upgrade/Upgrade_ScriptTemplate.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using UnityEditor;
-
-namespace RealMethod.Editor
-{
- class Upgrade_ScriptTemplate
- {
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Upgrade/ItemAsset", false, 80)]
- public static void CreateItem()
- {
- string Path = RM_Create.Script("UpgradeItemTemplate.txt", "MyUpgradeAsset.cs");
- }
- [MenuItem("Assets/Create/Scripting/RealMethod/Toolkit/Upgrade/MapConfig", false, 80)]
- public static void CreateConfig()
- {
- string Path = RM_Create.Script("UpgradeConfigTemplate.txt", "MyUpgradeConfig.cs");
- }
- }
-}
\ No newline at end of file
diff --git a/README.md b/README.md
index abe4bee8..718e059e 100644
--- a/README.md
+++ b/README.md
@@ -1,148 +1,31 @@
-# 🌌 RealMethod
-*A lightweight Unity architecture for scalable and modular project creation.*
----
-
-## ✨ Overview
-
-**RealMethod** is a Unity package that defines a clean and consistent **project architecture**.
-It focuses on separation of responsibility and lifecycle management, allowing developers to build games that are easily extendable, maintainable, and modular.
-
-RealMethod introduces five main layers:
-- **Core** – Defines the base relationships between Game, World, Manager, and Service.
-- **Library** – Common utility functions, interfaces, and shared components.
-- **Pattern** – Predefined architecture patterns and reusable managers.
-- **Toolkit** – Ready-to-use tools, inspectors, and debugging helpers.
-- **ReadySet** – Example setups and templates for quick project initialization.
-
----
-
-## 🧩 Core Architecture
-
-### **Game**
-- The **Game** class is the entry point of the RealMethod framework.
-- It is a **singleton** that lives for the entire game lifecycle (until quit).
-- Responsible for global operations such as:
- - Scene management (`OpenScene`, `ReloadScene`, etc.)
- - Time control (`SetGameSpeed`)
- - Service construction and destruction
-
-All **Managers** and **Services** are registered through `Game`, ensuring consistent global access.
-
----
-
-### **World**
-- The **World** class exists **once per scene** and acts as the runtime context for that scene.
-- It initializes all **World-scoped Managers** and prepares the scene for gameplay.
-- While **Game** persists between scenes, **World** resets when scenes change.
-- Required in every scene that uses RealMethod.
-
----
-
-### **Manager**
-- A **Manager** defines a controllable system within a given scope (Game or World).
-- Implements the `IManager` interface.
-- Managers are initialized **before Unity’s Awake/Start** callbacks.
-- Can live in one of two scopes:
- - **Game scope:** persists between scenes (registered under Game).
- - **World scope:** tied to a specific scene (registered under World).
-
-Both Game and World automatically call `DontDestroyOnLoad` for their scoped Managers.
-
----
-
-### **Service**
-- A **Service** is a lightweight, non-MonoBehaviour object managed by the Game.
-- Created dynamically using `Game.CreateService()`.
-- All Managers automatically recognize and can interact with new Services.
-- Can be destroyed at any time via `Game.DestroyService()`.
-- Ideal for runtime systems like data caching, analytics, or network clients.
-
----
-
-## ⚙️ Lifecycle Summary
-
-| Layer | Scope | Lifetime | Created By | Notes |
-|-------|--------|-----------|-------------|-------|
-| Game | Global | Until Quit | App Start | Singleton |
-| World | Scene | Per Scene | Scene Load | Scene Context |
-| Manager | Global/Scene | Anytime | Game/World | Registered in Game/Scene scope |
-| Service | Runtime | Dynamic | Game | Fully managed objects |
-
----
-
-## 📦 Package Structure
-RealMethod is organized into clearly separated runtime, editor, and resource layers — each designed to keep your project scalable, readable, and modular.
-### 🧩 Runtime
-Core runtime code that runs inside Unity builds.
-
-- **Core/**
- - `Architecture/` – Core systems such as **Game**, **World**, **Manager**, and **Service**.
- - `Attributes/` – Custom attributes used across the framework.
- - `Definitions/` – Global enums, tags, and static definitions.
- - `ProjectSetting/` – Runtime configuration and project constants.
-
-- **Library/**
- - `Extension/` – Unity extensions and helper methods.
- - `Interfaces/` – Common interfaces for modular communication.
- - `SharedScripts/` – Shared data structures (Classes, Enums, Structs).
- - `Utilities/` – Core utility scripts.
- - `Vendor/SerializableDictionary/` – Third-party generic dictionary support.
-
-- **Pattern/**
- - `Components/` – Base components using RealMethod patterns.
- - `DataAssets/` – ScriptableObject-based configuration.
- - `DesignPatterns/` – Common gameplay and architecture patterns.
- - `Managers/` – Runtime manager implementations.
- - `Services/` – Service classes managed by the Game/World.
-
-- **ReadySet/**
- - `Commands/` – Command execution framework (Executors, Tasks).
- - `Components/` – Common building blocks (Input, Method, Physics, Time, UI, Visual).
- - `DefaultsClass/` – Predefined data and logic templates.
- - `Managers/` – Ready-to-use manager classes.
- - `Presets/` – Resource and pooling presets (PoolAsset, ResourceAsset, Task).
- - `Services/` – Prebuilt services and systems.
-
-- **Toolkit/**
- - `Ability/` – Ability system and samples.
- - `Actor/` – Actor handling and lifecycle logic.
- - `CSVFile/` – CSV parsing and data import tools.
- - `CurveViewer/` – Editor curve visualization.
- - `Interaction/` – Interaction handling system.
- - `Inventory/` – Inventory architecture.
- - `PCG/` – Procedural generation tools and resources.
- - `Pickup/` – Item pickup logic.
- - `RPG/` – RPG systems (Resource, StatSystem).
- - `Tutorial/` – Tutorial system and utilities.
- - `Upgrade/` – Upgrade and progression tools.
-
----
-
-### 🛠️ Editor
-Unity Editor extensions for all RealMethod layers.
-
-- **Core/** – Editor scripts for Architecture, Definitions, and Project Settings.
-- **Library/** – Shared scripts, vendor tools, and utilities.
-- **Pattern/** – Custom editors for data assets and managers.
-- **ReadySet/** – Editor tools for content setup and asset generation.
-- **Toolkit/** – Editors for gameplay systems (Ability, Inventory, TerrainTools, etc.).
-
----
-
-### 🧃 Reservoir
-Central storage for framework assets.
-
-- `Icons/` – Organized icons for Core, Pattern, and Toolkit editors.
-- `Prefabs/` – Prefab resources for samples and managers.
-- `SceneTemplates/` – Example scenes for quick setup.
-- `ScriptTemplates/` – Script templates for fast development.
-
----
-
-### 🧪 Samples~
-Example projects demonstrating **PopupMessage** and **Tutorial** systems.
-
----
-
-### 🧠 Tests
-Unit and integration tests for **General**, **Inspector**, and **ScenesDot** systems.
+# RealMethod
+**"`RealMethod` is a minimal, Unreal-inspired architecture for structuring Unity games with clear lifetime, ownership, and system boundaries."**
+### Links
+* [Documentation(Wiki)](https://github.com/AliJimpa/RealMethod/wiki/Home)
+* [Video Tutorials]()
+### The Pitch
+`RealMethod` is a minimal architectural framework for Unity. It provides a small, explicit structure for organizing game lifetime, world context, and systems, inspired by **Unreal Engine** concepts such as `GameInstance` and `GameMode`.
+
+`RealMethod` is designed to help programmers build and maintain scalable Unity projects by enforcing clear ownership and predictable lifecycles. It favors simplicity and clarity over abstraction and avoids heavy frameworks, dependency injection containers, or hidden execution flows. `RealMethod` focuses on structure, not gameplay, and does not attempt to replace Unity workflows.
+
+`RealMethod` is particularly suited for games and real-time applications where long-term maintainability matters: indie and studio projects, system-heavy games, tool-driven workflows, and projects that must evolve over time without architectural collapse.
+* Clear ownership and responsibility
+* Unreal-like mental model for Unity
+* Minimal core, flexible edges
+* Scales from small games
+* experimental for productions
+* Team-friendly and testable architecture
+### Quick Setup
+Install via Unity Package Manager:
+1. Open Package Manager
+2. Click Add package from Git URL
+3. Paste
+>https://github.com/AliJimpa/RealMethod.git
+4. Follow the Getting Started guide
+>https://github.com/AliJimpa/RealMethod/wiki/Quick-Setup
+### Gallery
+Examples projects using RealMethod: [Death Pulse](https://github.com/wolfpld/tracy](https://cafebazaar.ir/app/com.Mustard.DeathPulse?l=en)), [Crush Conquest](https://cafebazaar.ir/app/com.Mustard.CrushConquest?l=en), [HeardSpoken]() and [Fireball]().
+
+| | |
+|--|--|
+|
 |
 |
diff --git a/Reservoir/ScriptTemplates/CompileRuleTemplate.txt b/Reservoir/ScriptTemplates/CompileRuleTemplate.txt
new file mode 100644
index 00000000..73e984b9
--- /dev/null
+++ b/Reservoir/ScriptTemplates/CompileRuleTemplate.txt
@@ -0,0 +1,33 @@
+using System;
+using RealMethod.Editor;
+using UnityEngine;
+
+public class #SCRIPTNAME# : CompileRule
+{
+ // CompileRule Methods
+ protected override void Initilized()
+ {
+ // Called right after Construct
+ }
+ public override void OnStartCheck(RuleExecutionMode mode)
+ {
+ // Called once per mode befor any cheking.
+ }
+ public override bool CanCheck(RuleExecutionMode mode, Type type)
+ {
+ // A Type that all target classes must derive from
+ if (mode == RuleExecutionMode.AfterCompilation)
+ {
+ return type.IsSubclassOf(typeof(????));
+ }
+ else
+ {
+ // Skip other mode
+ return false;
+ }
+ }
+ public override void OnCheck(Type type)
+ {
+ // Called when CanCheck was true.
+ }
+}
diff --git a/Reservoir/ScriptTemplates/CompileRuleTemplate.txt.meta b/Reservoir/ScriptTemplates/CompileRuleTemplate.txt.meta
new file mode 100644
index 00000000..07c8093c
--- /dev/null
+++ b/Reservoir/ScriptTemplates/CompileRuleTemplate.txt.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: ff50126801b38d34db2274c3060c4695
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Reservoir/ScriptTemplates/CompositManagerTemplate.txt b/Reservoir/ScriptTemplates/CompositManagerTemplate.txt
deleted file mode 100644
index 753502e6..00000000
--- a/Reservoir/ScriptTemplates/CompositManagerTemplate.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : CompositManager
-{
- [Header("Music")]
- [SerializeField]
- private AudioClip[] CreateLayers;
- [SerializeField]
- private bool AddServiceOnInitiate = false;
-
- protected override void OnInitiate(bool AlwaysLoaded)
- {
- foreach (var clip in CreateLayers)
- {
- CreateLayer(clip);
- }
- if (AddServiceOnInitiate)
- Game.AddService(this);
- }
- protected override void MusicStateAssigned()
- {
- }
-}
-
-public enum MUSCIENUM
-{
- Default,
- STATE_1,
- STATE_2,
-}
-
-public sealed class STATESETVICE : StateService
-{
- public MUSCIENUM() : base(MUSCIENUM.Default) // This is the First State Value
- {
-
- }
-
- // Service Methods
- protected override void OnStart(object Author)
- {
- }
- protected override void OnEnd(object Author)
- {
-
- }
-
- // StateService Methods
- protected override DefaulMusicLayer DefaultState()
- {
- return DefaulMusicLayer.Default;
- }
- public override bool CanSwitch(DefaulMusicLayer A, DefaulMusicLayer B)
- {
- if (A == B)
- {
- return false;
- }
- return true;
- }
- protected override bool CanResetforNewWorld(World NewWorld)
- {
- return false;
- }
-}
\ No newline at end of file
diff --git a/Reservoir/ScriptTemplates/Core.meta b/Reservoir/ScriptTemplates/Core.meta
new file mode 100644
index 00000000..92623ef3
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d66d434cac454c34f823e1a3cea9a39e
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Reservoir/ScriptTemplates/Core/CloneAssetTemplate.txt b/Reservoir/ScriptTemplates/Core/CloneAssetTemplate.txt
new file mode 100644
index 00000000..9c24adb7
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core/CloneAssetTemplate.txt
@@ -0,0 +1,7 @@
+using UnityEngine;
+using RealMethod;
+
+[CreateAssetMenu(fileName = "#SCRIPTNAME#", menuName = "#PROJECTNAME#/#SCRIPTNAME#", order = 1)]
+public class #SCRIPTNAME# : CloneAsset
+{
+}
\ No newline at end of file
diff --git a/Reservoir/ScriptTemplates/Core/CloneAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/CloneAssetTemplate.txt.meta
new file mode 100644
index 00000000..e5b5e0fe
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core/CloneAssetTemplate.txt.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 22f923a8fe4c59b4baca28070f31141c
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Reservoir/ScriptTemplates/ConfigAssetTemplate.txt b/Reservoir/ScriptTemplates/Core/ConfigAssetTemplate.txt
similarity index 58%
rename from Reservoir/ScriptTemplates/ConfigAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Core/ConfigAssetTemplate.txt
index 42a4a16f..397f8885 100644
--- a/Reservoir/ScriptTemplates/ConfigAssetTemplate.txt
+++ b/Reservoir/ScriptTemplates/Core/ConfigAssetTemplate.txt
@@ -4,10 +4,4 @@ using RealMethod;
[CreateAssetMenu(fileName = "#SCRIPTNAME#", menuName = "#PROJECTNAME#/#SCRIPTNAME#", order = 1)]
public class #SCRIPTNAME# : ConfigAsset
{
- #if UNITY_EDITOR
- // public override void OnEditorPlay()
- // {
- // base.OnEditorPlay();
- // }
- #endif
}
diff --git a/Reservoir/ScriptTemplates/ConfigAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/ConfigAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/ConfigAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/ConfigAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/DataAssetTemplate.txt b/Reservoir/ScriptTemplates/Core/DataAssetTemplate.txt
similarity index 58%
rename from Reservoir/ScriptTemplates/DataAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Core/DataAssetTemplate.txt
index 2b4c0cc6..895c8cc7 100644
--- a/Reservoir/ScriptTemplates/DataAssetTemplate.txt
+++ b/Reservoir/ScriptTemplates/Core/DataAssetTemplate.txt
@@ -4,10 +4,4 @@ using RealMethod;
[CreateAssetMenu(fileName = "#SCRIPTNAME#", menuName = "#PROJECTNAME#/#SCRIPTNAME#", order = 1)]
public class #SCRIPTNAME# : DataAsset
{
- #if UNITY_EDITOR
- // public override void OnEditorPlay()
- // {
- // base.OnEditorPlay();
- // }
- #endif
}
\ No newline at end of file
diff --git a/Reservoir/ScriptTemplates/DataAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/DataAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/DataAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/DataAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Core/GameBridgeTemplate.txt b/Reservoir/ScriptTemplates/Core/GameBridgeTemplate.txt
new file mode 100644
index 00000000..fabf4ee5
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core/GameBridgeTemplate.txt
@@ -0,0 +1,5 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : GameBridge
+{
+}
diff --git a/Reservoir/ScriptTemplates/GameServiceTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/GameBridgeTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/GameServiceTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/GameBridgeTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/GameConfigTemplate.txt b/Reservoir/ScriptTemplates/Core/GameConfigTemplate.txt
similarity index 75%
rename from Reservoir/ScriptTemplates/GameConfigTemplate.txt
rename to Reservoir/ScriptTemplates/Core/GameConfigTemplate.txt
index 7e7ae088..bca67f27 100644
--- a/Reservoir/ScriptTemplates/GameConfigTemplate.txt
+++ b/Reservoir/ScriptTemplates/Core/GameConfigTemplate.txt
@@ -4,8 +4,9 @@ using RealMethod;
[CreateAssetMenu(fileName = "#SCRIPTNAME#", menuName = "#PROJECTNAME#/#SCRIPTNAME#", order = 1)]
public class #SCRIPTNAME# : GameConfig
{
- // Base GameSettingAsset Methods
+ // GameConfig Methods
public override void Initialized(Game Author)
{
+ // Called after load in Game by GameClass
}
}
diff --git a/Reservoir/ScriptTemplates/GameConfigTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/GameConfigTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/GameConfigTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/GameConfigTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Core/GameTemplate.txt b/Reservoir/ScriptTemplates/Core/GameTemplate.txt
new file mode 100644
index 00000000..69ff4ff2
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core/GameTemplate.txt
@@ -0,0 +1,39 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : Game
+{
+
+ // Game Methods
+ protected override void OnGameOpen()
+ {
+ // Invoked when starting up the runtime. Called before the first scene is loaded.
+ // Called when game run in platform befor any scene loaded or even splash screen
+ // In this stage your game component just created.
+ }
+ protected override void OnGameInitialized()
+ {
+ // Invoked when the first scene's objects are loaded into memory but before Awake has been called.
+ // Called right after Unity finishes loading the engine before any scene or subsystem is loaded.
+ // You can insure when called that GameBridge , GameConfig and all Managers in GameScope Initilized.
+ }
+ protected override void OnGameStart()
+ {
+ // Invoked when the first scene's objects are loaded into memory but before Awake has been called.
+ // Called after Unity finishes initializing the engine, but before the first scene is loaded.
+ // It’s guaranteed to execute before any Awake() or Start() in your scene objects.
+ }
+ protected override void OnWorldChanged(World NewWorld)
+ {
+ // Called when each World Initialized
+ // You can insure the Game.world refrence is valid
+ // Note: if you use world in scene and load scene as additive not OpenScen() that world didnt connect to Game and removed by Main World class (more= GameBridge)
+ }
+ protected override void OnGameClosed()
+ {
+ // Called when application start exit
+ // You can insure this called befor and object destroy in scene (yes befor)
+ }
+
+
+
+}
diff --git a/Reservoir/ScriptTemplates/GameTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/GameTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/GameTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/GameTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Core/ManagerTemplate.txt b/Reservoir/ScriptTemplates/Core/ManagerTemplate.txt
new file mode 100644
index 00000000..83cef781
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core/ManagerTemplate.txt
@@ -0,0 +1,15 @@
+using UnityEngine;
+using RealMethod;
+
+public class #SCRIPTNAME# : MonoBehaviour, IGameManager
+{
+ // Implement IGameManage Interface
+ MonoBehaviour IGameManager.GetManagerClass() => this;
+ void IGameManager.InitiateManager(Scope owner)
+ {
+ // Called Just Once Befor any Awake called
+ // Called when World or Game initializing
+ // Owner means your manager initialize in GameScope(always valid) or World Scope(destroy after change World)
+ }
+
+}
diff --git a/Reservoir/ScriptTemplates/ManagerTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/ManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/ManagerTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/ManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Core/ServiceTemplate.txt b/Reservoir/ScriptTemplates/Core/ServiceTemplate.txt
new file mode 100644
index 00000000..a71c6c14
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core/ServiceTemplate.txt
@@ -0,0 +1,22 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : Service
+{
+
+ // Service Methods
+ protected override void OnStart(object Author)
+ {
+ // Called right after Construct and stored in Game
+ // Called befor any Manager Know this Service Created
+ }
+ protected override void OnNewWorld()
+ {
+ // Called after each World Initialized
+ }
+ protected override void OnEnd(object Author)
+ {
+ // Called befor Destroyed.
+ // Called after all Manager know this Service going to Destroyed
+ }
+
+}
diff --git a/Reservoir/ScriptTemplates/ServiceTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/ServiceTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/ServiceTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/ServiceTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/UniqueAssetTemplate.txt b/Reservoir/ScriptTemplates/Core/UniqueAssetTemplate.txt
similarity index 58%
rename from Reservoir/ScriptTemplates/UniqueAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Core/UniqueAssetTemplate.txt
index 85899e0d..c5f53889 100644
--- a/Reservoir/ScriptTemplates/UniqueAssetTemplate.txt
+++ b/Reservoir/ScriptTemplates/Core/UniqueAssetTemplate.txt
@@ -4,10 +4,4 @@ using RealMethod;
[CreateAssetMenu(fileName = "#SCRIPTNAME#", menuName = "#PROJECTNAME#/#SCRIPTNAME#", order = 1)]
public class #SCRIPTNAME# : UniqueAsset
{
- #if UNITY_EDITOR
- // public override void OnEditorPlay()
- // {
- // base.OnEditorPlay();
- // }
- #endif
}
diff --git a/Reservoir/ScriptTemplates/UniqueAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/UniqueAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/UniqueAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/UniqueAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Core/WorldTemplate.txt b/Reservoir/ScriptTemplates/Core/WorldTemplate.txt
new file mode 100644
index 00000000..e81b1750
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Core/WorldTemplate.txt
@@ -0,0 +1,17 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : World
+{
+ // World Methods
+ protected override void WorldBegin()
+ {
+ // When World Awake
+ // Called befor awake and befor any Monobehaviort in Scene (by executionorder)
+ // You can insure your world is connect to game class and all Manager Initilize & Player Selected or Spawn in Scene
+ }
+ protected override void WorldEnd()
+ {
+ // When World Destroy
+ }
+
+}
diff --git a/Reservoir/ScriptTemplates/WorldTemplate.txt.meta b/Reservoir/ScriptTemplates/Core/WorldTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/WorldTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Core/WorldTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/DataManagerTemplate.txt b/Reservoir/ScriptTemplates/DataManagerTemplate.txt
deleted file mode 100644
index 9991f8e0..00000000
--- a/Reservoir/ScriptTemplates/DataManagerTemplate.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : DataManager
-{
-
- // Base DataManager Methods
- protected override void ResolveService(Service service, bool active)
- {
- throw new System.NotImplementedException();
- }
- protected override void OnSaveFile(SaveFile targetfile)
- {
- throw new System.NotImplementedException();
- }
- protected override void OnLoadFile(SaveFile targetfile)
- {
- throw new System.NotImplementedException();
- }
- protected override void OnDelete(SaveFile targetfile)
- {
- throw new System.NotImplementedException();
- }
- protected override bool IsExist(SaveFile targetfile)
- {
- throw new System.NotImplementedException();
- }
-
-}
diff --git a/Reservoir/ScriptTemplates/GameServiceTemplate.txt b/Reservoir/ScriptTemplates/GameServiceTemplate.txt
deleted file mode 100644
index f2476d26..00000000
--- a/Reservoir/ScriptTemplates/GameServiceTemplate.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : GameService
-{
- // Base Service Methods
- protected override void OnStart(object Author) { }
- protected override void OnNewWorld() { }
- protected override void OnNewAdditiveWorld(World target) { }
- protected override void OnEnd(object Author) { }
-
- // GameService Virtual Methods
- // public override IEnumerator GetLoadScneCorotine(SceneReference TargetScene)
- // {
- // return base.GetLoadScneCorotine();
- // }
- // public override IEnumerator GetLoadWorldCorotine(WorldSceneConfig WorldScene)
- // {
- // return base.GetLoadWorldCorotine();
- // }
- // public override IEnumerator GetReloadSWCorotine()
- // {
- // return base.GetReloadSWCorotine();
- // }
-}
diff --git a/Reservoir/ScriptTemplates/GameTemplate.txt b/Reservoir/ScriptTemplates/GameTemplate.txt
deleted file mode 100644
index de24ed55..00000000
--- a/Reservoir/ScriptTemplates/GameTemplate.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : Game
-{
-
- // Base Game Methods
- protected override void GameInitialized()
- {
- }
- protected override void GameStarted()
- {
- }
- protected override void GameWorldSynced(World NewWorld)
- {
- }
- protected override void GameClosed()
- {
- }
-
-
-
-}
diff --git a/Reservoir/ScriptTemplates/ItemAssetTemplate.txt b/Reservoir/ScriptTemplates/ItemAssetTemplate.txt
deleted file mode 100644
index c1c8d60b..00000000
--- a/Reservoir/ScriptTemplates/ItemAssetTemplate.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-using UnityEngine;
-using RealMethod;
-
-[CreateAssetMenu(fileName = "#SCRIPTNAME#", menuName = "#PROJECTNAME#/#SCRIPTNAME#", order = 1)]
-public class #SCRIPTNAME# : ItemAsset
-{
- #if UNITY_EDITOR
- // public override void OnEditorPlay()
- // {
- // base.OnEditorPlay();
- // }
- #endif
-}
diff --git a/Reservoir/ScriptTemplates/ManagerTemplate.txt b/Reservoir/ScriptTemplates/ManagerTemplate.txt
deleted file mode 100644
index c3ad458f..00000000
--- a/Reservoir/ScriptTemplates/ManagerTemplate.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-using UnityEngine;
-using RealMethod;
-
-public class #SCRIPTNAME# : MonoBehaviour, IGameManager
-{
-
- // Implement IGameManage Methods
- MonoBehaviour IGameManager.GetManagerClass()
- {
- return this;
- }
- void IGameManager.InitiateManager(bool AlwaysLoaded)
- {
- throw new System.NotImplementedException();
- }
- void IGameManager.ResolveService(Service service, bool active)
- {
- throw new System.NotImplementedException();
- }
-
-}
diff --git a/Reservoir/ScriptTemplates/MixerManagerTemplate.txt b/Reservoir/ScriptTemplates/MixerManagerTemplate.txt
deleted file mode 100644
index 0d2d04b2..00000000
--- a/Reservoir/ScriptTemplates/MixerManagerTemplate.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : MixerManager
-{
-
- // Implement IGameManage Methods
- protected override void InitiateManager(bool AlwaysLoaded)
- {
- throw new System.NotImplementedException();
- }
- protected override void ResolveService(Service service, bool active)
- {
- throw new System.NotImplementedException();
- }
-
-}
diff --git a/Reservoir/ScriptTemplates/Pattern.meta b/Reservoir/ScriptTemplates/Pattern.meta
new file mode 100644
index 00000000..65b0d77c
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Pattern.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bbc5ddc017cc6cf43a5f82f18222a728
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Reservoir/ScriptTemplates/AudioManagerTemplater.txt b/Reservoir/ScriptTemplates/Pattern/AudioManagerTemplate.txt
similarity index 96%
rename from Reservoir/ScriptTemplates/AudioManagerTemplater.txt
rename to Reservoir/ScriptTemplates/Pattern/AudioManagerTemplate.txt
index 21601618..b3e80db4 100644
--- a/Reservoir/ScriptTemplates/AudioManagerTemplater.txt
+++ b/Reservoir/ScriptTemplates/Pattern/AudioManagerTemplate.txt
@@ -2,6 +2,4 @@ using RealMethod;
public class #SCRIPTNAME# : AudioManager
{
-
-
}
diff --git a/Reservoir/ScriptTemplates/AudioManagerTemplater.txt.meta b/Reservoir/ScriptTemplates/Pattern/AudioManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/AudioManagerTemplater.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/AudioManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/CommandTemplate.txt b/Reservoir/ScriptTemplates/Pattern/CommandTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/CommandTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/CommandTemplate.txt
diff --git a/Reservoir/ScriptTemplates/CommandTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/CommandTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/CommandTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/CommandTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Pattern/CompositManagerTemplate.txt b/Reservoir/ScriptTemplates/Pattern/CompositManagerTemplate.txt
new file mode 100644
index 00000000..3d54e3bd
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Pattern/CompositManagerTemplate.txt
@@ -0,0 +1,23 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : CompositManager
+{
+ [Header("MusicList")]
+ [SerializeField]
+ private Map Clips = new Map();
+
+ // IGameManager Interface
+ protected override void InitiateManager(Scope owner)
+ {
+ base.InitiateManager(owner);
+ foreach (var clip in Clips)
+ {
+ CreateLayer(clip.Key, clip.Value);
+ }
+ }
+
+ protected override bool CompairStates(MUSCIENUM State_A, MUSCIENUM State_B)
+ {
+ return State_A == State_B;
+ }
+}
\ No newline at end of file
diff --git a/Reservoir/ScriptTemplates/CompositManagerTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/CompositManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/CompositManagerTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/CompositManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/FileAssetTemplate.txt b/Reservoir/ScriptTemplates/Pattern/FileAssetTemplate.txt
similarity index 58%
rename from Reservoir/ScriptTemplates/FileAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/FileAssetTemplate.txt
index be13179c..61eaebc6 100644
--- a/Reservoir/ScriptTemplates/FileAssetTemplate.txt
+++ b/Reservoir/ScriptTemplates/Pattern/FileAssetTemplate.txt
@@ -4,10 +4,4 @@ using RealMethod;
[CreateAssetMenu(fileName = "#SCRIPTNAME#", menuName = "#PROJECTNAME#/#SCRIPTNAME#", order = 1)]
public class #SCRIPTNAME# : FileAsset
{
- #if UNITY_EDITOR
- // public override void OnEditorPlay()
- // {
- // base.OnEditorPlay();
- // }
- #endif
}
diff --git a/Reservoir/ScriptTemplates/FileAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/FileAssetTemplate.txt.meta
similarity index 75%
rename from Reservoir/ScriptTemplates/FileAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/FileAssetTemplate.txt.meta
index c2f1e25a..375ee173 100644
--- a/Reservoir/ScriptTemplates/FileAssetTemplate.txt.meta
+++ b/Reservoir/ScriptTemplates/Pattern/FileAssetTemplate.txt.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 4744f0022d011cf44a0b25e6e9f8cd79
+guid: 939c3f2e8c0d6a347a60d9b6a104ed73
TextScriptImporter:
externalObjects: {}
userData:
diff --git a/Reservoir/ScriptTemplates/GameSettingFileTemplate.txt b/Reservoir/ScriptTemplates/Pattern/GameSettingFileTemplate.txt
similarity index 91%
rename from Reservoir/ScriptTemplates/GameSettingFileTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/GameSettingFileTemplate.txt
index 5a0d620f..e749ac6b 100644
--- a/Reservoir/ScriptTemplates/GameSettingFileTemplate.txt
+++ b/Reservoir/ScriptTemplates/Pattern/GameSettingFileTemplate.txt
@@ -5,7 +5,7 @@ using UnityEngine;
public class #SCRIPTNAME# : SettingFile
{
// SaveFile Methods
- protected override void OnStable(DataManager manager){}
+ protected override void OnStable(SaveManager manager){}
protected override void OnLoaded(){}
protected override void OnDeleted(){}
diff --git a/Reservoir/ScriptTemplates/GameSettingFileTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/GameSettingFileTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/GameSettingFileTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/GameSettingFileTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/GizmoManagerTemplate.txt b/Reservoir/ScriptTemplates/Pattern/GizmoManagerTemplate.txt
similarity index 51%
rename from Reservoir/ScriptTemplates/GizmoManagerTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/GizmoManagerTemplate.txt
index 546c370d..4653ff1e 100644
--- a/Reservoir/ScriptTemplates/GizmoManagerTemplate.txt
+++ b/Reservoir/ScriptTemplates/Pattern/GizmoManagerTemplate.txt
@@ -2,14 +2,10 @@ using RealMethod;
public class #SCRIPTNAME# : GizmoManager
{
- // Base DataManager Methods
+ // Base SaveManager Methods
protected override GUIRenderer[] GetRenderSlots()
{
throw new System.NotImplementedException();
}
- protected override void ResolveService(Service service, bool active)
- {
- throw new System.NotImplementedException();
- }
}
diff --git a/Reservoir/ScriptTemplates/GizmoManagerTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/GizmoManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/GizmoManagerTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/GizmoManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/HapticConfigTemplate.txt b/Reservoir/ScriptTemplates/Pattern/HapticConfigTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/HapticConfigTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/HapticConfigTemplate.txt
diff --git a/Reservoir/ScriptTemplates/HapticConfigTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/HapticConfigTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/HapticConfigTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/HapticConfigTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/ItemConfigTemplate.txt b/Reservoir/ScriptTemplates/Pattern/ItemConfigTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/ItemConfigTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/ItemConfigTemplate.txt
diff --git a/Reservoir/ScriptTemplates/ItemConfigTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/ItemConfigTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/ItemConfigTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/ItemConfigTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Pattern/MixerManagerTemplate.txt b/Reservoir/ScriptTemplates/Pattern/MixerManagerTemplate.txt
new file mode 100644
index 00000000..b044190e
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Pattern/MixerManagerTemplate.txt
@@ -0,0 +1,12 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : MixerManager
+{
+
+ // Implement IGameManage Methods
+ protected override void InitiateManager(Scope owner)
+ {
+ throw new System.NotImplementedException();
+ }
+
+}
diff --git a/Reservoir/ScriptTemplates/MixerManagerTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/MixerManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/MixerManagerTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/MixerManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/PoolAssetTemplate.txt b/Reservoir/ScriptTemplates/Pattern/PoolAssetTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/PoolAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/PoolAssetTemplate.txt
diff --git a/Reservoir/ScriptTemplates/PoolAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/PoolAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/PoolAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/PoolAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/SaveFileTemplate.txt b/Reservoir/ScriptTemplates/Pattern/SaveFileTemplate.txt
similarity index 71%
rename from Reservoir/ScriptTemplates/SaveFileTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/SaveFileTemplate.txt
index 7631c755..84f31a95 100644
--- a/Reservoir/ScriptTemplates/SaveFileTemplate.txt
+++ b/Reservoir/ScriptTemplates/Pattern/SaveFileTemplate.txt
@@ -5,16 +5,10 @@ using UnityEngine;
public class #SCRIPTNAME# : SaveFile
{
// SaveFile Method
- protected override void OnStable(DataManager manager)
- {
- }
protected override void OnSaved()
{
}
protected override void OnLoaded()
{
}
- protected override void OnDeleted()
- {
- }
}
diff --git a/Reservoir/ScriptTemplates/SaveFileTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/SaveFileTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/SaveFileTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/SaveFileTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Pattern/SaveManagerTemplate.txt b/Reservoir/ScriptTemplates/Pattern/SaveManagerTemplate.txt
new file mode 100644
index 00000000..7a70b659
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Pattern/SaveManagerTemplate.txt
@@ -0,0 +1,6 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : SaveMethodManager
+{
+
+}
diff --git a/Reservoir/ScriptTemplates/DataManagerTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/SaveManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/DataManagerTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/SaveManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/SharedRootAssetTemplate.txt b/Reservoir/ScriptTemplates/Pattern/SharedRootAssetTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/SharedRootAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/SharedRootAssetTemplate.txt
diff --git a/Reservoir/ScriptTemplates/SharedRootAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/SharedRootAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/SharedRootAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/SharedRootAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/TableTemplate.txt b/Reservoir/ScriptTemplates/Pattern/TableAssetTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/TableTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/TableAssetTemplate.txt
diff --git a/Reservoir/ScriptTemplates/TableTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/TableAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/TableTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/TableAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/TaskAssetTemplate.txt b/Reservoir/ScriptTemplates/Pattern/TaskAssetTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/TaskAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/TaskAssetTemplate.txt
diff --git a/Reservoir/ScriptTemplates/TaskAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/TaskAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/TaskAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/TaskAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/TickManagerTemplate.txt b/Reservoir/ScriptTemplates/Pattern/TickManagerTemplate.txt
similarity index 55%
rename from Reservoir/ScriptTemplates/TickManagerTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/TickManagerTemplate.txt
index 1a7ab79d..72e4e8a1 100644
--- a/Reservoir/ScriptTemplates/TickManagerTemplate.txt
+++ b/Reservoir/ScriptTemplates/Pattern/TickManagerTemplate.txt
@@ -4,13 +4,9 @@ public class #SCRIPTNAME# : TickManager
{
// TickManager Methods
- protected override void InitiateManager(bool alwaysLoaded)
+ protected override void InitiateManager(Scope owner)
{
- }
- protected override void ResolveService(Service service, bool active)
- {
-
}
protected override bool CheckUnit(T unit)
{
diff --git a/Reservoir/ScriptTemplates/TickManagerTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/TickManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/TickManagerTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/TickManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Trigger2DTemplate.txt b/Reservoir/ScriptTemplates/Pattern/Trigger2DTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/Trigger2DTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/Trigger2DTemplate.txt
diff --git a/Reservoir/ScriptTemplates/Trigger2DTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/Trigger2DTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/Trigger2DTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/Trigger2DTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Trigger3DTemplate.txt b/Reservoir/ScriptTemplates/Pattern/Trigger3DTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/Trigger3DTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/Trigger3DTemplate.txt
diff --git a/Reservoir/ScriptTemplates/Trigger3DTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/Trigger3DTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/Trigger3DTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/Trigger3DTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Pattern/UIManagerTemplate.txt b/Reservoir/ScriptTemplates/Pattern/UIManagerTemplate.txt
new file mode 100644
index 00000000..33137c4e
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Pattern/UIManagerTemplate.txt
@@ -0,0 +1,12 @@
+using RealMethod;
+
+public class #SCRIPTNAME# : UIManager
+{
+
+ // UIManager Methods
+ protected override void InitiateManager(Scope owner)
+ {
+
+ }
+
+}
diff --git a/Reservoir/ScriptTemplates/UIManagerTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/UIManagerTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/UIManagerTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/UIManagerTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/WidgetTemplate.txt b/Reservoir/ScriptTemplates/Pattern/WidgetTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/WidgetTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/WidgetTemplate.txt
diff --git a/Reservoir/ScriptTemplates/WidgetTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/WidgetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/WidgetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/WidgetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/WidgetToolkitTemplate.txt b/Reservoir/ScriptTemplates/Pattern/WidgetToolkitTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/WidgetToolkitTemplate.txt
rename to Reservoir/ScriptTemplates/Pattern/WidgetToolkitTemplate.txt
diff --git a/Reservoir/ScriptTemplates/WidgetToolkitTemplate.txt.meta b/Reservoir/ScriptTemplates/Pattern/WidgetToolkitTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/WidgetToolkitTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Pattern/WidgetToolkitTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/ServiceTemplate.txt b/Reservoir/ScriptTemplates/ServiceTemplate.txt
deleted file mode 100644
index 2f895170..00000000
--- a/Reservoir/ScriptTemplates/ServiceTemplate.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : Service
-{
-
- // Service Methods
- protected override void OnStart(object Author)
- {
- }
- protected override void OnNewWorld()
- {
- }
- protected override void OnEnd(object Author)
- {
- }
-
-}
diff --git a/Reservoir/ScriptTemplates/Toolkit.meta b/Reservoir/ScriptTemplates/Toolkit.meta
new file mode 100644
index 00000000..efa985c2
--- /dev/null
+++ b/Reservoir/ScriptTemplates/Toolkit.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 002acfcd71cdf2e45a91d3a78b0c40a0
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Reservoir/ScriptTemplates/AbilityActionAssetTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/AbilityActionAssetTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/AbilityActionAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/AbilityActionAssetTemplate.txt
diff --git a/Reservoir/ScriptTemplates/AbilityActionAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/AbilityActionAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/AbilityActionAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/AbilityActionAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/AbilityAssetTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/AbilityAssetTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/AbilityAssetTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/AbilityAssetTemplate.txt
diff --git a/Reservoir/ScriptTemplates/AbilityAssetTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/AbilityAssetTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/AbilityAssetTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/AbilityAssetTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/AbilityEffectTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/AbilityEffectTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/AbilityEffectTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/AbilityEffectTemplate.txt
diff --git a/Reservoir/ScriptTemplates/AbilityEffectTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/AbilityEffectTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/AbilityEffectTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/AbilityEffectTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/BuffConfigTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/BuffConfigTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/BuffConfigTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/BuffConfigTemplate.txt
diff --git a/Reservoir/ScriptTemplates/BuffConfigTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/BuffConfigTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/BuffConfigTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/BuffConfigTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/InventoryItemTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/InventoryItemTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/InventoryItemTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/InventoryItemTemplate.txt
diff --git a/Reservoir/ScriptTemplates/InventoryItemTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/InventoryItemTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/InventoryItemTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/InventoryItemTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/PCGRequestTamplate.txt b/Reservoir/ScriptTemplates/Toolkit/PCGRequestTamplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/PCGRequestTamplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/PCGRequestTamplate.txt
diff --git a/Reservoir/ScriptTemplates/PCGRequestTamplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/PCGRequestTamplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/PCGRequestTamplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/PCGRequestTamplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Pickup2DTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/Pickup2DTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/Pickup2DTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/Pickup2DTemplate.txt
diff --git a/Reservoir/ScriptTemplates/Pickup2DTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/Pickup2DTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/Pickup2DTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/Pickup2DTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/Pickup3DTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/Pickup3DTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/Pickup3DTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/Pickup3DTemplate.txt
diff --git a/Reservoir/ScriptTemplates/Pickup3DTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/Pickup3DTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/Pickup3DTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/Pickup3DTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/UpgradeConfigTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/UpgradeConfigTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/UpgradeConfigTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/UpgradeConfigTemplate.txt
diff --git a/Reservoir/ScriptTemplates/UpgradeConfigTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/UpgradeConfigTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/UpgradeConfigTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/UpgradeConfigTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/UpgradeItemTemplate.txt b/Reservoir/ScriptTemplates/Toolkit/UpgradeItemTemplate.txt
similarity index 100%
rename from Reservoir/ScriptTemplates/UpgradeItemTemplate.txt
rename to Reservoir/ScriptTemplates/Toolkit/UpgradeItemTemplate.txt
diff --git a/Reservoir/ScriptTemplates/UpgradeItemTemplate.txt.meta b/Reservoir/ScriptTemplates/Toolkit/UpgradeItemTemplate.txt.meta
similarity index 100%
rename from Reservoir/ScriptTemplates/UpgradeItemTemplate.txt.meta
rename to Reservoir/ScriptTemplates/Toolkit/UpgradeItemTemplate.txt.meta
diff --git a/Reservoir/ScriptTemplates/UIManagerTemplate.txt b/Reservoir/ScriptTemplates/UIManagerTemplate.txt
deleted file mode 100644
index e3274d33..00000000
--- a/Reservoir/ScriptTemplates/UIManagerTemplate.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : UIManager
-{
-
- // UIManager Methods
- protected override void InitiateManager(bool alwaysLoaded)
- {
-
- }
- protected override void ResolveService(Service service, bool active)
- {
-
- }
-
-}
diff --git a/Reservoir/ScriptTemplates/WorldTemplate.txt b/Reservoir/ScriptTemplates/WorldTemplate.txt
deleted file mode 100644
index 380a4323..00000000
--- a/Reservoir/ScriptTemplates/WorldTemplate.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-using RealMethod;
-
-public class #SCRIPTNAME# : World
-{
-
- // World Methods
- protected override void AwakeWorld()
- {
- }
- protected override void DestroyWorld()
- {
- }
-
-}
diff --git a/Runtime/Core/Architecture/EnumStorage.cs b/Runtime/Core/Architecture/EnumStorage.cs
new file mode 100644
index 00000000..d2075042
--- /dev/null
+++ b/Runtime/Core/Architecture/EnumStorage.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+
+namespace RealMethod
+{
+ public sealed class EnumStorage : IDisposable
+ {
+ private GlobalEnum _state;
+ private readonly Dictionary _values = new();
+ ///
+ /// Invoked when game state changed.
+ ///
+ public event Action OnStateChanged;
+
+ public GlobalEnum Global
+ {
+ get => _state;
+ set
+ {
+ if (_state == value)
+ return;
+
+ var old = _state;
+ _state = value;
+
+ OnStateChanged?.Invoke(old, _state);
+ }
+ }
+
+ // Implement IDisposable Interface
+ void IDisposable.Dispose()
+ {
+ _values.Clear();
+ }
+
+ public void Set(T enumValue) where T : Enum
+ {
+ _values[typeof(T)] = Convert.ToByte(enumValue);
+ }
+ public T Get() where T : Enum
+ {
+ Type type = typeof(T);
+
+ if (!_values.TryGetValue(type, out byte storedValue))
+ {
+ storedValue = 0;
+ _values[type] = 0;
+ }
+
+ return (T)Enum.ToObject(type, storedValue);
+ }
+
+
+ // -------- Operator Overloads --------
+ public static implicit operator GlobalEnum(EnumStorage storage)
+ {
+ return storage.Global;
+ }
+
+ public static implicit operator EnumStorage(GlobalEnum value)
+ {
+ return new EnumStorage { Global = value };
+ }
+
+ public static bool operator ==(EnumStorage a, GlobalEnum b)
+ => a is not null && a._state == b;
+
+ public static bool operator !=(EnumStorage a, GlobalEnum b)
+ => !(a == b);
+
+ public static bool operator <(EnumStorage a, GlobalEnum b)
+ => a is not null && a._state < b;
+
+ public static bool operator >(EnumStorage a, GlobalEnum b)
+ => a is not null && a._state > b;
+
+ public static bool operator <=(EnumStorage a, GlobalEnum b)
+ => a is not null && a._state <= b;
+
+ public static bool operator >=(EnumStorage a, GlobalEnum b)
+ => a is not null && a._state >= b;
+
+ public static bool operator ==(GlobalEnum a, EnumStorage b)
+ => b == a;
+
+ public static bool operator !=(GlobalEnum a, EnumStorage b)
+ => !(b == a);
+
+ public static bool operator <(GlobalEnum a, EnumStorage b)
+ => b is not null && a < b._state;
+
+ public static bool operator >(GlobalEnum a, EnumStorage b)
+ => b is not null && a > b._state;
+
+ public static bool operator <=(GlobalEnum a, EnumStorage b)
+ => b is not null && a <= b._state;
+
+ public static bool operator >=(GlobalEnum a, EnumStorage b)
+ => b is not null && a >= b._state;
+
+ // -------- Overrides --------
+
+ public override bool Equals(object obj)
+ {
+ if (obj is EnumStorage other)
+ return _state.Equals(other._state);
+
+ if (obj is GlobalEnum e)
+ return _state.Equals(e);
+
+ return false;
+ }
+ public override int GetHashCode()
+ {
+ return _state.GetHashCode();
+ }
+ public override string ToString()
+ {
+ return _state.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Core/Architecture/EnumStorage.cs.meta b/Runtime/Core/Architecture/EnumStorage.cs.meta
new file mode 100644
index 00000000..6b5981d7
--- /dev/null
+++ b/Runtime/Core/Architecture/EnumStorage.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 62bca4ee2575e6240a01e4f582caa5c8
\ No newline at end of file
diff --git a/Runtime/Core/Architecture/Game.cs b/Runtime/Core/Architecture/Game.cs
index 81997b3a..5167e80f 100644
--- a/Runtime/Core/Architecture/Game.cs
+++ b/Runtime/Core/Architecture/Game.cs
@@ -2,17 +2,43 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
-using System.Linq;
+
+
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEditor.SceneManagement;
+#endif
namespace RealMethod
{
- public abstract class Game : MonoBehaviour
+
+ ///
+ /// Core game singleton that manages the active , registered s,
+ /// configuration and high-level game lifecycle (initialization, start, and shutdown).
+ /// Derive from this class to implement project-specific behavior for the game's lifecycle hooks.
+ ///
+ public abstract class Game : Scope
{
- // Public Static Variables
+ ///
+ /// Singleton instance of the active game.
+ ///
public static Game Instance;
- public static GameConfig Config { get; private set; }
+ ///
+ /// The currently active . Updated when a world is initiated.
+ ///
public static World World { get; private set; }
- public static GameService Service { get; private set; }
+ ///
+ /// The core implementation used for scene/world loading and basic events.
+ ///
+ public static GameBridge Bridge { get; private set; }
+ ///
+ /// Active game configuration instance.
+ ///
+ public static GameConfig Config { get; private set; }
+ ///
+ /// Convenience property returning the player GameObject from the current .
+ /// Returns null and logs a warning if no world is set.
+ ///
public static GameObject Player
{
get
@@ -25,72 +51,210 @@ public static GameObject Player
return World.GetPlayerObject();
}
}
- public static bool isPaused => Time.timeScale == 0;
-
- // Private Variable
- private IGameManager[] Managers;
- private List GameServices;
-
- // Public Functions
- public T GetManager() where T : class
+ ///
+ /// Reperesent Game State that youser can define state in ProjectSetting
+ ///
+ public static readonly EnumStorage State = new EnumStorage();
+ ///
+ /// Indicates whether a scene or world load operation is currently in progress.
+ ///
+ public static bool IsPaused
{
- foreach (var manager in Managers)
+ get
{
- if (manager.GetManagerClass() is T Result)
+ if (Instance != null)
{
- return Result;
+ return Instance.IsGamePaused();
+ }
+ else
+ {
+ Debug.LogWarning("GameInstance did not called !");
+ return false;
}
}
- return null;
}
- public IGameManager GetManager(string ObjectName)
+ ///
+ /// Indicates whether the game is in loading stage
+ /// Return true when game in loading section for new scene
+ ///
+ public static bool IsLoading
{
- foreach (var manger in Managers)
+ get
{
- if (manger.GetManagerClass().gameObject.name == ObjectName)
+ if (Instance != null)
{
- return manger;
+ return Instance.IsGameLoading();
+ }
+ else
+ {
+ Debug.LogWarning("GameInstance did not called !");
+ return false;
}
}
- return null;
}
- // Protected Functions
- protected T NeedManager() where T : MonoBehaviour
+ ///
+ /// Indicate whether the game complitly initialized.
+ /// after true OnGameInitialized called.
+ /// befor first scene load
+ ///
+ public static bool IsGameInitialized { get; private set; } = false;
+
+
+
+
+ ///
+ /// Initializes the game singleton and core systems on subsystem registration.
+ /// This sets up the , game ,
+ /// configuration, prefabs and managers and registers quit callbacks.
+ /// Invoked when starting up the runtime. Called before the first scene is loaded.
+ ///
+ [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
+ private static void InitializeGame()
{
- T Result = GetManager();
- if (Result == null)
+ // Load Project Setting
+ ProjectSettingAsset ProjectSettings = Resources.Load("RealMethod/RealMethodSetting");
+ if (ProjectSettings == null)
{
- Result = gameObject.AddComponent();
- Debug.LogWarning($"Manager of type {typeof(T).Name} was not found. [A new one has been added].");
+ Debug.LogError("ProjectSettingAsset is missing from Resources folder!");
+ Quit();
+ return;
+ }
+ // Initiate GameClass
+ var RealObject = new GameObject("RealMethod");
+ Type TargetClass = ProjectSettings.GetGameType();
+ if (TargetClass == null)
+ {
+ Debug.LogWarning("GameInstanceClass that was empty. DefaultGame Created");
+ Instance = RealObject.AddComponent();
}
- return Result;
+ else
+ {
+ if (typeof(Game).IsAssignableFrom(TargetClass))
+ {
+ Instance = (Game)RealObject.AddComponent(TargetClass);
+ }
+ else
+ {
+ Debug.LogWarning($"Component of type {TargetClass} is not assignable from Game. DefaultGame Created");
+ Instance = RealObject.AddComponent();
+ }
+ }
+ Instance.OnProjectSeettingLoaded(ref ProjectSettings);
+
+ Instance.OnGameOpen();
+
+ // Create GameBridge
+ Type targetService = ProjectSettings.GetBridgeType();
+ if (targetService == null)
+ {
+ Debug.LogWarning($"GetGameBridgeType that was empty. DefaultGameBridge Created");
+ Bridge = new DefaultGameBridge(Instance.Notify_OnWorldInitiate);
+ }
+ else
+ {
+ if (typeof(GameBridge).IsAssignableFrom(targetService))
+ {
+ try
+ {
+ var parameter = new object[1] { (Action)Instance.Notify_OnWorldInitiate };
+ Bridge = (GameBridge)Activator.CreateInstance(targetService, parameter);
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError($"Failed to instantiate {targetService}: {ex.Message}. DefaultGameBridge Created");
+ Bridge = new DefaultGameBridge(Instance.Notify_OnWorldInitiate);
+ }
+ }
+ else
+ {
+ Debug.LogWarning($"Type {targetService} is not assignable to GameBridge. DefaultGameBridge Created");
+ Bridge = new DefaultGameBridge(Instance.Notify_OnWorldInitiate);
+ }
+ }
+
+ // Set GameConfig
+ if (ProjectSettings.GetGameConfigAsset() != null)
+ {
+ Config = ProjectSettings.GetGameConfigAsset();
+ }
+ else
+ {
+ Config = ScriptableObject.CreateInstance();
+ }
+
+ // Initiate GamePrefab & Managers
+ GameObject[] Objects = new GameObject[3];
+ if (ProjectSettings.GetPrefab_1() != null)
+ {
+ GameObject newobj = Instantiate(ProjectSettings.GetPrefab_1());
+ newobj.name = "GameScope(Runtime)";
+ Objects[0] = newobj;
+ newobj.transform.SetParent(RealObject.transform);
+ }
+#if UNITY_EDITOR
+ if (ProjectSettings.GetPrefab_2() != null)
+ {
+ GameObject newobj = Instantiate(ProjectSettings.GetPrefab_2());
+ newobj.name = "GameScope(Editor)";
+ Objects[1] = newobj;
+ newobj.transform.SetParent(RealObject.transform);
+ }
+#endif
+#if UNITY_SERVER
+ if (ProjectSettings.GetPrefab_3() != null)
+ {
+ GameObject newobj = Instantiate(ProjectSettings.GetPrefab_3());
+ newobj.name = "GameScope(Server)";
+ Objects[2] = newobj;
+ newobj.transform.SetParent(RealObject.transform);
+ }
+#endif
+ Instance.OpenScope(Objects);
+
+ // Unload Project Setting
+ Resources.UnloadAsset(ProjectSettings);
+ ProjectSettings = null;
+
+ // Move Self GameObject to DontDestroy
+ DontDestroyOnLoad(RealObject);
+ Application.quitting += Instance.Notify_OnGameQuit;
}
- // Private Functions
- private void OnGameWorldReplaced(World NewWorld)
+ ///
+ /// Called before any scene is loaded. Invokes on the active instance.
+ /// Invoked when the first scene's objects are loaded into memory but before Awake has been called.
+ ///
+ [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+ private static void RuntimeBeforeSceneLoad()
{
- World = NewWorld;
- foreach (var service in GameServices)
+ if (Instance != null)
{
- service.provider.WorldUpdated();
+ IsGameInitialized = true;
+ Instance.OnGameInitialized();
}
- GameWorldSynced(World);
}
- private void OnGameQuit()
+ ///
+ /// Called after a scene has finished loading. Invokes on the active instance.
+ /// Right after all Awake() and OnEnable() calls but befor Start()
+ /// Invoked when the first scene's objects are loaded into memory but before Awake has been called.
+ ///
+ [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
+ private static void RuntimeAfterSceneLoad()
{
- Application.quitting -= OnGameQuit;
- if (GameServices != null)
+ if (Instance != null)
{
- for (int i = 0; i < GameServices.Count; i++)
- {
- GameServices[i].provider.Deleted(this);
- GameServices.RemoveAt(i);
- }
+ Instance.OnGameStart();
}
- Service.provider.Deleted(this);
- GameClosed();
}
- // Public Static Functions
+
+
+
+ ///
+ /// Attempts to cast the global to the specified type .
+ /// Logs an error and returns null if the cast fails.
+ ///
+ /// The target type to cast the instance to.
+ /// The casted instance of type , or null on failure.
public static T CastInstance() where T : class
{
if (Instance is T CastedInstance)
@@ -103,6 +267,12 @@ public static T CastInstance() where T : class
return null;
}
}
+ ///
+ /// Attempts to cast the current to the specified type .
+ /// Logs an error and returns null if the cast fails.
+ ///
+ /// The target type to cast the world to.
+ /// The casted world of type , or null on failure.
public static T CastWorld() where T : class
{
if (World is T CastedWorld)
@@ -115,78 +285,109 @@ public static T CastWorld() where T : class
return null;
}
}
- public static T AddService(object author) where T : Service, new()
+ ///
+ /// Retrieves a manager of type from the active manager scopes.
+ /// The search is performed in the following order:
+ /// 1. The current World scope (if available).
+ /// 2. The global Instance scope.
+ ///
+ /// The type of manager to retrieve.
+ ///
+ /// The manager of type if found; otherwise null.
+ ///
+ public static T GetManager() where T : Component, IGameManager
+ {
+ if (World != null && World.TryFindGameManager(out T worldResult))
+ return worldResult;
+
+ if (Instance.TryFindGameManager(out T gameResult))
+ return gameResult;
+
+ return null;
+ }
+ ///
+ /// Retrieves the service instance of type if available.
+ ///
+ /// IService type to retrieve.
+ /// The service instance of type , or null if not found.
+ public static T GetService() where T : IService
{
- // Check if a service of this type already exists
- if (Instance.GameServices.Any(s => s.GetType() == typeof(T)))
+ if (Services.TryGet(out T Myservice))
{
- Debug.LogWarning($"Service of type {typeof(T).Name} already exists.");
- return null;
+ return Myservice;
}
-
- // Create Service
- T newService = new T();
- newService.provider.Created(author);
- if (Instance.Managers != null)
+ else
{
- foreach (var manager in Instance.Managers)
- {
- manager.ResolveService(newService, true);
- }
+ return default;
}
- Service.OnServiceCreated?.Invoke(newService);
- Instance.GameServices.Add(newService);
- return newService;
}
- public static bool RemoveService(object author) where T : Service
+ ///
+ /// Injects dependencies into the specified target object using the internal dependency injection system.
+ ///
+ /// The object whose dependencies should be injected.
+ public static void Inject(object target)
{
- var service = Instance.GameServices.FirstOrDefault(s => s.GetType() == typeof(T));
- if (service != null)
- {
- if (Instance.Managers != null)
- {
- foreach (var manager in Instance.Managers)
- {
- manager.ResolveService(service, false);
- }
- }
- Service.OnServiceRemoved?.Invoke(service);
- service.provider.Deleted(author);
- Instance.GameServices.Remove(service);
- return true;
- }
-
- Debug.LogWarning($"Service of type {typeof(T).Name} not found to remove.");
- return false;
+ DInjection.Inject(target);
}
- public static T GetService() where T : Service
+ ///
+ /// Registers and enables a feature instance in the dependency injection container.
+ ///
+ /// Type of the feature implementing .
+ /// The feature instance to register.
+ ///
+ /// If true, replaces an existing registered feature of the same type; otherwise keeps the existing one.
+ ///
+ public static void Enable(F instance, bool overwrite = false) where F : IFeature
{
- return Instance.GameServices.OfType().FirstOrDefault();
+ DInjection.Register(instance, overwrite);
}
- public static Service GetService(Type type)
+ ///
+ /// Disables and unregisters a feature of the specified type from the dependency injection container.
+ ///
+ /// Type of the feature implementing .
+ /// True if the feature was successfully removed; otherwise false.
+ public static bool Disable() where F : IFeature
{
- if (!typeof(Service).IsAssignableFrom(type))
- {
- Debug.LogError($"Type {type.Name} is not a valid Service.");
- return null;
- }
-
- return Instance.GameServices.FirstOrDefault(s => s.GetType() == type);
+ return DInjection.Unregister();
+ }
+ ///
+ /// Publishes an event to all subscribers of the specified event type.
+ ///
+ /// Type of the event.
+ /// The event data to publish.
+ public static void Publish(T eventData) where T : IEvent
+ {
+ EventBus.Publish(eventData);
}
- public static bool TryFindService(out T service) where T : Service
+ ///
+ /// Subscribes a listener to a specific event type.
+ ///
+ /// Type of the event to listen for.
+ /// Callback invoked when the event is published.
+ public static void Subscribe(Action listener) where T : IEvent
{
- service = Instance.GameServices.OfType().FirstOrDefault();
- return service != null;
+ EventBus.Subscribe(listener);
}
- public string[] GetAllServiceNames()
+ ///