Class GameGraphicsSettingsCreator
Generates (or updates) the UnityGameGraphicsSettings singleton — the asset holding the three binding keys (QualityLevelKey, ScreenResolutionKey, IsFullScreenKey) and the four Default* fields.
The four Default* fields were a live, verified first-run defect — now repaired, not merely
cosmetic. The project's own UnityGameGraphicsSettingsEditor
inspector never rendered them, and — confirmed live in the open editor — the shipped
Assets/Serenity/Media/GameGraphics/GameGraphicsSettings.asset had shipped with them entirely
absent from its YAML: DefaultQualityLevel loaded null, DefaultResolutionWidth/
DefaultResolutionHeight loaded 0, DefaultIsFullScreen loaded false — and
UnityGameGraphicsService consumes every one of them unconditionally. That shipped asset has been
repaired as part of this change (its YAML now serializes all four fields with the class's intended
defaults). Every asset this wizard creates or updates writes all eight fields unconditionally (see
Serenity.Global.Infrastructure.Editor.SerenityWizardScratchDraft`1.CopyOnto(`0,`0), the single write path both Create(Input)
and CreateFromDraft(UnityGameGraphicsSettings, Input) now funnel through) precisely so a wizard-touched asset can never carry
this gap again. This is the first dedicated creation wizard for the GameGraphics aggregate.
Resolution mirrors Serenity.Logging.Infrastructure.Editor.Builder.LoggingProfileCreator's
two sink settings, not its UnityLogProfile. Verified by reading both
Install(GameGraphicsInstallerInstallInput) and
Serenity.Installation.UnitySerenityInstaller.InstallGameGraphics: the installer only ever
receives a base GameGraphicsInstallerInstallInput from the composition root — never the Unity
subclass carrying a direct UnityGameGraphicsSettings reference — so the is branch in
Install that would honor a direct assignment is dead in production today, even though
UnitySerenityInstaller exposes a GameGraphicsSettings field. Resolution therefore falls
through unconditionally to UnityAssetUtils.LoadAllFromAnyBlocking<UnityGameGraphicsSettings>
over the GAME_GRAPHICS label, taking the first match — a project-wide
singleton exactly like Logging's two sinks, so ambiguity (more than one existing asset) is a warning,
never an error, resolved through the same shared SettingsAssetAuthoring engine. This is a
real, verified gap in UnitySerenityInstaller (the field is unreachable dead wiring) — reported
here, not fixed, per this change's scope.
The three binding keys are plain strings, not object references — they must equal the
IFoundationSettings.Id of a UnityGraphicGameSettingsDefinition the
GameSettings module discovers via the GAME_SETTINGS label
(UnityGameSettingsInstaller.Install loads every UnityGameSettingsDefinition — the base
type, so a UnityGraphicGameSettingsDefinition instance qualifies — tagged that label; it silently
no-ops, rather than throwing, when none are found). UnityGameSettingsService keys its runtime
lookup with a plain Dictionary<string, GameSettingsEntity> — the default (ordinal,
case-sensitive) comparer — so key resolution below matches Ids ordinally, not case-insensitively.
Only QualityLevel's key is validated as an error (mirroring
UnityGameGraphicsInstaller's own
ValidateSettings, which throws on an empty/null QualityLevelKey and nothing else); an
unresolved or empty key for any of the three is a warning, since the installer does not validate that a
key actually resolves to an existing definition at all — only that QualityLevelKey is non-empty.
"Create missing definition" only ever creates, never duplicates. Per key, when the flag is set
and no existing UnityGraphicGameSettingsDefinition resolves that Id anywhere in the
project, this run authors one directly (constructing the type is safe from an isolated editor assembly
— unlike the GameSettings module's own generic GameSettingCreator, which folds into
Serenity.UnityGlobal.Infrastructure.Editor and is built for authoring an arbitrary
UnityGameSettingsDefinition of a caller-chosen Type one at a time — a shape this
wizard's three-keys-in-one-run authoring does not fit), labeled GAME_SETTINGS
so the GameSettings module actually discovers it. When a matching definition already exists, the flag
is a documented no-op (see Serenity.GameGraphics.Installation.Settings.Editor.Builder.GameGraphicsSettingsCreator.ValidateKeyResolution(Serenity.GameGraphics.Installation.Settings.Editor.Builder.GameGraphicsSettingsCreator.KeyBindingInput,System.String,Serenity.GameGraphics.Installation.Settings.Editor.Builder.GameGraphicsSettingsCreator.Input,Serenity.Global.Infrastructure.Editor.SerenityCreationValidationResult)) — this wizard never creates a
second definition sharing an Id.
Inherited Members
Namespace: Serenity.GameGraphics.Installation.Settings.Editor.Builder
Assembly: Serenity.UnityGraphicsSettings.Installation.Editor.dll
Syntax
public static class GameGraphicsSettingsCreator
Fields
DefaultOutputFolder
Folder a brand-new settings asset is created under when the caller names none.
Declaration
public const string DefaultOutputFolder = "Assets/Game/Media/GameGraphics"
Field Value
| Type | Description |
|---|---|
| string |
SettingsAssetFileNameFallback
Fallback file name for the settings asset when Id sanitizes to nothing usable — passed to FileNameSafe(string, string) alongside CreateGameGraphicsSettingsWindow's own Summary-step path preview, so both compute the exact same planned file name.
Declaration
public const string SettingsAssetFileNameFallback = "GameGraphicsSettings"
Field Value
| Type | Description |
|---|---|
| string |
Methods
Create(Input)
Validates the request, then resolves-or-creates each key's backing definition (only when its "create missing" flag is set and nothing already resolves it), then resolves-or-creates the UnityGameGraphicsSettings singleton itself. On any failure every mutation is rolled back through the transaction's existing-asset restores: an already-existing settings asset has its pre-call field values restored, and created assets/folders are deleted along with their Addressables entries.
Declaration
public static GameGraphicsSettingsCreator.Result Create(GameGraphicsSettingsCreator.Input input)
Parameters
| Type | Name | Description |
|---|---|---|
| GameGraphicsSettingsCreator.Input | input |
Returns
| Type | Description |
|---|---|
| GameGraphicsSettingsCreator.Result |
CreateFromDraft(UnityGameGraphicsSettings, Input)
The single write path: resolves-or-creates each key's backing definition, then the
UnityGameGraphicsSettings singleton itself, then commits every field on
draft onto it via ResolveAndCommit<TSettings>(TSettings, string, string, string, SerenityAssetCreationTransaction)
— serialization decides what gets written, not a hand-maintained field list. That shared call is the
same one CreateFromDraft(TSettings, string, string, bool)
uses for the Ui/Menu/Modal singletons; GameGraphics cannot instantiate that engine directly because it
must move a package asset and resolve-or-create three definitions BEFORE the settings asset itself is
even resolved — steps the engine's generic shape has no room for — so this method keeps its own
transaction/move/definition orchestration and calls only the shared resolve-and-commit step in
between, instead of keeping a second copy of it. Kept for headless/test callers that only have the
flat GameGraphicsSettingsCreator.Input shape (see Create(Input)); CreateGameGraphicsSettingsWindow
itself skips that DTO entirely and calls this with its own
SerenityWizardDraftLifecycle<UnityGameGraphicsSettings>-managed draft directly.
input still carries what a draft alone cannot: the definition-creation directives
(CreateMissingDefinition and the shape of a definition to create), the
output/move paths, and RegisterAsAddressables — none of them fields
UnityGameGraphicsSettings itself owns. On any failure every mutation is rolled back
through the transaction's existing-asset restores.
Declaration
public static GameGraphicsSettingsCreator.Result CreateFromDraft(UnityGameGraphicsSettings draft, GameGraphicsSettingsCreator.Input input)
Parameters
| Type | Name | Description |
|---|---|---|
| UnityGameGraphicsSettings | draft | Every settings-asset field to write, already resolved (an already-seeded scratch
draft from an existing asset for an update-in-place run, or a freshly populated one for a create).
Its own Guid is ignored on purpose — identity is owned by
ResolveAndCommit<TSettings>(TSettings, string, string, string, SerenityAssetCreationTransaction). Its three binding-key fields are
expected to already equal |
| GameGraphicsSettingsCreator.Input | input | The definition-creation directives and paths — see the type doc above. |
Returns
| Type | Description |
|---|---|
| GameGraphicsSettingsCreator.Result |
ResolveSettingsContext(string)
Thin wrapper over the shared ResolveSettingsContext<TSettings>(string, string), exposed so CreateGameGraphicsSettingsWindow can auto-detect the project-wide singleton for its "Edit existing" field.
Declaration
public static SettingsAssetAuthoring.SettingsResolution<UnityGameGraphicsSettings> ResolveSettingsContext(string explicitSettingsAssetPath = "")
Parameters
| Type | Name | Description |
|---|---|---|
| string | explicitSettingsAssetPath |
Returns
| Type | Description |
|---|---|
| SettingsResolution<UnityGameGraphicsSettings> |
Validate(Input)
Validates the request: a well-formed output folder, a non-empty QualityLevel.Key (the only one of the three keys UnityGameGraphicsInstaller itself validates), each key's resolution against existing UnityGraphicGameSettingsDefinition Ids (warnings), and the same resolve-or-edit ambiguity Create(Input) would act on for the settings singleton.
Declaration
public static SerenityCreationValidationResult Validate(GameGraphicsSettingsCreator.Input input)
Parameters
| Type | Name | Description |
|---|---|---|
| GameGraphicsSettingsCreator.Input | input |
Returns
| Type | Description |
|---|---|
| SerenityCreationValidationResult |