Class PlayerInputCreator
Generates (or updates) the PlayerInput aggregate's asset chain: a UnityPlayerInputSettingsDefinition and, in Multiplayer, the three settings assets it can reference — Serenity.InputGateway.Infrastructure.Settings.UnityPlayerInputRoutingSettings, Serenity.InputGateway.Infrastructure.Settings.UnityPlayerInputJoinGateSettings, and Serenity.InputGateway.Infrastructure.Settings.UnityPlayerInputDeviceFilterSettings. This is the most complex creator in the project (four inter-referencing assets); a dedicated wizard window over this engine ships separately.
Resolution is by-Id-in-folder for all four types, mirroring
Serenity.GameMode.Installation.Editor.Builder.GameModeSettingsCreator: nothing at runtime
resolves any of these four assets by Id — UnitySerenityInstaller assigns the
UnityPlayerInputSettingsDefinition directly on the composition root, and the Definition in
turn either carries a direct routing reference or the installer falls back to an
Addressables-label lookup (see below) — so more than one instance of any of the four types can
legitimately exist per project (e.g. per build configuration), exactly like Logging's profiles.
The routing fallback is NOT null-tolerant end to end — verified by reading both call sites.
UnityPlayerInputInstaller.InstallInputRoutingSettingsFromDefinition uses the Definition's
own routing field when assigned; otherwise it calls
UnityAssetUtils.LoadAllFromAnyBlocking<UnityPlayerInputRoutingSettings> over the
PLAYER_INPUT label and takes the first match. If THAT also finds nothing, the
resolved routing stays null, and Install() unconditionally calls
InstallUiInputRouter → UnityPlayerInputUiInputRouterFactory.Create →
UiInputRouterFactoryInput.EnsureValid(), which throws ArgumentNullException when
RoutingSettings is null — a hard boot crash, not a graceful degrade. This is why every asset this
creator produces is retagged with PLAYER_INPUT (not just for inventory
consistency, unlike GameMode's settings — here the label is load-bearing for the fallback), and why
SinglePlayer — which deliberately leaves the Definition's routing
reference untouched — validates (warns, never blocks) whether a labeled
Serenity.InputGateway.Infrastructure.Settings.UnityPlayerInputRoutingSettings already exists anywhere the fallback could find it. By
contrast, InstallJoinBehavior and UnityPrimaryInputGate.IsDeviceAllowedForPrimary both
null-check routing and degrade gracefully (join disabled, any device allowed as primary) — only the UI
router path is a hard crash.
Player Prefab is authored as a UnityEngine.GameObject, not the strongly-typed
UnityEngine.InputSystem.PlayerInput field the Definition actually stores. A designer drags a prefab asset; this
engine resolves its UnityEngine.InputSystem.PlayerInput component (mirroring
UnityPlayerInputInstaller.InstallJoinBehavior's own GetComponent<PlayerInput>() check)
and warns — never blocks, matching the installer's own severity — when the prefab has none.
onPrimaryJoinTask is a plain reference, not authored. It is a UnityReflectionCallTaskDefinition — a generic reflection-call task asset with its own authoring surface entirely out of scope here; this engine only assigns whatever reference is handed to it (or preserves the existing one on update), the same way it treats InputAsset.
A wizard window collecting input and rendering results ships in a separate change; every asset mutation lives here.
Inherited Members
Namespace: Serenity.InputGateway.Installation.Editor.Builder
Assembly: Serenity.UnityPlayerInput.Installation.Editor.dll
Syntax
public static class PlayerInputCreator
Methods
Create(Input)
Validates the request, then — in Multiplayer — resolves-or-creates the Device Filter and Join Gate bottom-up, then Routing (wiring both), then always resolves-or-creates the Definition (wiring Routing only in Multiplayer mode; SinglePlayer never touches the Definition's Routing reference, whether creating new — where it stays null — or updating — where whatever is already there is preserved). On any failure every mutation across every touched asset is rolled back: created assets/folders are deleted, their Addressables entries removed, and any already-existing asset that was being edited has its pre-call field values restored.
Declaration
public static PlayerInputCreator.Result Create(PlayerInputCreator.Input input)
Parameters
| Type | Name | Description |
|---|---|---|
| PlayerInputCreator.Input | input |
Returns
| Type | Description |
|---|---|
| PlayerInputCreator.Result |
Validate(Input)
Validates the request: a non-empty Id, a well-formed output folder, every timing throw UnityPlayerInputInstaller.ValidateSettings would raise, a required Input Asset (the installer throws when it is null), the UI Action Map name resolving against it (an error — see Serenity.InputGateway.Installation.Editor.Builder.PlayerInputCreator.ValidateActionNames(Serenity.InputGateway.Installation.Editor.Builder.PlayerInputCreator.Input,Serenity.Global.Infrastructure.Editor.SerenityCreationValidationResult)), the Navigate/Submit/Cancel action names resolving within that map (warnings), the Player Prefab carrying a UnityEngine.InputSystem.PlayerInput component when assigned (a warning, mirroring the installer's own severity), and the same resolve-or-edit duplicate-Id/unlink warnings Create(Input) would act on — including, in SinglePlayer, whether the installer's Routing label fallback has anything to find at all.
Declaration
public static SerenityCreationValidationResult Validate(PlayerInputCreator.Input input)
Parameters
| Type | Name | Description |
|---|---|---|
| PlayerInputCreator.Input | input |
Returns
| Type | Description |
|---|---|
| SerenityCreationValidationResult |