diff --git a/Assets/Pacore/.gitignore b/Assets/Pacore/.gitignore new file mode 100644 index 0000000..ce22883 --- /dev/null +++ b/Assets/Pacore/.gitignore @@ -0,0 +1,3 @@ +# Files are generated/modified at runtime and do not need backing up # +Resources.meta +Resources diff --git a/Assets/Pacore/Editor/Data.meta b/Assets/Pacore/Editor/Data.meta new file mode 100644 index 0000000..22716e6 --- /dev/null +++ b/Assets/Pacore/Editor/Data.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 023429caa3904eb99618d2b079e3a508 +timeCreated: 1769386974 \ No newline at end of file diff --git a/Assets/Pacore/Editor/Data/CreateScriptableObject.cs b/Assets/Pacore/Editor/Data/CreateScriptableObject.cs new file mode 100644 index 0000000..caff907 --- /dev/null +++ b/Assets/Pacore/Editor/Data/CreateScriptableObject.cs @@ -0,0 +1,25 @@ +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace PashaBibko.Pacore.Editor.Data +{ + public static class ScriptableObjectGenerator + { + public static T Create(string path, string name) where T : ScriptableObject + { + /* Creates the asset instance */ + T asset = ScriptableObject.CreateInstance(); + + /* Creates the file on disk */ + string fullpath = Path.Join(path, name); + AssetDatabase.CreateAsset(asset, fullpath); + + /* Refreshes the asset database before returning */ + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + + return asset; + } + } +} diff --git a/Assets/Pacore/Editor/Data/CreateScriptableObject.cs.meta b/Assets/Pacore/Editor/Data/CreateScriptableObject.cs.meta new file mode 100644 index 0000000..d5bc177 --- /dev/null +++ b/Assets/Pacore/Editor/Data/CreateScriptableObject.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 670c37fd285242438eabfb6c328a7e53 +timeCreated: 1769363293 \ No newline at end of file diff --git a/Assets/Pacore/Editor/Data/PacoreDataCreator.cs b/Assets/Pacore/Editor/Data/PacoreDataCreator.cs new file mode 100644 index 0000000..7b852d4 --- /dev/null +++ b/Assets/Pacore/Editor/Data/PacoreDataCreator.cs @@ -0,0 +1,42 @@ +using PashaBibko.Pacore.Data; +using UnityEditor; +using System.IO; +using System.Reflection; + +namespace PashaBibko.Pacore.Editor.Data +{ + [InitializeOnLoad] public static class PacoreDataCreator + { + private static StaticFieldValues ValuesAsset; + + static PacoreDataCreator() // Runs on editor startup or recompile + { + /* Creates the folder for the data files */ + if (!Directory.Exists(PacoreDataLoader.FullResourcesPath)) + { + Directory.CreateDirectory(PacoreDataLoader.FullResourcesPath); + } + + /* Creates the ScriptableObject asset file for StaticFieldValues */ + const string VALUES_NAME = "StaticFieldValues.asset"; // .asset is REQUIRED by unity API + string valuesPath = Path.Combine(PacoreDataLoader.ResourcesPath, VALUES_NAME); + if (!File.Exists(valuesPath)) + { + ValuesAsset = ScriptableObjectGenerator.Create + ( + path: PacoreDataLoader.ResourcesPath, + name: VALUES_NAME + ); + } + + /* If one already exists loads it */ + else + { + ValuesAsset = AssetDatabase.LoadAssetAtPath(valuesPath); + } + } + + public static void SetStaticFieldValue(FieldInfo field, object value) + => ValuesAsset.AddValue(field, value); + } +} diff --git a/Assets/Pacore/Editor/Data/PacoreDataCreator.cs.meta b/Assets/Pacore/Editor/Data/PacoreDataCreator.cs.meta new file mode 100644 index 0000000..8e7b230 --- /dev/null +++ b/Assets/Pacore/Editor/Data/PacoreDataCreator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: da662fed35ba45aa890b57c00f94a987 +timeCreated: 1769375660 \ No newline at end of file diff --git a/Assets/Pacore/Editor/Data/StaticFieldValuesExtensions.cs b/Assets/Pacore/Editor/Data/StaticFieldValuesExtensions.cs new file mode 100644 index 0000000..d0d5345 --- /dev/null +++ b/Assets/Pacore/Editor/Data/StaticFieldValuesExtensions.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using PashaBibko.Pacore.Data; +using UnityEditor; +using UnityEngine; + +namespace PashaBibko.Pacore.Editor.Data +{ + public static class StaticFieldValuesExtensions + { + public static void AddValue(this StaticFieldValues asset, FieldInfo info, object value) + { + /* Checks field has a declaring type */ + Type declaringType = info.DeclaringType; + if (declaringType == null) + { + Debug.LogError($"[StaticFieldValues] Cannot add field {info.Name} because it has no declaring type"); + return; + } + + /* Checks if the type is already contained */ + string typename = declaringType.FullName; + int tIdx = -1; + + if (asset.StoredValues != null) + { + for (int i = 0; i < asset.StoredValues.Length; i++) + { + if (asset.StoredValues[i].Typename == typename) + { + tIdx = i; + break; + } + } + } + + /* Adds the type if it is not contained */ + if (tIdx == -1) + { + StaticFieldValues.TypeFieldValues newType = new() + { + Typename = typename, + Fields = Array.Empty() + }; + + List types = asset.StoredValues?.ToList() ?? + new List(); + types.Add(newType); + + asset.StoredValues = types.ToArray(); + tIdx = types.Count - 1; // -1 for 0 based indexing + } + + /* Checks if the field is already contained in the type */ + string fieldName = info.Name; + int sIdx = -1; + + Debug.Assert(asset.StoredValues != null, nameof(asset.StoredValues) + " != null"); + for (int i = 0; i < asset.StoredValues[tIdx].Fields.Length; i++) + { + if (asset.StoredValues[tIdx].Fields[i].Name == fieldName) + { + sIdx = i; + break; + } + } + + /* Adds the field if it is not contained */ + if (sIdx == -1) + { + StaticFieldValues.FieldValue newValue = new() + { + SerializedValue = value.ToString(), + Name = fieldName + }; + + List fields = asset.StoredValues[tIdx].Fields?.ToList() ?? + new List(); + fields.Add(newValue); + + asset.StoredValues[tIdx].Fields = fields.ToArray(); + } + + /* Else updates the value */ + else + { + asset.StoredValues[tIdx].Fields[sIdx].SerializedValue = value.ToString(); + } + + /* Tells Unity to save the value */ + EditorUtility.SetDirty(asset); + AssetDatabase.SaveAssets(); + } + } +} \ No newline at end of file diff --git a/Assets/Pacore/Editor/Data/StaticFieldValuesExtensions.cs.meta b/Assets/Pacore/Editor/Data/StaticFieldValuesExtensions.cs.meta new file mode 100644 index 0000000..4bca6b9 --- /dev/null +++ b/Assets/Pacore/Editor/Data/StaticFieldValuesExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4ba9a121a4524876b105945f75e1e79d +timeCreated: 1769387061 \ No newline at end of file diff --git a/Assets/Pacore/Editor/Drawers/MonoBehaviourDrawer.cs b/Assets/Pacore/Editor/Drawers/MonoBehaviourDrawer.cs index 9a30e33..a114091 100644 --- a/Assets/Pacore/Editor/Drawers/MonoBehaviourDrawer.cs +++ b/Assets/Pacore/Editor/Drawers/MonoBehaviourDrawer.cs @@ -3,6 +3,7 @@ using UnityEditor; using UnityEngine; using System; using System.Reflection; +using PashaBibko.Pacore.Editor.Data; using Object = UnityEngine.Object; namespace PashaBibko.Pacore.Editor.Drawers @@ -57,7 +58,14 @@ namespace PashaBibko.Pacore.Editor.Drawers for (int i = 0; i < fields.Length; i++) { + EditorGUI.BeginChangeCheck(); fields[i].Value = DrawStaticField(fields[i].Info, fields[i].Value); + bool changed = EditorGUI.EndChangeCheck(); + + if (changed) + { + PacoreDataCreator.SetStaticFieldValue(fields[i].Info, fields[i].Value); + } } } diff --git a/Assets/Pacore/Runtime/Data.meta b/Assets/Pacore/Runtime/Data.meta new file mode 100644 index 0000000..f51a5f7 --- /dev/null +++ b/Assets/Pacore/Runtime/Data.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d323da97ac614fdb8e6d952111ba0b7d +timeCreated: 1769362533 \ No newline at end of file diff --git a/Assets/Pacore/Runtime/Data/DataLoader.cs b/Assets/Pacore/Runtime/Data/DataLoader.cs new file mode 100644 index 0000000..12bf328 --- /dev/null +++ b/Assets/Pacore/Runtime/Data/DataLoader.cs @@ -0,0 +1,12 @@ +using System.IO; +using UnityEngine; + +namespace PashaBibko.Pacore.Data +{ + public static class PacoreDataLoader + { + private const string BASE_PATH = "Pacore/Resources/PacoreData"; + public static string FullResourcesPath => Path.Join(Application.dataPath, BASE_PATH); + public static string ResourcesPath => Path.Join("Assets", BASE_PATH); + } +} diff --git a/Assets/Pacore/Runtime/Data/DataLoader.cs.meta b/Assets/Pacore/Runtime/Data/DataLoader.cs.meta new file mode 100644 index 0000000..ca6c947 --- /dev/null +++ b/Assets/Pacore/Runtime/Data/DataLoader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 79da011308294074b6edb339ac2f271b +timeCreated: 1769372269 \ No newline at end of file diff --git a/Assets/Pacore/Runtime/Data/StaticFieldValues.cs b/Assets/Pacore/Runtime/Data/StaticFieldValues.cs new file mode 100644 index 0000000..ab57ebc --- /dev/null +++ b/Assets/Pacore/Runtime/Data/StaticFieldValues.cs @@ -0,0 +1,22 @@ +using UnityEngine; +using System; + +namespace PashaBibko.Pacore.Data +{ + public class StaticFieldValues : ScriptableObject + { + [Serializable] public struct FieldValue + { + public string SerializedValue; + public string Name; + } + + [Serializable] public struct TypeFieldValues + { + public string Typename; + public FieldValue[] Fields; + } + + public TypeFieldValues[] StoredValues; + } +} diff --git a/Assets/Pacore/Runtime/Data/StaticFieldValues.cs.meta b/Assets/Pacore/Runtime/Data/StaticFieldValues.cs.meta new file mode 100644 index 0000000..912c2c9 --- /dev/null +++ b/Assets/Pacore/Runtime/Data/StaticFieldValues.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7e0846e954a8489cbc43e81d8f1dcc01 +timeCreated: 1769362550 \ No newline at end of file