The ScyllaInputConfiguration ScriptableObject and its companion JSON config file let you tune every Input module knob without a rebuild, from scheme-detection thresholds to rebind timeouts to binding storage backends.
Summary
This page documents ScyllaInputConfiguration, the ScriptableObject asset that holds every knob the Input module exposes, plus the JSON config file that lets you override those knobs at runtime without a rebuild. It is the same dual-layer model the rest of the framework uses – the Core Configuration page covers the mechanics in full; this page focuses on the Input-specific fields and the conventions that fit Input’s surface.
The settings are organised into five exported groups that map one-to-one with the runtime managers documented on the other Input pages: Control Scheme Detection (five thresholds for the auto-detection covered in Control Schemes and Hints), Input Buffering (three knobs for the ring buffer covered in Buffering), Binding Storage (five settings for the persistence layer covered in Rebinding), Rebind Settings (four defaults for interactive rebinding), and Input Logging (three per-category log toggles). Top-level fields outside the groups carry the references that cannot live in JSON: the InputActionAsset and the five built-in InputIconSet slots (Keyboard, Xbox, PlayStation, Nintendo, Fallback).
A companion asset, ScyllaInputContextConfiguration, owns the default context set – six InputContextDefinition entries that produce Gameplay, Free Camera, Strategy Camera, Menu, Console, and Global contexts on first load. It is a separate asset rather than a section of ScyllaInputConfiguration because the context set tends to grow project-specific and benefits from its own data model and its own “Reset to Defaults” affordance. You assign both assets to the ScyllaInput component independently.
There is always a moment in QA when a tester wants to retry a level with the gamepad stick deadzone halved, or an accessibility audit asks for the rebind timeout doubled to ten seconds, or a streamer reports that the auto-scheme-detection thrashes on their setup and asks you to lock it to keyboard prompts. The dual-layer model exists for those cases: you or a tester drop a JSON file under User Documents/{ProductName}/Config/ and the module’s ApplyConfigFileOverrides reads each key the file provides and writes it into the live settings. Keys the file omits keep their asset defaults, so a one-line override file is the right shape for “I only want to change the rebind timeout”.
Use this page for:
- Creating the configuration asset and assigning it to
ScyllaInput. - Looking up which knob controls which behaviour and what its default is.
- Authoring a JSON override file for a player, a tester, or a per-build environment.
- Switching binding storage backends from the Inspector (JSON file vs PlayerPrefs).
- Tuning auto-detection thresholds without code edits.
- Disabling per-category log noise for production builds.
- Authoring the project’s
ScyllaInputContextConfigurationset.
Features
- Five exported setting groups plus top-level references. Five grouped sections cover the runtime knobs (Control Scheme Detection, Input Buffering, Binding Storage, Rebind Settings, Input Logging). Top-level fields carry the
InputActionAssetreference and five icon-set slots that cannot be serialised as JSON paths. - JSON config file overlay. Every numeric, boolean, and string knob can be overridden at runtime via the Scylla config file system. Asset references are excluded from JSON overrides; their slots are filled at editor time on the asset itself.
Apply()runs during module initialization. The module reads the assigned configuration duringInitialize; the JSON overrides are layered on top of the asset values and the resulting settings are pushed into the sub-managers. There is no per-frame settings sync; tuning live requires re-applying.LoadDefault()Resources fallback. When no configuration is assigned toScyllaInput, the module loadsResources/Configurations/Scylla Input Configuration(and a sibling Resources path for the context configuration). The shipped framework asset becomes the default until you supply your own.ExportToConfigFile()round-trip. The asset can export itself as aConfigFiletemplate for players or server operators to edit. The Inspector “Export Config File” button drops the JSON on disk in the canonical four-tier path. Round-trips cleanly withApplyConfigFileOverrides.- Three logging toggle pairs. Binding changes, context changes, and scheme changes each have their own boolean. Default is on for all three, which is helpful in development; turn them off individually for shipping builds where log volume matters.
- Companion
ScyllaInputContextConfigurationasset. Holds the project’sInputContextDefinitionset. Ships with six defaults (Gameplay, Free Camera, Strategy Camera, Menu, Console, Global) and a “Reset to Defaults” button. Edit, remove, or extend per project. - Four-tier fallback per the Core configuration model. User Documents -> Application -> Resources -> compiled defaults. The Input module does not add or remove tiers; see Configuration for the full mechanics.
Concepts
The vocabulary used through the page. The Core Configuration page covers the dual-layer mechanics in full; this table is the Input-specific subset.
| Concept | Type / shape | Notes |
|---|---|---|
ScyllaInputConfiguration | [CreateAssetMenu] ScriptableObject | The one asset that bundles every Input module knob. Assigned to ScyllaInput in the Inspector. Created via Assets > Create > Scylla > Input > Input Configuration. |
ScyllaInputContextConfiguration | sibling [CreateAssetMenu] ScriptableObject | Holds the InputContextDefinition set. Separate from ScyllaInputConfiguration because contexts tend to grow project-specific. |
| Setting group | named sub-section, mapped to a nested class for the three “complex” groups | Five groups are exported to JSON: Control Scheme Detection, Input Buffering, Binding Storage, Rebind Settings, Input Logging. The first two are flat fields on the root asset; the last three live on nested classes (BindingStorageSettings, etc.). |
ConfigFile | Scylla Core JSON model | The serialisable shape the JSON override file uses. Each group is a JSON object; each key is a tuning knob. TryGetInt/TryGetFloat/TryGetBool/TryGetString read individual keys with defaults preserved when absent. |
| Four-tier fallback | User Documents -> Application -> Resources -> code defaults | The order in which ConfigFileManager looks for an override file. Higher tiers win when present. Documented in detail in Configuration. |
| Asset reference fields | InputActionAsset + five InputIconSet slots | Top-level fields outside any group. Excluded from JSON overrides because object references cannot be serialised as JSON paths; assign in the Inspector only. |
| Per-build gate | IsConfigFileEnabledForCurrentBuild() override | Controls whether the JSON override layer is active for a given build target. Defaults to always enabled; override on a configuration subclass to restrict to specific build types (e.g. only development builds). |
Recipes
These recipes cover the full configuration workflow. Each one is self-contained – jump to the one you need. The first recipe, creating and assigning the asset, is the setup step every other recipe assumes is already done.
Create the asset and assign it to ScyllaInput
Problem. You need the module to find a configuration on startup. The framework ships a default asset under Resources/Configurations/Scylla Input Configuration that the module loads when no explicit assignment exists, so a fresh project works without any configuration ceremony. But the moment you want to supply your own InputActionAsset or tune any knob, you need a project-specific asset assigned in the Inspector.
Solution. Create the asset once at project setup time, fill in the asset-reference fields, and drop it into the ScyllaInput component.
Editor steps:
1. Right-click in the Project window:
Create > Scylla > Input > Input Configuration
Save the asset as Assets/Game/Configs/Input Configuration.asset (or
wherever your project keeps configurations).
2. With the asset selected, fill in the top-level reference fields:
- Input Action Asset: your project's primary InputActionAsset
(e.g. Assets/Game/Input/GameInputActions.inputactions)
- Keyboard Icon Set: your keyboard prompt sprites
- Xbox Icon Set: your Xbox prompt sprites
- PlayStation Icon Set: your PlayStation prompt sprites
- Nintendo Icon Set: optional; falls back to FallbackIconSet when null
- Fallback Icon Set: your generic gamepad prompt sprites
3. In the Scene Hierarchy, select the ScyllaBootstrap GameObject's
ScyllaInput child, find the Configuration slot, and drop the asset in.
4. Enter Play mode. The Console shows "ScyllaInputConfiguration applied"
on successful initialisation. Missing fields log as named warnings
(e.g. "Input Action Asset is null; attempting to load
Resources/Input Actions/Scylla Input Actions").
Override knobs via JSON config file
Problem. A QA tester reports the gamepad stick deadzone is too tight on their controller and wants to test with 0.05. An accessibility audit asks for a ten-second rebind timeout. A streamer wants the auto-detection cooldown extended to one second. You need all three changes testable without a rebuild and without touching the asset that everyone else is using.
Solution. Drop a JSON override file under User Documents/{ProductName}/Config/ (the platform-specific path is documented in the Core Configuration page) and the next Apply reads and applies it. Only the keys you include are overridden; everything else keeps its asset default.
{
"Control Scheme Detection": {
"GamepadStickThreshold": 0.05,
"SchemeSwitchCooldown": 1.0
},
"Rebind Settings": {
"RebindSettings": {
"Timeout": 10.0
}
},
"Input Logging": {
"InputLogging": {
"LogContextChanges": false
}
}
}
A few things worth knowing about the file format:
- Only changed keys appear. Every key the file omits keeps the asset’s default. The example above changes four settings out of the 17 the module exports; the other 13 stay at their asset values.
- Groups are JSON objects keyed by the human-readable name. Group names match the constants on
ScyllaInputConfiguration(GROUP_CONTROL_SCHEME_DETECTION,GROUP_REBIND_SETTINGS, etc.). The settings table below lists each group’s exact name. - Nested groups (Binding Storage, Rebind Settings, Input Logging) use a sub-object key. Each nested class becomes a JSON object keyed by its internal group name (e.g.
"RebindSettings","InputLogging"). The outer key is the human-readable group name; the inner key is the class name. - Types are JSON primitives. Floats are JSON numbers, bools are JSON booleans, strings are JSON strings. Enum-shaped settings (e.g.
StorageType=JSONFileorPlayerPrefs) are written as strings matching the enum value name.
You can hand-edit the file, drop it via an installer, or export it from the asset itself: select the configuration asset, click “Export Config File” in the Inspector, and the framework writes the canonical JSON to the appropriate four-tier path. Edit from there; the next module initialisation picks up the changes.
Read the InputActionAsset and icon-set fields from code
Problem. You need to inspect at runtime which action asset or icon set the module is using – perhaps to log a diagnostic, to display the icon set name in a debug overlay, or to verify that a particular icon set was registered correctly.
Solution. The five object-reference fields live at the top of the asset and never participate in JSON overrides. Unity ScriptableObject references cannot be serialised as JSON paths in a way that survives builds, so they are assigned once in the Inspector and read from code when needed. The framework reads them once during module initialisation and forwards them to the appropriate sub-managers.
/* The framework reads these during Initialize and forwards to the hints manager.
* Reading them from game code is uncommon; it is most useful for diagnostics
* and for editor tooling that needs to inspect which assets are wired up. */
var config = ScyllaInput.Instance.Configuration;
/* Which action asset is loaded? Useful in an editor diagnostic window. */
UnityEngine.Debug.Log($"Action asset: {config.InputActionAsset.name}");
/* Which icon sets were registered? The hints manager already holds these after
* Initialize, but you can inspect the configuration directly. */
UnityEngine.Debug.Log($"Keyboard icons: {config.KeyboardIconSet?.IconSetID}");
UnityEngine.Debug.Log($"Xbox icons: {config.XboxIconSet?.IconSetID}");
UnityEngine.Debug.Log($"Fallback icons: {config.FallbackIconSet?.IconSetID}");
Author the companion ScyllaInputContextConfiguration
Problem. Contexts (the LIFO stack covered in Contexts) define which action maps are active at a given moment and whether higher-priority contexts block input from lower-priority ones. You need to ship a default context set that works for your game’s structure without modifying the main ScyllaInputConfiguration asset.
Solution. The context set lives in a separate ScyllaInputContextConfiguration asset. A fresh asset created via the menu ships pre-populated with the six default contexts – Gameplay, Free Camera, Strategy Camera, Menu, Console, and Global – as InputContextDefinition entries. Edit, remove, or add definitions in the Inspector. The “Reset to Defaults” button restores the original six.
Editor steps:
1. Right-click in the Project window:
Create > Scylla > Input > Context Configuration
Save the asset as Assets/Game/Configs/Input Context Configuration.asset.
2. With the asset selected, the Inspector shows six default
InputContextDefinition entries:
- Gameplay (priority 0, exclusion group "Movement", enables Gameplay maps)
- Free Camera (priority 0, exclusion group "Movement", enables Free Camera map)
- Strategy Camera (priority 0, exclusion group "Movement", enables Strategy Camera map)
- Menu (priority 80, blocks lower)
- Console (priority 90, blocks lower)
- Global (priority 100, blocks nothing)
3. Edit, remove, or add definitions. Each definition carries:
- Context ID (the string identifier used by PushContext)
- Display Name (for debug UI)
- Priority (integer, drives the blocking decision)
- Blocks Lower Pty (boolean)
- Consumes All Input (boolean)
- Exclusion Group (optional shared string for mutually exclusive contexts)
- Enabled Action Maps (list of map names enabled on activation)
- Disabled Action Maps (list of map names disabled on activation)
4. In the Scene Hierarchy, select the ScyllaInput component and drop
the context configuration asset into the Context Configuration slot
(separate from the main Input Configuration slot).
5. Enter Play mode. The Context Manager auto-registers every definition;
PushContext("Menu") works from that point forward.
Each InputContextDefinition emits a runtime InputContext via CreateContext() during initialisation. The runtime objects are then registered with the context manager and become the targets for PushContext(string) calls. See the Contexts page for the runtime API surface.
Gate JSON overrides to development builds only
Problem. Your game is shipping to a certification or competitive environment where you cannot allow players to edit configuration files. You want JSON overrides active during development and QA but completely disabled in shipping builds.
Solution. Subclass ScyllaInputConfiguration and override IsConfigFileEnabledForCurrentBuild. The subclass becomes a new ScriptableObject type you assign to ScyllaInput in the Inspector exactly like the base type. The Apply call still runs on initialisation; the JSON layer simply does not contribute to the final values when the gate returns false.
using Scylla.Input;
using UnityEngine;
/* Project-specific subclass that gates JSON overrides to development
* builds only. Shipped builds use the asset values as the only source
* of truth; the JSON layer is not consulted. */
[CreateAssetMenu(menuName = "Game/Configs/Locked Input Configuration")]
public sealed class LockedInputConfiguration : ScyllaInputConfiguration
{
public override bool IsConfigFileEnabledForCurrentBuild()
{
#if UNITY_EDITOR || DEVELOPMENT_BUILD
return true;
#else
return false;
#endif
}
}
Projects that want a finer-grained gate (for example, enable for QA, disable for cert builds) can branch on Application.installerName, a custom scripting define, or any project-specific condition.
API Sketch
The shape of the configuration asset, the four nested settings classes, and the companion context configuration.
namespace Scylla.Input
{
[CreateAssetMenu(fileName = "Scylla Input Configuration",
menuName = "Scylla/Input/Input Configuration")]
public sealed class ScyllaInputConfiguration : ScyllaConfiguration
{
/* Asset references (top-level; excluded from JSON overrides). */
public UnityEngine.InputSystem.InputActionAsset InputActionAsset { get; set; }
public InputIconSet KeyboardIconSet { get; set; }
public InputIconSet XboxIconSet { get; set; }
public InputIconSet PlayStationIconSet { get; set; }
public InputIconSet NintendoIconSet { get; set; }
public InputIconSet FallbackIconSet { get; set; }
/* Control Scheme Detection group (5 keys). */
public bool AutoDetectionEnabled { get; set; } /* default true */
public float SchemeSwitchCooldown { get; set; } /* default 0.3 s, range 0.1-2.0 */
public float GamepadStickThreshold { get; set; } /* default 0.2, range 0.05-0.5 */
public float GamepadTriggerThreshold { get; set; } /* default 0.1, range 0.05-0.5 */
public float MouseDeltaThreshold { get; set; } /* default 5 px, range 1-20 */
/* Input Buffering group (3 keys). */
public bool BufferingEnabled { get; set; } /* default false */
public float DefaultBufferWindow { get; set; } /* default 0.15 s, range 0.05-1.0 */
public int MaxBufferedInputs { get; set; } /* default 10, range 1-20 */
/* Nested settings groups. */
public BindingStorageSettings BindingStorage { get; set; }
public RebindSettings Rebind { get; set; }
public InputLoggingSettings Logging { get; set; }
/* Apply settings to the running module (called automatically on
* Initialize; can be re-invoked at runtime after changes). */
public void Apply();
/* Inherited from ScyllaConfiguration. */
public override string GetConfigFileBaseName();
public override int ApplyConfigFileOverrides(ConfigFile configFile);
public override ConfigFile ExportToConfigFile();
public virtual bool IsConfigFileEnabledForCurrentBuild();
/* Resources fallback loader. */
public static ScyllaInputConfiguration LoadDefault();
[Serializable] public class BindingStorageSettings
{
public BindingStorageType StorageType { get; set; } /* default JSONFile */
public string JSONStorageFolder { get; set; } /* default "Scylla/Input" */
public string DefaultProfileID { get; set; } /* default "default" */
public bool AutoLoadBindings { get; set; } /* default true */
public bool AutoSaveBindings { get; set; } /* default true */
}
[Serializable] public class RebindSettings
{
public float Timeout { get; set; } /* default 5 s, range 1-30 */
public string DefaultCancelPath { get; set; } /* default "<Keyboard>/escape" */
public bool ExcludeMousePosition { get; set; } /* default true */
public bool ExcludeMouseDelta { get; set; } /* default true */
}
[Serializable] public class InputLoggingSettings
{
public bool LogBindingChanges { get; set; } /* default true */
public bool LogContextChanges { get; set; } /* default true */
public bool LogSchemeChanges { get; set; } /* default true */
}
}
[CreateAssetMenu(fileName = "Scylla Input Context Configuration",
menuName = "Scylla/Input/Context Configuration")]
public sealed class ScyllaInputContextConfiguration : ScyllaConfiguration
{
public List<InputContextDefinition> ContextDefinitions { get; set; }
public static ScyllaInputContextConfiguration LoadDefault();
public void ResetToDefaults();
}
}
See the API reference for the full surface, including the constants that define the JSON key names and the framework-internal Apply plumbing.
Settings reference
Every knob, organised by group, with the JSON group name and the default.
Control Scheme Detection
JSON group name: Control Scheme Detection.
| Key | Type | Default | Range / accepted values | Effect |
|---|---|---|---|---|
AutoDetectionEnabled | bool | true | true or false | When true, the control scheme manager samples device input every frame and switches schemes automatically. When false, only programmatic switches work. |
SchemeSwitchCooldown | float | 0.3 | 0.1 to 2.0 seconds | Minimum gap between auto-switches. Prevents thrashing when both devices register input in quick succession. |
GamepadStickThreshold | float | 0.2 | 0.05 to 0.5 | Minimum analog stick magnitude that counts as gamepad activity. Filters analog drift. |
GamepadTriggerThreshold | float | 0.1 | 0.05 to 0.5 | Minimum trigger pressure that counts as gamepad activity. Filters resting-finger contact. |
MouseDeltaThreshold | float | 5 | 1 to 20 pixels | Minimum mouse movement per frame that counts as keyboard/mouse activity. Filters optical sensor noise. |
Input Buffering
JSON group name: Input Buffering.
| Key | Type | Default | Range / accepted values | Effect |
|---|---|---|---|---|
BufferingEnabled | bool | false | true or false | When true, action presses recorded via BufferAction are queued in the ring buffer. When false, all buffer operations are no-ops. |
DefaultBufferWindow | float | 0.15 | 0.05 to 1.0 seconds | Default age limit for buffered entries. Overridden per-action via SetActionBufferWindow. |
MaxBufferedInputs | int | 10 | 1 to 20 | Ring buffer capacity. When full, the oldest entry is overwritten on the next BufferAction call. |
Binding Storage
JSON group name: Binding Storage. Settings live on the nested BindingStorageSettings class.
| Key | Type | Default | Accepted values | Effect |
|---|---|---|---|---|
StorageType | enum | JSONFile | JSONFile, PlayerPrefs | Selects the active IBindingStorage backend. JSON writes files under JSONStorageFolder; PlayerPrefs uses Unity’s registry. |
JSONStorageFolder | string | Scylla/Input | Any non-empty relative path | Subdirectory under Application.persistentDataPath where binding JSON files are written. Only used when StorageType = JSONFile. |
DefaultProfileID | string | default | Any non-empty string | Profile ID used as the implicit target for SaveBindings / LoadBindings when none is specified. |
AutoLoadBindings | bool | true | true or false | When true, the default profile is loaded automatically during module initialisation. |
AutoSaveBindings | bool | true | true or false | When true, bindings are saved automatically after every successful rebind operation. |
Rebind Settings
JSON group name: Rebind Settings. Settings live on the nested RebindSettings class.
| Key | Type | Default | Range / accepted values | Effect |
|---|---|---|---|---|
Timeout | float | 5 | 1 to 30 seconds | Maximum seconds a rebind operation waits for input before auto-cancelling. |
DefaultCancelPath | string | <Keyboard>/escape | Any Input System path or empty | Control path that immediately cancels an active rebind. An empty string disables the cancel path (timeout only). |
ExcludeMousePosition | bool | true | true or false | When true, <Mouse>/position is rejected as a rebind target so players cannot accidentally bind to cursor location. |
ExcludeMouseDelta | bool | true | true or false | When true, <Mouse>/delta is rejected so players cannot accidentally bind to mouse motion. |
Input Logging
JSON group name: Input Logging. Settings live on the nested InputLoggingSettings class.
| Key | Type | Default | Effect |
|---|---|---|---|
LogBindingChanges | bool | true | When true, logs each binding override applied, reset, loaded, or saved. Useful in development; noisy in shipped builds. |
LogContextChanges | bool | true | When true, logs every push and pop on the context stack. Useful for tracing context flow when debugging input priority issues. |
LogSchemeChanges | bool | true | When true, logs every active control scheme switch. Useful for verifying auto-detection thresholds during development. |
Best Practices
- Keep one configuration asset per project. A single shared asset is easier to maintain than per-scene variants. Per-build differences belong in the JSON override layer or in a subclass that overrides
IsConfigFileEnabledForCurrentBuild. - Author the asset early; tune via JSON. Set the asset to defaults that match your game’s general feel; let QA, accessibility, and platform-specific overrides land via the JSON file. This avoids per-build asset duplication.
- Use the framework defaults as a starting point. The default
Scylla Input Configurationasset that ships underResources/Configurationscarries the conservative values documented in this page. Copy it (or create fresh and copy the defaults) when starting a new project, then tune from there. - Export from the Inspector to seed the JSON file. Click “Export Config File” to produce a canonical JSON document that matches the current asset values; ship that file as the “if you want to override, start here” seed for player-facing tuning options.
- Keep
AutoLoadBindingsandAutoSaveBindingson by default. Manually managing save/load through code is the right shape for advanced settings UI (a confirm-changes pattern that should not auto-save mid-rebind), but most projects benefit from the default “the player rebinds; the change persists immediately” flow. - Disable the three logging toggles in shipping builds. Each is on by default for development. For cert and shipping builds, turn off the categories you do not need to investigate. Shipping titles typically keep
LogBindingChanges = true(useful for support tickets) and disable the other two. - Choose
BindingStorage.StorageTypeper platform. DefaultJSONFilefor desktop (modding-friendly, easy for support),PlayerPrefsfor mobile and console (no file-system access required, certification-friendly). A platform-specific subclass override or a JSON file shipped per build is the right shape for the switch. - Treat
BufferingEnabledas the global on/off switch. When your project uses buffering at all, leave it on and tune via per-action windows from code. When your project does not use buffering, leave it off so the buffer manager’s per-frame work is skipped. - Subclass for project-specific gates. The
IsConfigFileEnabledForCurrentBuildoverride is the cleanest path for “JSON overrides only in development”. Subclassing produces a new asset type that ships alongside the framework default without modifying the framework code.
Pitfalls
Related
- Scylla Input
- Buffering
- Rebinding
- Control Schemes and Hints
- Contexts
- Configuration
- API reference:
Scylla.Input.ScyllaInputConfiguration - API reference:
Scylla.Input.ScyllaInputContextConfiguration - API reference:
Scylla.Input.ScyllaInputConfiguration.BindingStorageSettings - API reference:
Scylla.Input.ScyllaInputConfiguration.RebindSettings - API reference:
Scylla.Input.ScyllaInputConfiguration.InputLoggingSettings