Class SettingsAssetAuthoring
Shared, engine-side (non-IMGUI) plumbing every single-settings-asset creation wizard needs: resolving
the project-wide settings asset the way the runtime picks it (explicit path, the project's own copy over a
shipped one, an ambiguity between two project copies, or none), Assets-path shape
validation, recursive folder creation with a rollback-friendly created-paths trail, and a hardened
asset-write check. Extracted from Serenity.GameProgress.Infrastructure.Editor.Builder.GameProgressCreator
and Serenity.GameSave.Infrastructure.Editor.Builder.GameSaveCreator, which were byte-for-byte
duplicating this exact logic. Serenity.Leaderboard.Infrastructure.Editor.Builder.LeaderboardCreator
exposes ResolveSettingsContext publicly like every other adopter, and resolves-or-creates its
settings asset through ResolveOrCreateAtPath<TSettings>(SettingsResolution<TSettings>, string, string, string, SerenityAssetCreationTransaction, out bool); its
board-uniqueness and view/menu-option resolution live on top of both and this shared helper knows
nothing about them.
Inheritance
SettingsAssetAuthoring
Assembly: Serenity.UnityStructuredPersistence.Infrastructure.Editor.dll
Syntax
public static class SettingsAssetAuthoring
Methods
EnsureProjectFolderExists(string, ICollection<string>)
Creates every missing segment of folderPath under the project's Assets folder,
appending each newly created folder to createdPaths (shallowest first) so a
caller's rollback can delete them in reverse order: assets first (appended last), then folders
deepest-to-shallowest. A folder Unity's cache already reports as valid is left untouched.
createdPaths takes any ICollection<T> — including
Serenity.Global.Infrastructure.Editor.SerenityAssetCreationTransaction.FolderTracking —
not just a concrete List<T>.
Declaration
public static void EnsureProjectFolderExists(string folderPath, ICollection<string> createdPaths)
Parameters
Path-shape validation for a folder that will hold generated assets. A folder that does not exist
yet is considered valid — EnsureProjectFolderExists(string, ICollection<string>) creates it during creation — this
only rejects paths outside the project's Assets folder, or with empty/invalid segments.
Declaration
public static bool IsWellFormedAssetsPath(string path)
Parameters
| Type |
Name |
Description |
| string |
path |
|
Returns
RequireProperty(SerializedObject, string)
UnityEditor.SerializedObject.FindProperty(System.String) returns null — not an exception — for a field name
that does not exist, so an unguarded chain like serializedObject.FindProperty("x").intValue = ...
turns a renamed [SerializeField] into a NullReferenceException with no indication
of which property or asset was involved. This resolves the property or throws a precise,
self-diagnosing error instead.
Declaration
public static SerializedProperty RequireProperty(SerializedObject serializedObject, string propertyName)
Parameters
| Type |
Name |
Description |
| SerializedObject |
serializedObject |
|
| string |
propertyName |
|
Returns
| Type |
Description |
| SerializedProperty |
|
ResolveSettingsContext(string, string, string)
Lists every asset of type settingsTypeName by its simple type name, for a caller whose
assembly cannot reference the concrete settings type. Unlike ResolveSettingsContext<TSettings>(string, string)
this applies no ownership rule: an explicit explicitSettingsAssetPath wins outright;
otherwise a search — the whole project, or just searchRootFolder when given — returns
the lone match, no match, or flags every path found when more than one exists, shipped copies included,
because its callers read the whole candidate set themselves (a collection system's members, the
adopted twin beside a shipped default). A caller resolving a singleton wants
ResolveSingletonSettingsContext(string, string, string) instead. The resolved asset is loaded via
UnityEditor.AssetDatabase.LoadMainAssetAtPath(System.String) since the concrete type is not known here.
Declaration
public static SettingsAssetAuthoring.SettingsResolution ResolveSettingsContext(string settingsTypeName, string explicitSettingsAssetPath, string searchRootFolder = null)
Parameters
| Type |
Name |
Description |
| string |
settingsTypeName |
|
| string |
explicitSettingsAssetPath |
|
| string |
searchRootFolder |
|
Returns
ResolveSettingsContext<TSettings>(string, string)
Resolves the one project-wide TSettings asset a wizard edits — the same asset the
runtime boots on. An explicit explicitSettingsAssetPath wins outright (a test seam and
an already-known-asset fast path). Otherwise a search — the whole project, or just
searchRootFolder when given — applies the boot-time ownership rule
(Serenity.Global.Infrastructure.Editor.SerenitySingletonSettingsAudit.ResolveSelection(System.Collections.Generic.IReadOnlyList{System.String}), the editor mirror of
UnitySingletonSettingsLoader): the project's own copy beats a shipped one, so after adoption the
adopted copy resolves and the shipped original is not a candidate at all; with no project copy the
shipped copy the runtime falls back to resolves; and two or more project copies are the one real
ambiguity, reported as every project copy's path — never a shipped one, which is not the author's to
delete or merge.
Declaration
public static SettingsAssetAuthoring.SettingsResolution<TSettings> ResolveSettingsContext<TSettings>(string explicitSettingsAssetPath, string searchRootFolder = null) where TSettings : Object
Parameters
| Type |
Name |
Description |
| string |
explicitSettingsAssetPath |
|
| string |
searchRootFolder |
Test seam: narrows the scan to this single Assets-rooted folder
instead of the whole project, so a test creating its own TSettings fixtures
under a temp folder does not collide with a package-shipped singleton elsewhere in the project.
Null (the default) scans the whole project, matching every caller before this parameter existed.
|
Returns
Type Parameters
| Name |
Description |
| TSettings |
|
ResolveSingletonSettingsContext(string, string, string)
The non-generic form of ResolveSettingsContext<TSettings>(string, string), for a caller that only knows the
settings type by its simple name: the one project-wide singleton asset, by the same boot-time ownership
rule — the project's own copy beats a shipped one, with no project copy the shipped copy the runtime
falls back to resolves, and only two or more project copies are reported as an ambiguity. The generic
overload delegates here, so the two cannot drift apart.
Declaration
public static SettingsAssetAuthoring.SettingsResolution ResolveSingletonSettingsContext(string settingsTypeName, string explicitSettingsAssetPath, string searchRootFolder = null)
Parameters
| Type |
Name |
Description |
| string |
settingsTypeName |
|
| string |
explicitSettingsAssetPath |
|
| string |
searchRootFolder |
|
Returns
ValidateResolution<TSettings>(SettingsResolution<TSettings>, string, SerenityCreationValidationResult)
The validation pass every by-type settings wizard runs over its own
ResolveSettingsContext<TSettings>(string, string) outcome: an ambiguity between the project's own copies is
warned about in SettingsAssetAmbiguityNotice's words and nothing else is checked, an
already-resolved asset needs no target at all, and only a run that will genuinely create a new asset has
its outputFolder shape validated.
The ambiguity finding is a WARNING, not an error: the wizard's own target gate is what blocks the run
until the author picks one of the copies. Both sentences name the asset by
Serenity.Global.Infrastructure.Editor.SerenitySingletonSettingsCatalog.AuthorFacingNameOf(System.Type), so the folder rejection and the
ambiguity never call the same asset two different things.
Declaration
public static void ValidateResolution<TSettings>(SettingsAssetAuthoring.SettingsResolution<TSettings> resolution, string outputFolder, SerenityCreationValidationResult result) where TSettings : Object
Parameters
Type Parameters
| Name |
Description |
| TSettings |
|
VerifyAssetWasWrittenToDisk(string)
UnityEditor.AssetDatabase.CreateAsset(UnityEngine.Object,System.String) logs a native engine error rather than throwing when its
destination folder is valid in Unity's cache but has actually been removed from disk. This turns
that silent failure into a genuine, catchable exception so a caller's rollback triggers
deterministically instead of reporting success over a half-written project.
Declaration
public static void VerifyAssetWasWrittenToDisk(string assetPath)
Parameters
| Type |
Name |
Description |
| string |
assetPath |
|