init
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d237fce79f744309f3744dcfb79d002
|
||||
timeCreated: 1759058841
|
||||
@@ -0,0 +1,21 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RPGCoreCommon.Settings.Editor
|
||||
{
|
||||
[CustomEditor(typeof(MainSettingsSO))]
|
||||
internal class MainSettingsSODrawer : UnityEditor.Editor
|
||||
{
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
var rootElement = new VisualElement();
|
||||
|
||||
var button = new Button();
|
||||
button.text = "Open settings editor";
|
||||
button.clicked += SettingsEditorWindow.ShowSettingsEditor;
|
||||
|
||||
rootElement.Add(button);
|
||||
return rootElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55ff5e0dc4c245da9af8fa287298efaa
|
||||
timeCreated: 1759062565
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "RPGCoreCommon.Settings.Editor",
|
||||
"rootNamespace": "RPGCoreCommon.Settings.Editor",
|
||||
"references": [
|
||||
"RPGCoreCommon.Settings",
|
||||
"RPGCoreCommon.Helpers"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82c9ca36f8574ede9895a338716393c3
|
||||
timeCreated: 1759058870
|
||||
@@ -0,0 +1,278 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Compilation;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace RPGCoreCommon.Settings.Editor
|
||||
{
|
||||
internal class SettingsEditorWindow : EditorWindow
|
||||
{
|
||||
[SerializeField] private VisualTreeAsset _visualTreeAsset;
|
||||
|
||||
private const string FolderName = "_CustomSettings";
|
||||
private const string FolderPath = "Assets/" + FolderName;
|
||||
|
||||
private const string CreateExampleContent = @"using RPGCoreCommon.Settings;
|
||||
|
||||
[CustomSettings(""Example Custom Settings"")]
|
||||
public class ExampleCustomSettingsSO : CustomSettingsSO
|
||||
{
|
||||
public string exampleText;
|
||||
public int exampleNumber;
|
||||
}
|
||||
";
|
||||
|
||||
// ELEMENTS
|
||||
private ScrollView _listElement;
|
||||
private ObjectField _objectField;
|
||||
private InspectorElement _inspectorElement;
|
||||
private VisualElement _errorElement;
|
||||
private VisualElement _missingElement;
|
||||
private Button _reloadDomainButton;
|
||||
private Button _createExampleButton;
|
||||
private Button _createMissingButton;
|
||||
|
||||
// SETTINGS
|
||||
private MainSettingsSO _mainSettings;
|
||||
private Dictionary<string, Type> _settingsTypeMap;
|
||||
private string _currentKey;
|
||||
|
||||
[MenuItem("TheVVaS/RPGCore/Settings Editor")]
|
||||
public static void ShowSettingsEditor()
|
||||
{
|
||||
var window = GetWindow<SettingsEditorWindow>();
|
||||
window.titleContent = new GUIContent("Custom Settings Editor");
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public override void SaveChanges()
|
||||
{
|
||||
_mainSettings.settings.ForEach(EditorUtility.SetDirty);
|
||||
_mainSettings.settings.ForEach(AssetDatabase.SaveAssetIfDirty);
|
||||
EditorUtility.SetDirty(_mainSettings);
|
||||
AssetDatabase.SaveAssetIfDirty(_mainSettings);
|
||||
hasUnsavedChanges = false;
|
||||
}
|
||||
|
||||
private void CreateGUI()
|
||||
{
|
||||
_visualTreeAsset.CloneTree(rootVisualElement);
|
||||
|
||||
_listElement = rootVisualElement.Q<ScrollView>("cs-left");
|
||||
_listElement.Clear();
|
||||
_objectField = rootVisualElement.Q<ObjectField>("cs-settings-object");
|
||||
_objectField.RegisterValueChangedCallback(ev => OnObjectChanged(ev.newValue));
|
||||
_inspectorElement = rootVisualElement.Q<InspectorElement>("cs-settings-inspector");
|
||||
_errorElement = rootVisualElement.Q<VisualElement>("cs-error");
|
||||
_missingElement = rootVisualElement.Q<VisualElement>("cs-missing");
|
||||
_reloadDomainButton = rootVisualElement.Q<Button>("cs-reload-domain");
|
||||
_reloadDomainButton.clicked += EditorUtility.RequestScriptReload;
|
||||
_createExampleButton = rootVisualElement.Q<Button>("cs-create-example");
|
||||
_createExampleButton.clicked += CreateExampleSettings;
|
||||
_createMissingButton = rootVisualElement.Q<Button>("cs-create-missing");
|
||||
_createMissingButton.clicked += () => CreateMissingSettings(_settingsTypeMap[_currentKey]);
|
||||
|
||||
// Base info
|
||||
_mainSettings = FindOrCreateMainSettings();
|
||||
_settingsTypeMap = CreateSettingsTypeMap();
|
||||
|
||||
// No custom settings found - maybe user didn't create any yet? maybe domain is not reloaded? Show alternative
|
||||
if (!_settingsTypeMap.Any())
|
||||
{
|
||||
_errorElement.style.display = DisplayStyle.Flex;
|
||||
return;
|
||||
}
|
||||
|
||||
// Select first settings available
|
||||
PopulateList();
|
||||
SelectKey(_settingsTypeMap.Keys.First());
|
||||
}
|
||||
|
||||
private void PopulateList()
|
||||
{
|
||||
var orderedKeys = _settingsTypeMap.Keys.OrderBy(key => key.Count(s => s == '/')).ToList();
|
||||
|
||||
foreach (var key in orderedKeys)
|
||||
{
|
||||
var isEmpty = !orderedKeys.Any(k => k.StartsWith(key + "/"));
|
||||
var isSelectable = _settingsTypeMap[key] is not null;
|
||||
var parentKey = string.Join('/', key.Split('/').SkipLast(1));
|
||||
var parent = string.IsNullOrEmpty(parentKey) ? _listElement : _listElement.Q(parentKey);
|
||||
var foldout = new Foldout();
|
||||
foldout.name = key;
|
||||
foldout.text = key.Split('/').Last();
|
||||
foldout.toggleOnLabelClick = false;
|
||||
foldout.Q<Label>().RegisterCallback<MouseDownEvent>(_ => SelectKey(key));
|
||||
|
||||
if (isEmpty) foldout.AddToClassList("empty");
|
||||
if (isSelectable) foldout.AddToClassList("selectable");
|
||||
|
||||
parent.Add(foldout);
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectKey(string key)
|
||||
{
|
||||
var isSelectable = _settingsTypeMap[key] is not null;
|
||||
if (!isSelectable) return;
|
||||
|
||||
_listElement.Query(className: "selected").ForEach(el => el.RemoveFromClassList("selected"));
|
||||
_listElement.Q(key).AddToClassList("selected");
|
||||
_currentKey = key;
|
||||
RefreshInspector(key);
|
||||
}
|
||||
|
||||
private void RefreshInspector(string key)
|
||||
{
|
||||
// Clicked foldout without settings attached - do nothing
|
||||
if (_settingsTypeMap[key] is not {} settingsType) return;
|
||||
|
||||
var settings = _mainSettings.settings.FirstOrDefault(s => s.GetType() == settingsType);
|
||||
|
||||
_objectField.objectType = settingsType;
|
||||
_objectField.SetValueWithoutNotify(settings);
|
||||
_inspectorElement.Unbind();
|
||||
_inspectorElement.Clear();
|
||||
|
||||
if (settings)
|
||||
{
|
||||
_inspectorElement.Bind(new SerializedObject(settings));
|
||||
_missingElement.style.display = DisplayStyle.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
_missingElement.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnObjectChanged(Object newSettings)
|
||||
{
|
||||
hasUnsavedChanges = true;
|
||||
|
||||
var settingsType = _settingsTypeMap[_currentKey];
|
||||
if (newSettings.GetType() != settingsType)
|
||||
{
|
||||
Debug.LogError($"Only acceptable type here is: <b>{settingsType}</b>");
|
||||
return;
|
||||
}
|
||||
|
||||
_mainSettings.settings.RemoveAll(s => s.GetType() == settingsType);
|
||||
_mainSettings.settings.Add((CustomSettingsSO)newSettings);
|
||||
RefreshInspector(_currentKey);
|
||||
}
|
||||
|
||||
private void CreateMissingSettings(Type settingsType)
|
||||
{
|
||||
// Create and load wanted settings
|
||||
if (!AssetDatabase.AssetPathExists(FolderPath)) AssetDatabase.CreateFolder("Assets", FolderName);
|
||||
var path = FolderPath + "/" + settingsType.Name + ".asset";
|
||||
AssetDatabase.CreateAsset(CreateInstance(settingsType), path);
|
||||
var settings = AssetDatabase.LoadAssetAtPath<CustomSettingsSO>(path);
|
||||
|
||||
// Update Main Settings
|
||||
_mainSettings.settings.RemoveAll(s => s.GetType() == settingsType);
|
||||
_mainSettings.settings.Add(settings);
|
||||
|
||||
OnObjectChanged(settings);
|
||||
}
|
||||
|
||||
private void CreateExampleSettings()
|
||||
{
|
||||
var absolutePath = Application.dataPath + "/CustomSettingsSO example.cs";
|
||||
var relativePath = "Assets/CustomSettingsSO example.cs";
|
||||
File.AppendAllText(absolutePath, CreateExampleContent);
|
||||
AssetDatabase.ImportAsset(relativePath);
|
||||
AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath<MonoScript>(relativePath));
|
||||
}
|
||||
|
||||
private MainSettingsSO FindOrCreateMainSettings()
|
||||
{
|
||||
var mainPath = GetMainSettingsAssetPath();
|
||||
var paths = AssetDatabase.FindAssets($"t:{nameof(MainSettingsSO)}").Select(AssetDatabase.GUIDToAssetPath).ToList();
|
||||
paths.Remove(mainPath);
|
||||
|
||||
// MainSettings not found or moved - move to original folder or recreate if missing
|
||||
if (!AssetDatabase.AssetPathExists(mainPath))
|
||||
{
|
||||
Debug.LogWarning($"{nameof(MainSettingsSO)} not found in '{mainPath}'!");
|
||||
|
||||
if (paths.Count > 0)
|
||||
{
|
||||
Debug.LogWarning($"{nameof(MainSettingsSO)} found in <b>{paths[0]}</b>, moved to its original path: <b>{mainPath}</b>!");
|
||||
AssetDatabase.MoveAsset(paths[0], mainPath);
|
||||
paths.RemoveAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetDatabase.CreateAsset(CreateInstance<MainSettingsSO>(), mainPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Illegal or invalid assets found - DELETE them
|
||||
if (paths.Count > 0)
|
||||
{
|
||||
Debug.LogWarning($"Multiple {nameof(MainSettingsSO)} found, deleting all excessive ones: {string.Join(", ", paths)}");
|
||||
paths.ForEach(path => AssetDatabase.DeleteAsset(path));
|
||||
}
|
||||
|
||||
return AssetDatabase.LoadAssetAtPath<MainSettingsSO>(mainPath);
|
||||
}
|
||||
|
||||
private Dictionary<string, Type> CreateSettingsTypeMap()
|
||||
{
|
||||
var dict = new Dictionary<string, Type>();
|
||||
|
||||
// Assign unique key to each settings type
|
||||
foreach (var settingsType in TypeCache.GetTypesDerivedFrom<CustomSettingsSO>())
|
||||
{
|
||||
if (!settingsType.IsClass || settingsType.IsAbstract) continue;
|
||||
if (settingsType == typeof(MainSettingsSO)) continue;
|
||||
|
||||
var attribute = settingsType.GetCustomAttribute<CustomSettingsAttribute>();
|
||||
var settingsPath = attribute?.path ?? settingsType.Name;
|
||||
|
||||
var pathDuplicated = false;
|
||||
while (dict.ContainsKey(settingsPath))
|
||||
{
|
||||
pathDuplicated = true;
|
||||
settingsPath += " ?";
|
||||
}
|
||||
|
||||
if (pathDuplicated)
|
||||
{
|
||||
Debug.LogWarning($"Class <b>{settingsType}</b> has already used path, using <b>{settingsPath}</b> instead!" +
|
||||
$"Change path with attribute <b>{nameof(CustomSettingsAttribute)}</b>");
|
||||
}
|
||||
|
||||
dict[settingsPath] = settingsType;
|
||||
}
|
||||
|
||||
// Fill empty key to create empty parents if needed
|
||||
foreach (var key in dict.Keys.ToList())
|
||||
{
|
||||
var keySplitted = key.Split('/');
|
||||
for (var i = 1; i < keySplitted.Length; i++)
|
||||
dict.TryAdd(string.Join("/", keySplitted.Take(i)), null);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
private string GetMainSettingsAssetPath()
|
||||
{
|
||||
var projectPath = Application.dataPath.Replace("/Assets", "");
|
||||
var filePath = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName("RPGCoreCommon.Settings");
|
||||
var path = Path.GetDirectoryName(filePath);
|
||||
var relativePath = Path.GetRelativePath(projectPath, path);
|
||||
var relativeAssetPath = Path.Combine(relativePath, "Resources", "MainSettings.asset");
|
||||
return relativeAssetPath.Replace("\\", "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81335a84d15c49adac057f7724847fb4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- m_ViewDataDictionary: {instanceID: 0}
|
||||
- _visualTreeAsset: {fileID: 9197481963319205126, guid: 4de99465844afaa409a38eb7a9b3c599, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,128 @@
|
||||
#cs-left {
|
||||
padding-right: 2px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
#cs-left #unity-content {
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#cs-left Toggle {
|
||||
margin-top: 2px;
|
||||
margin-right: 2px;
|
||||
margin-bottom: 2px;
|
||||
margin-left: 2px;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
#cs-left Foldout Toggle {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#cs-left Foldout Foldout Toggle {
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
#cs-left Foldout Foldout Foldout Toggle {
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
#cs-left Foldout Foldout Foldout Foldout Toggle {
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
#cs-left Foldout Foldout Foldout Foldout Foldout Toggle {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
#cs-left Foldout Foldout Foldout Foldout Foldout Foldout Toggle {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
Foldout.selectable > Toggle:hover {
|
||||
background-color: rgba(255, 255, 255, 0.04);
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
Foldout.selected > Toggle {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
background-color: rgba(255, 255, 255, 0.14);
|
||||
-unity-font-style: bold;
|
||||
}
|
||||
|
||||
Foldout.empty > Toggle #unity-checkmark {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#cs-right {
|
||||
}
|
||||
|
||||
#cs-right #cs-settings-object {
|
||||
padding-top: 5px;
|
||||
padding-right: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
background-color: rgba(255, 255, 255, 0.12);
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 5px;
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
#cs-right #cs-settings-inspector #unity-input-m_Script {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#cs-error {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
background-color: var(--unity-colors-window-background);
|
||||
display: none;
|
||||
}
|
||||
|
||||
#cs-error > Label {
|
||||
width: 100%;
|
||||
font-size: 24px;
|
||||
-unity-font-style: bold;
|
||||
-unity-text-align: middle-center;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#cs-error > .cs-error-block {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
#cs-error > .cs-error-block > HelpBox {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#cs-error > .cs-error-block > Button {
|
||||
}
|
||||
|
||||
#cs-missing {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#cs-missing HelpBox {
|
||||
flex-grow: 1;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2328868bd9cdc2946a328e88f4b9f71c
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,45 @@
|
||||
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
|
||||
<Style src="project://database/Assets/TheVVaS/RPGCoreCommon/Settings/Editor/SettingsEditorWindow.uss?fileID=7433441132597879392&guid=2328868bd9cdc2946a328e88f4b9f71c&type=3#SettingsEditorWindow" />
|
||||
<RPGCoreCommon.Helpers.UIElements.TwoPaneSplitView fixed-pane-initial-dimension="160">
|
||||
<ui:ScrollView name="cs-left">
|
||||
<ui:Foldout text="Foldout" name="Foldout" class="selectable">
|
||||
<ui:Foldout text="Foldout" class="empty selectable" />
|
||||
<ui:Foldout text="Foldout" class="empty selectable" />
|
||||
<ui:Foldout text="Foldout" class="selectable">
|
||||
<ui:Foldout text="Foldout" class="empty selected selectable" />
|
||||
<ui:Foldout text="Foldout" class="empty selectable" />
|
||||
</ui:Foldout>
|
||||
</ui:Foldout>
|
||||
<ui:Foldout text="Foldout">
|
||||
<ui:Foldout text="Foldout">
|
||||
<ui:Foldout text="Foldout">
|
||||
<ui:Foldout text="Foldout">
|
||||
<ui:Foldout text="Foldout" class="selectable">
|
||||
<ui:Foldout text="Foldout" name="Foldout" class="empty selectable" />
|
||||
</ui:Foldout>
|
||||
</ui:Foldout>
|
||||
</ui:Foldout>
|
||||
</ui:Foldout>
|
||||
</ui:Foldout>
|
||||
</ui:ScrollView>
|
||||
<ui:VisualElement name="cs-right" style="flex-grow: 1;">
|
||||
<uie:ObjectField label="Settings file:" name="cs-settings-object" type="RPGCoreCommon.Settings.CustomSettingsSO, RPGCoreCommon.Settings" />
|
||||
<RPGCoreCommon.Helpers.Editor.UIElements.InspectorElement name="cs-settings-inspector" />
|
||||
<ui:VisualElement name="cs-missing">
|
||||
<RPGCoreCommon.Helpers.UIElements.HelpBox message-type="Warning" text="<b>CustomSettings is missing!</b><br>Drag/Select existing settings of that type or press <b>Generate...</b> to create new one.<br>Generated file will be opened with default editor." />
|
||||
<ui:Button text="Generate..." name="cs-create-missing" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</RPGCoreCommon.Helpers.UIElements.TwoPaneSplitView>
|
||||
<ui:VisualElement name="cs-error">
|
||||
<ui:Label text="CustomSettings cannot be loaded!" />
|
||||
<ui:VisualElement class="cs-error-block">
|
||||
<RPGCoreCommon.Helpers.UIElements.HelpBox text="<b>Fix errors and reload domain</b><br>Its possible that unity didn't save your implementation of CustomSettingsSO to cache properly.<br>Fix all code errors and press <b>Reload Domain</b> (ctrl + r)." message-type="Error" />
|
||||
<ui:Button text="Reload Domain" name="cs-reload-domain" />
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement class="cs-error-block">
|
||||
<RPGCoreCommon.Helpers.UIElements.HelpBox text="<b>Create new CustomSettingsSO example</b><br>You didn't create any CustomSettingsSO so far.<br>You can do it by yourself or by clicking <b>Create Example</b>." message-type="Error" />
|
||||
<ui:Button text="Create Example" name="cs-create-example" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4de99465844afaa409a38eb7a9b3c599
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 998d4a8463fe4de69ae4b37b478e12df
|
||||
timeCreated: 1759058847
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace RPGCoreCommon.Settings
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class CustomSettingsAttribute : Attribute
|
||||
{
|
||||
internal string path { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Optionally attached to class that extends <see cref="CustomSettingsSO"/>.<br/>
|
||||
/// All paths in project should be unique otherwise different name will be generated.
|
||||
/// </summary>
|
||||
/// <param name="path">custom path and name with "/" as delimiter.</param>
|
||||
public CustomSettingsAttribute(string path)
|
||||
{
|
||||
this.path = new Regex("/+").Replace(path, "/").Trim('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f707df1d72104aee928f9c94d1bdaf78
|
||||
timeCreated: 1759151290
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGCoreCommon.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// Extend this to create new type of settings. These will be automatically added to settings editor window.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract class CustomSettingsSO : ScriptableObject
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0846fc0c7874dd182f4dd9f83a06acf
|
||||
timeCreated: 1759059292
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("RPGCoreCommon.Settings.Editor")]
|
||||
|
||||
namespace RPGCoreCommon.Settings
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a05ba05117242eca64be63d17123d74
|
||||
timeCreated: 1759063680
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGCoreCommon.Settings
|
||||
{
|
||||
internal class MainSettingsSO : CustomSettingsSO
|
||||
{
|
||||
[SerializeReference] internal List<CustomSettingsSO> settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1b15ea3617b447290121c2f34009f42
|
||||
timeCreated: 1759059460
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "RPGCoreCommon.Settings",
|
||||
"rootNamespace": "RPGCoreCommon.Settings",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42d6bbb0c4c8403d800c75cd28a1feef
|
||||
timeCreated: 1759058936
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f81c1b5e2a3146898d759c18b6a9ffa0
|
||||
timeCreated: 1759058859
|
||||
@@ -0,0 +1,21 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e1b15ea3617b447290121c2f34009f42, type: 3}
|
||||
m_Name: MainSettings
|
||||
m_EditorClassIdentifier:
|
||||
settings:
|
||||
- {fileID: 11400000, guid: 6dbd2048bd875ca42bf5e2ccd3282671, type: 2}
|
||||
- {fileID: 11400000, guid: 4bc4327b80b188146b7b4df067d792b0, type: 2}
|
||||
- {fileID: 11400000, guid: f583031a590e02f4da97ee00f6d56be7, type: 2}
|
||||
- {fileID: 11400000, guid: f96c774b23415ae46a33cd04b1eeb0f7, type: 2}
|
||||
- {fileID: 11400000, guid: f1565c1ea85209c46b34b5066482be4b, type: 2}
|
||||
- {fileID: 11400000, guid: 9df758ff4bf9af948aa6ad53f610288b, type: 2}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a07eaaeda7416b4f8c78d79c5f9fb8c
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGCoreCommon.Settings
|
||||
{
|
||||
public static class SettingsManager
|
||||
{
|
||||
private static MainSettingsSO _mainSettings;
|
||||
|
||||
public static T Get<T>() where T : CustomSettingsSO
|
||||
{
|
||||
_mainSettings ??= Resources.Load<MainSettingsSO>("MainSettings");
|
||||
return _mainSettings.settings.FirstOrDefault(settings => settings is T) as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9233d376eb8d441c8557a2489d3f39cd
|
||||
timeCreated: 1759058999
|
||||
Reference in New Issue
Block a user