Class ControlSchemeManager
Concrete implementation of IControlSchemeManager that manages a registry of ControlScheme instances and automatically switches between them based on detected input device activity.
Implements
Inherited Members
Namespace: Scylla.Input
Assembly: ScyllaInput.dll
Syntax
public class ControlSchemeManager : IControlSchemeManager
Remarks
On initialization the manager registers two built-in schemes produced by CreateDefaultKeyboardMouse() and CreateDefaultGamepad(). The initial active scheme is determined by querying IsGamepadConnected(): if a gamepad is connected, the gamepad scheme is activated; otherwise the keyboard/mouse scheme is used.
Auto-detection: When AutoDetectionEnabled is true,
Update() is called once per frame by the owning module. Each call
polls for significant gamepad axis/button input and keyboard/mouse input through
the IInputBridgeManager. The detection priority is gamepad first:
if any stick axis exceeds GamepadStickThreshold (squared),
any trigger exceeds GamepadTriggerThreshold, or any common button
was pressed this frame, the manager switches to the gamepad scheme. Otherwise, if
any key was pressed, the mouse moved more than MouseDeltaThreshold
pixels, any of the three primary mouse buttons was pressed, or the scroll wheel
moved, the manager switches to the keyboard/mouse scheme. Switching is guarded by
SwitchCooldown measured against
Time.realtimeSinceStartupAsDouble and is therefore unaffected by game pause.
Gamepad type detection: Whenever the active scheme switches to a
Gamepad scheme, or when a gamepad connects,
Scylla.Input.ControlSchemeManager.DetectGamepadType() inspects the Unity Input System device's
displayName and layout strings for known substrings to classify
the controller as Xbox, PlayStation, Nintendo, Steam, or Generic. A change in
detected type fires OnGamepadTypeChanged.
Every scheme switch fires OnSchemeChanged and publishes a ControlSchemeChangedEvent through the Scylla Event eXchange System.
Properties
ActiveScheme
Gets the currently active control scheme, or null if no scheme is active.
Declaration
public ControlScheme ActiveScheme { get; }
Property Value
| Type | Description |
|---|---|
| ControlScheme | The ControlScheme that was last set via auto-detection or an explicit
call to SetActiveScheme(string) / SetActiveScheme(ControlSchemeType).
Returns |
ActiveSchemeType
Gets the ControlSchemeType of the currently active scheme.
Declaration
public ControlSchemeType ActiveSchemeType { get; }
Property Value
| Type | Description |
|---|---|
| ControlSchemeType | The type category of the active scheme. Returns Unknown
when ActiveScheme is |
AutoDetectionEnabled
Gets or sets a value indicating whether the manager should automatically switch the active scheme based on recent input device activity each time Update() is called.
Declaration
public bool AutoDetectionEnabled { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
|
Remarks
When enabled, Update() polls the IInputBridgeManager for gamepad axis/button activity and keyboard/mouse activity each frame. The scheme only switches if the detected input type differs from the currently active type and the SwitchCooldown period has elapsed since the last switch.
DetectedGamepadType
Gets the manufacturer/platform type of the gamepad that was most recently identified by the auto-detection system.
Declaration
public GamepadType DetectedGamepadType { get; }
Property Value
| Type | Description |
|---|---|
| GamepadType | A GamepadType value indicating whether the connected gamepad is an Xbox, PlayStation, Nintendo, Steam, or Generic controller. The value is updated whenever the active scheme switches to a Gamepad scheme or whenever the underlying gamepad device changes. Returns Generic when no gamepad is connected. |
See Also
GamepadStickThreshold
Gets or sets the minimum stick axis magnitude required to register gamepad stick movement as significant input during auto-detection.
Declaration
public float GamepadStickThreshold { get; set; }
Property Value
| Type | Description |
|---|---|
| float | A value in the range [0, 1], clamped automatically. Defaults to |
Remarks
Increasing this threshold makes the auto-detection less sensitive to analog stick drift and minor controller vibration, at the cost of requiring more deliberate stick movement to trigger a scheme switch.
GamepadTriggerThreshold
Gets or sets the minimum analog value required on either gamepad trigger to register trigger input as significant during auto-detection.
Declaration
public float GamepadTriggerThreshold { get; set; }
Property Value
| Type | Description |
|---|---|
| float | A value in the range [0, 1], clamped automatically. Defaults to |
IsInitialized
Gets a value indicating whether Initialize(IInputBridgeManager) has been called and the manager is ready to process input.
Declaration
public bool IsInitialized { get; }
Property Value
| Type | Description |
|---|---|
| bool |
|
MouseDeltaThreshold
Gets or sets the minimum mouse movement delta magnitude (in pixels) required to register mouse movement as significant input during auto-detection.
Declaration
public float MouseDeltaThreshold { get; set; }
Property Value
| Type | Description |
|---|---|
| float | A non-negative pixel delta. Values below zero are silently raised to zero.
Defaults to |
Remarks
Small mouse deltas caused by optical sensor noise or minor accidental movement can be filtered out by raising this value. Lowering it makes the auto-detection more responsive to subtle mouse movement.
SwitchCooldown
Gets or sets the minimum number of seconds that must elapse between automatic scheme switches.
Declaration
public float SwitchCooldown { get; set; }
Property Value
| Type | Description |
|---|---|
| float | A non-negative number of seconds. The value is clamped to zero from below; negative
values are silently raised to zero. Defaults to |
Remarks
This cooldown prevents rapid scheme toggling that can occur when the player uses
both a gamepad and a keyboard simultaneously (for example, when glancing at a
keyboard shortcut while holding a gamepad). The clock is measured against
Time.realtimeSinceStartupAsDouble and is unaffected by game pause or
time scale.
Methods
GetAllSchemes()
Returns a read-only view of all currently registered control schemes in registration order.
Declaration
public IReadOnlyList<ControlScheme> GetAllSchemes()
Returns
| Type | Description |
|---|---|
| IReadOnlyList<ControlScheme> | A IReadOnlyList<T> of ControlScheme instances. The list is empty before Initialize(IInputBridgeManager) is called or if all schemes have been unregistered. |
GetScheme(string)
Returns the registered ControlScheme with the specified ID.
Declaration
public ControlScheme GetScheme(string schemeID)
Parameters
| Type | Name | Description |
|---|---|---|
| string | schemeID | The SchemeID to look up. Null or empty values always
return |
Returns
| Type | Description |
|---|---|
| ControlScheme | The matching ControlScheme, or |
GetSchemeByType(ControlSchemeType)
Returns the first registered ControlScheme whose
SchemeType matches schemeType.
Declaration
public ControlScheme GetSchemeByType(ControlSchemeType schemeType)
Parameters
| Type | Name | Description |
|---|---|---|
| ControlSchemeType | schemeType | The ControlSchemeType to look up. |
Returns
| Type | Description |
|---|---|
| ControlScheme | The primary ControlScheme for that type, or |
Remarks
Only the scheme that was registered first for a given type is stored in the type-keyed index. If the primary scheme is unregistered, the next scheme of the same type is promoted. Use GetScheme(string) to retrieve schemes by their exact ID when multiple schemes share a type.
HasScheme(string)
Determines whether a scheme with the specified ID is currently registered.
Declaration
public bool HasScheme(string schemeID)
Parameters
| Type | Name | Description |
|---|---|---|
| string | schemeID | The SchemeID to test. Null or empty values always
return |
Returns
| Type | Description |
|---|---|
| bool |
|
Initialize(IInputBridgeManager)
Initializes the control scheme manager with the given bridge manager and registers the built-in default keyboard/mouse and gamepad schemes.
Declaration
public void Initialize(IInputBridgeManager bridgeManager)
Parameters
| Type | Name | Description |
|---|---|---|
| IInputBridgeManager | bridgeManager | The IInputBridgeManager instance that will be queried for device
state during auto-detection and gamepad type identification. Must not be |
Remarks
After initialization, the active scheme is determined by whether a gamepad is currently connected (IsGamepadConnected()). Calling this method more than once is safe but logs a warning and returns without re-initializing.
RegisterScheme(ControlScheme)
Registers a ControlScheme with the manager so that it can be selected as the active scheme.
Declaration
public bool RegisterScheme(ControlScheme scheme)
Parameters
| Type | Name | Description |
|---|---|---|
| ControlScheme | scheme | The control scheme to register. Must not be |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
For each ControlSchemeType, only the first registered scheme of that type becomes the primary lookup target for GetSchemeByType(ControlSchemeType) and SetActiveScheme(ControlSchemeType). Subsequent schemes of the same type are registered by ID only and can be activated via SetActiveScheme(string).
SetActiveScheme(ControlSchemeType)
Manually activates the first registered ControlScheme whose type
matches schemeType, bypassing auto-detection cooldown and thresholds.
Declaration
public bool SetActiveScheme(ControlSchemeType schemeType)
Parameters
| Type | Name | Description |
|---|---|---|
| ControlSchemeType | schemeType | The ControlSchemeType of the scheme to activate. |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
This overload selects the type-keyed primary scheme (the first scheme of that type that was registered). If the target scheme is already active, no events are fired. On a successful switch, OnSchemeChanged is raised and a ControlSchemeChangedEvent is published via the Scylla Event eXchange System.
SetActiveScheme(string)
Manually activates the registered ControlScheme with the given ID, bypassing auto-detection cooldown and thresholds.
Declaration
public bool SetActiveScheme(string schemeID)
Parameters
| Type | Name | Description |
|---|---|---|
| string | schemeID | The SchemeID of the scheme to activate. |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
If the requested scheme is already the active scheme, no events are fired and the
method still returns true. On a successful switch, OnSchemeChanged
is raised and a ControlSchemeChangedEvent is published via the
Scylla Event eXchange System.
Shutdown()
Shuts down the control scheme manager, clears all registered schemes, and releases the reference to the IInputBridgeManager.
Declaration
public void Shutdown()
Remarks
After shutdown, IsInitialized returns false and
ActiveScheme is null. Calling Update() after
shutdown is safe and has no effect. The manager can be re-initialized by calling
Initialize(IInputBridgeManager) again.
UnregisterScheme(string)
Removes a previously registered ControlScheme from the manager.
Declaration
public bool UnregisterScheme(string schemeID)
Parameters
| Type | Name | Description |
|---|---|---|
| string | schemeID | The SchemeID of the scheme to remove. Null or empty
values are treated as not found and return |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
If the unregistered scheme was the primary type-keyed entry for its
ControlSchemeType, the manager promotes the next registered scheme
of the same type to the primary slot. If the unregistered scheme was the active
scheme, the manager falls back to the first remaining scheme in registration order,
or sets ActiveScheme to null if no schemes remain.
Update()
Polls for input device activity and switches the active control scheme if a change is detected. Should be called once per frame from the owning module's update loop.
Declaration
public void Update()
Remarks
This method is a no-op when IsInitialized is false or when
AutoDetectionEnabled is false. The scheme switch is subject
to the SwitchCooldown guard and the analog input thresholds defined
by GamepadStickThreshold, GamepadTriggerThreshold, and
MouseDeltaThreshold.
Events
OnGamepadTypeChanged
Occurs when the manager identifies a change in the connected gamepad's manufacturer or platform type.
Declaration
public event Action<GamepadType> OnGamepadTypeChanged
Event Type
| Type | Description |
|---|---|
| Action<GamepadType> |
Remarks
This event fires when DetectedGamepadType changes - for example, when the player unplugs an Xbox controller and connects a PlayStation controller, or when a gamepad is first connected after startup. The argument is the newly detected GamepadType. Listeners can use this to update button-prompt icons without needing to observe a full scheme change.
OnSchemeChanged
Occurs when the active control scheme changes, either through auto-detection or a manual call to SetActiveScheme(string) / SetActiveScheme(ControlSchemeType).
Declaration
public event Action<ControlScheme, ControlScheme> OnSchemeChanged
Event Type
| Type | Description |
|---|---|
| Action<ControlScheme, ControlScheme> |
Remarks
The first argument is the scheme that was previously active (may be null
if no scheme was active before the switch). The second argument is the newly
active scheme. This event fires in addition to the
ControlSchemeChangedEvent published through the Scylla Event
eXchange System, allowing listeners to choose either subscription mechanism.