SettingsSystem (Unity)
Namespace: Vortex.Unity.SettingsSystem, Vortex.Unity.SettingsSystem.Presets, Vortex.Unity.SettingsSystem.Editor
Сборка: ru.vortex.unity.settings
Платформа: Unity 2021.3+
Назначение
Unity-слой системы настроек. Предоставляет драйвер загрузки настроек из Resources, абстрактный ScriptableObject-пресет для хранения конфигурации, автосоздание ассетов настроек при загрузке Editor и встроенный пресет стартовой сцены.
Возможности:
SettingsDriver— загрузка пресетов изResources/Settings/, заполнениеSettingsModelчерезCopyFromSettingsPreset— абстрактныйScriptableObject(базовый класс для пресетов настроек)StartSettings— встроенный пресет: стартовая сцена для Editor- Автосоздание ассетов: при загрузке Editor для каждого
SettingsPreset-наследника без ассета создаётся файл StartSceneHandler— загрузка стартовой сцены при Play Mode в Editor- Меню
Tools > Vortex > Configs > Application Start Config— навигация к ассетуStartSettings
Вне ответственности:
- Шина
Settings, модельSettingsModel, интерфейсIDriver— Core - Логика
CopyFrom(Reflection) —ObjectExtCopyв Extensions
Зависимости
| Зависимость | Назначение |
|---|---|
Vortex.Core.SettingsSystem |
Settings, SettingsModel, IDriver |
Vortex.Core.System |
Singleton<T> |
Vortex.Core.Extensions |
ObjectExtCopy.CopyFrom() |
Vortex.Unity.FileSystem |
File.CreateFolders() |
Vortex.Unity.Extensions |
SoData (базовый класс), MenuConfigSearchController |
| Odin Inspector | [InfoBox], [ValueDropdown] (в StartSettings) |
Архитектура
SettingsDriver : Singleton<SettingsDriver>, IDriver (partial)
├── Model → SettingsModel ← lazy, создаётся при первом обращении
├── Init() → LoadData()
├── GetData() → Model
├── LoadData()
│ ├── CheckPath() → создание Resources/Settings/
│ ├── Resources.LoadAll<SettingsPreset>("Settings")
│ └── foreach preset → Model.CopyFrom(preset)
├── [RuntimeInitializeOnLoadMethod] Run() ← Settings.SetDriver(Instance)
├── [InitializeOnLoadMethod] Run() ← Editor: то же
└── [InitializeOnLoadMethod] EditorRegister() ← автосоздание ассетов
SettingsPreset : SoData (abstract ScriptableObject)
└── Свойства { get; } → копируются в SettingsModel через CopyFrom
StartSettings : SettingsPreset
├── startScene: string ← [ValueDropdown] из Build Settings
└── StartScene → string
StartSceneHandler (Editor, static)
└── [RuntimeInitializeOnLoadMethod] Run()
└── SceneManager.LoadScene(Settings.Data().StartScene)
MenuController (Editor, static)
└── [MenuItem("Tools/Vortex/Configs/Application Start Config")]
└── навигация к ассету StartSettings
Загрузка настроек
SettingsDriver.Run()вызывается через[RuntimeInitializeOnLoadMethod]и[InitializeOnLoadMethod]Settings.SetDriver(Instance)— регистрация драйвера в Core-шине- При первом обращении к
Model— созданиеSettingsModel, вызовLoadData() LoadData()загружает всеSettingsPresetизResources/Settings/- Для каждого пресета —
Model.CopyFrom(preset): Reflection копирует read-only свойства по имени
Автосоздание ассетов (Editor)
EditorRegister() при [InitializeOnLoadMethod]:
- Создание папки
Resources/Settings/если не существует - Поиск всех наследников
SettingsPresetчерез Reflection по всем сборкам - Для каждого типа без существующего ассета —
ScriptableObject.CreateInstance+AssetDatabase.CreateAsset - Лог:
"Create new settings preset {TypeName}"
StartSceneHandler (Editor)
При Play Mode в Editor загружает сцену из Settings.Data().StartScene. Позволяет запускать проект с любой сцены, не меняя Build Settings. Работает только в Editor (#if UNITY_EDITOR).
Контракт
Вход
- Наследники
SettingsPresetсоздаются как ScriptableObject вResources/Settings/ - Ассеты создаются автоматически при загрузке Editor
- Значения настраиваются в Inspector
Выход
Settings.Data()—SettingsModelс агрегированными данными из всех пресетовSettingsDriver.OnInit— событие после загрузки всех пресетов
API
| Компонент | Назначение |
|---|---|
SettingsPreset |
Абстрактный базовый класс для пресетов настроек |
StartSettings |
Встроенный пресет стартовой сцены |
SettingsDriver.OnInit |
Событие завершения загрузки настроек |
Ограничения
| Ограничение | Причина |
|---|---|
Загрузка из Resources/Settings/ |
Resources.LoadAll<SettingsPreset>("Settings") |
| Автосоздание только в Editor | [InitializeOnLoadMethod] + AssetDatabase |
StartSceneHandler только в Editor |
#if UNITY_EDITOR |
Один ассет на тип SettingsPreset |
EditorRegister проверяет resources.Contains(type) |
| Порядок загрузки не определён | Resources.LoadAll не гарантирует порядок |
Использование
Создание нового пресета настроек
- Создать partial-расширение
SettingsModel(Core):
namespace Vortex.Core.SettingsSystem.Model
{
public partial class SettingsModel
{
public int MaxPlayers { get; private set; }
}
}
- Создать наследник
SettingsPreset(Unity):
public class GameplaySettings : SettingsPreset
{
[SerializeField] private int maxPlayers = 4;
public int MaxPlayers => maxPlayers;
}
- Перезагрузить Editor — ассет
GameplaySettings.assetсоздастся автоматически вResources/Settings/ - Настроить значения в Inspector
Навигация к настройкам
Menu: Tools > Vortex > Configs > Application Start Config — открывает ассет StartSettings в Inspector.
Граничные случаи
| Ситуация | Поведение |
|---|---|
Нет ассета для типа SettingsPreset |
Автосоздание при загрузке Editor |
Папка Resources/Settings/ не существует |
Автосоздание через File.CreateFolders |
Драйвер уже установлен (повторный SetDriver) |
Предупреждение в лог, Dispose() нового экземпляра |
CopyFrom не нашёл свойство |
Свойство модели остаётся default |
StartScene пустой |
SceneManager.LoadScene("") — ошибка Unity |
| Ассет удалён вручную | Пересоздастся при следующей загрузке Editor |
| Несколько пресетов с одинаковым свойством | Последний из LoadAll перезапишет значение |