09 Input – Configuration

28 min read

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

Every knob the Input module exposes lives on one ScriptableObject asset, ScyllaInputConfiguration, and every one of them can be overridden at runtime by a JSON config file without a rebuild. That is the same dual-layer model the rest of the framework uses, so the Core Configuration page covers the mechanics in full; this page stays on the Input-specific fields and the conventions that fit Input’s surface.

The settings are organized into five exported groups that map one-to-one with the runtime managers documented on the other Input pages. Control Scheme Detection carries five thresholds for the auto-detection covered in Control Schemes and Hints, and Input Buffering has three knobs for the ring buffer covered in Buffering. Binding Storage accounts for five settings on the persistence layer covered in Rebinding; Rebind Settings supplies four defaults for interactive rebinding; and Input Logging rounds it out with three per-category log toggles. Top-level fields outside the groups carry the references that cannot live in JSON: the ordered list of InputActionAssets and the five built-in InputIconSet slots (Keyboard, Xbox, PlayStation, Nintendo, Fallback).

A companion asset, ScyllaInputContextConfiguration, owns the default context set – five InputContextDefinition entries that produce Gameplay, Menu, Console, Global, and Rebinding 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.

Runtime overrides live in a JSON file under User Documents/{ProductName}/Config/. During module initialization, ApplyConfigFileOverrides reads each key the file provides and writes it into the live settings, and keys the file omits keep their asset defaults. A one-line override file is therefore perfectly normal, and it is the right layer for the late, specific requests: halving the gamepad stick deadzone for a QA pass, doubling the rebind timeout for an accessibility audit, or locking scheme detection to keyboard prompts on a setup where the auto-switch thrashes.

In the Unity Editor, Play mode works on runtime copies of both configuration assets. The module hands each one to Core’s PrepareConfiguration during initialization, which makes the copy, applies the JSON overrides to it, and registers it. Values changed at runtime and JSON overrides therefore last for the Play session only and never end up in the assets. Edits made to an asset in the Inspector during Play mode still reach the running module and are saved to the asset as usual. Builds use the assets directly.

Use this page for:

  • Creating the configuration asset and assigning it to ScyllaInput.
  • Looking up which knob controls which behavior 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 ScyllaInputContextConfiguration set.

Features

  • The action asset field is an ordered list. A new configuration arrives with Scylla Input Actions - Base, which supplies the Global map, and Scylla Input Actions - Default already in it, and a project adds its own alongside them. Every asset in the list is registered in turn. Order is precedence: a map name two assets declare resolves to whichever comes last, so a later asset in the list overrides an earlier one’s map of the same name. Listing nothing falls back to the same two.

  • 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 ordered InputActionAsset list and five icon-set slots that cannot be serialized 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.

  • Settings are read once, during module initialization. The module reads the configuration in OnInitialize, after the JSON overrides have been layered on top of the asset values, and pushes the results into the sub-managers. There is no per-frame settings sync. Apply() pushes the current values again, and the Inspector calls it for you when you edit the asset during Play mode.

  • Play mode leaves the assets alone. In the Unity Editor, the module works on runtime copies of the Input and Input Context configurations during Play mode, so runtime changes and JSON overrides do not reach the assets. ScyllaInput.Instance.Configuration and ContextConfiguration return the copies. Builds are unaffected.

  • LoadDefault() Resources fallback. When no configuration is assigned to ScyllaInput, the module loads Resources/Config/Scylla Input Configuration. The package does not ship that asset; the Input Wizard writes one there. With neither, the module runs on its built-in defaults.

  • The context configuration falls back twice. The module looks first at Resources/Config/Scylla Input Context Configuration, which is where the Input Wizard writes and where a project’s own asset belongs, then at the framework’s Resources/Input Contexts/Scylla Input Contexts - Default. A project asset always wins; a stock project gets the shipped one instead. If neither exists, the module registers the same set of contexts from code.

  • ExportToConfigFile() round-trip. The asset can export itself as a ConfigFile template 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 with ApplyConfigFileOverrides.

  • Three logging toggles. Binding changes, context changes, and scheme changes each have their own boolean, on by default. Turning one off silences that category’s routine messages; warnings and errors are always logged. Context changes log at Debug level, so they only show up when the logger includes Debug output.

  • Companion ScyllaInputContextConfiguration asset. The asset holds the project’s InputContextDefinition set and provides five defaults (Gameplay, Menu, Console, Global, Rebinding) plus a “Reset to Defaults” button. Edit, remove, or extend the definitions 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.

ConceptType / shapeNotes
ScyllaInputConfiguration[ScyllaCreateAsset] ScriptableObjectThe one asset that bundles every Input module knob. Assigned to ScyllaInput in the Inspector. Created via Assets > Create > Scylla > Input > Input Configuration.
ScyllaInputContextConfigurationsibling [ScyllaCreateAsset] ScriptableObjectHolds the InputContextDefinition set. Separate from ScyllaInputConfiguration because contexts tend to grow project-specific.
Setting groupnamed sub-section, mapped to a settings class for the three “complex” groupsFive 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 separate settings classes (BindingStorageSettings, etc.).
ConfigFileScylla Core JSON modelThe serializable 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 fallbackUser Documents -> Application -> Resources -> code defaultsThe order in which ConfigFileManager looks for an override file. Higher tiers win when present. Documented in detail in Configuration.
Asset reference fieldsInputActionAsset list + five InputIconSet slotsTop-level fields outside any group. Excluded from JSON overrides because object references cannot be serialized as JSON paths; assign in the Inspector only.
Per-build gateConfig File in DBG / Config File in PRD togglesControl whether the JSON override layer is active for this configuration in debug builds (Editor and development builds) and in production builds. Both default to on. IsConfigFileEnabledForCurrentBuild() evaluates them for the current build, and Core’s global config-file switches must also be on.

Recipes

The recipes below cover the whole configuration workflow between them, and each one works in isolation, so jump to whichever you need. The one exception is the first: 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. When nothing is assigned, the module looks for Resources/Config/Scylla Input Configuration and otherwise runs on built-in defaults with the shipped default action asset, 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 Assets: your project's assets, in order
                           (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 Input Configuration slot, and drop the asset in.

4. Enter Play mode. The console reports each registered action asset
   ("Registered InputActionAsset ...") and the module initializing. When
   the Input Action Assets list is empty, the module registers the shipped
   Base and Default assets from Resources instead, and it logs a warning
   only when it finds no action asset at all.

Factory action assets

Scylla ships a ready-made action asset per game type, so a new project starts from a set of actions that suits what it is rather than from a blank one. There are twelve: 3D Action, Party Tactics, 4X Strategy, 2D Platformer, 2D Top-Down, Puzzle, Fighting, Racing, Flight Sim, Shoot ’em Up, Adventure and Survival.

Each declares the control schemes its genre actually wants, so a strategy game is not asked to bind three keyboard movement layouts and a fighting game gets one layout per player. All of them share the same Menu map. The Console and Global maps are not in them at all, because those belong to the framework rather than to any game. Global lives in Scylla Input Actions - Base, which the configuration lists alongside whichever game asset you pick. The console’s own maps live in Scylla Input Actions - Debug Console, which the Console module includes and registers on its own.

Pick one on the Game Profile step of the Input Wizard and it is copied into your project, along with the metadata sidecar that carries the config-screen layout and the description of every action map and action. None of the twelve sits under Resources, so your build carries the asset you chose rather than all twelve. Resources instead holds two much smaller assets: Scylla Input Actions - Default, the fallback a project uses before it configures anything, and Scylla Input Actions - Base.

Register several action assets, and override a shipped map

Problem. Your game has its own actions asset, and you also want the shipped Global map. Later you want your own Global map instead, without editing an asset that came with the framework.

Solution. The Input Action Assets field on ScyllaInputConfiguration is a reorderable list. Add both assets, shared first, and the module registers them in that order during initialization. All of their maps are live together.

Input Action Assets
  0  Scylla Input Actions - Base     Global
  1  My Game Actions                 Gameplay, Menu

To override a map, declare one with the same name in the asset that comes later in the list. The last registration of a map name wins, the earlier map is unregistered, and a notice is logged naming it. Reordering the list therefore changes which one survives, which is why the list is reorderable rather than a set.

The replacement is wholesale rather than a merge. An action that only the replaced map declared stops resolving, so override a map when you mean to own all of it. To change what a key is bound to, use rebinding instead; see Rebinding.

Removing the shared asset from the list is supported and normal. It exists mostly for the Console module, which is itself optional, and the Input Wizard offers a checkbox for including it. A configuration that lists no assets at all falls back to the shipped defaults.

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 module initialization reads and applies it. Only the keys you include are overridden; everything else keeps its asset default. In Editor Play mode the overrides land on the runtime copy, so the asset keeps its own values.

{
  "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 20 the module exports; the other 16 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 internal group name.
  • Types are JSON primitives. Floats are JSON numbers, bools are JSON booleans, strings are JSON strings. Enum-shaped settings (e.g. StorageType = JSONFile or PlayerPrefs) 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 initialization 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 serialized 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 initialization 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;

/* In Editor Play mode this is the runtime copy, not the asset you assigned.
 * Compare values, not references, when checking which configuration is in use. */

/* Which action assets are loaded, in registration order? Useful in an editor
 * diagnostic window, and the order decides which map-name override wins. */
for (var i = 0; i < config.InputActionAssets.Count; i++)
{
    UnityEngine.Debug.Log($"Action asset [{i}]: {config.InputActionAssets[i]?.name}");
}

/* InputActionAsset is still there and returns the first entry, for a
 * caller that only ever expected one asset to keep using. */
UnityEngine.Debug.Log($"First 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 five default contexts – Gameplay, Menu, Console, Global, and Rebinding – as InputContextDefinition entries. Edit, remove, or add definitions in the Inspector. The “Reset to Defaults” button restores the original five.

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 five default
   InputContextDefinition entries:
     - Gameplay        (priority 0, enables the Gameplay map)
     - Menu            (priority 80, blocks lower)
     - Console         (priority 90, blocks lower)
     The first three share the conflict-exclusive tag "Mode".
     - Global          (priority 95, blocks nothing)
     - Rebinding       (priority 100, consumes all input, enables 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)
     - Conflict-Exclusive Tags
                            (optional; contexts sharing a tag are never active
                             together, so a controls screen stops reporting the
                             controls they have in common. Pick an existing tag
                             from the dropdown to avoid a typo splitting the set)
     - Enabled Action Maps  (list of map names enabled on activation)
     - Disabled Action Maps (list of map names disabled on activation.
                             "Fill from remaining maps" fills this with every
                             map the context does not enable)

4. In the Scene Hierarchy, select the ScyllaInput component and drop
   the context configuration asset into the Input Context Configuration
   slot (separate from the 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 initialization. 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.

Spell out each context’s disabled maps rather than listing only what it enables. Popping a context applies the new top context’s disabled list and then its enabled list, and never undoes what the context above it turned on, so a context that lists only its enabled maps leaks them downward: the pause menu keeps consuming arrow keys after the player resumes. The “Fill from remaining maps” button under the disabled list does this mechanically.

Conflict-exclusive tags are the one field here that does nothing at runtime. Nothing about which maps are enabled, which contexts block which, or how the stack behaves reads them. They exist for an in-game controls screen: two contexts that share a tag are understood never to be active together, so a screen built on InputRebindManager stops reporting the controls they have in common as conflicts. A game with a Jump on Space and a Handbrake on Space wants exactly this, and wants it stated once, here, rather than restated in the screen’s own code. See Declare which parts of a controls screen can never collide for the consuming side.

Tags survive the JSON round trip along with the rest of the definition. They are written as an array of strings under ConflictExclusiveTags inside each entry of the Contexts array, so a tag containing a comma is safe.

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. Every Scylla configuration asset carries two switches for this in the Metadata section of its Inspector: Config File in DBG covers the Editor and development builds, and Config File in PRD covers production builds. Both default to on. Turn off Config File in PRD on the Input Configuration asset, and on the Input Context Configuration asset if it should be locked as well. IsConfigFileEnabledForCurrentBuild() evaluates the switch that matches the current build, and the module then initializes from the asset values alone.

Editor steps:

1. Select the Input Configuration asset.

2. In the Inspector, open the Metadata section and turn off
   "Config File in PRD". Leave "Config File in DBG" on so the Editor
   and development builds keep reading the JSON file.

3. Repeat for the Input Context Configuration asset if its contexts
   should be locked too.

The same switches exist globally on the Core configuration, and a configuration’s own switch only takes effect when the global one for that build type is also on. To lock every module at once, turn off the global production switch instead. See Configuration for the global switches.

ScyllaInputConfiguration is sealed, so a gate that needs a condition other than the build type (for example, enabled for QA and disabled for certification builds) has to be expressed through those switches per build, for example by setting them from a build script.

API Sketch

What follows is the configuration asset itself, its three public settings classes, and the companion context configuration. The settings classes are declared directly in the Scylla.Input namespace.

namespace Scylla.Input
{
    [ScyllaCreateAsset("Input/Input Configuration", FileName = "Scylla Input Configuration")]
    public sealed class ScyllaInputConfiguration : ScyllaConfiguration
    {
        /* Asset references (top-level; excluded from JSON overrides). Every property here is
           read-only: the values are serialized fields edited in the Inspector, and code changes
           them through the JSON overlay or by editing the asset, not by assignment. */
        public IReadOnlyList<UnityEngine.InputSystem.InputActionAsset> InputActionAssets { get; }
        public UnityEngine.InputSystem.InputActionAsset InputActionAsset { get; }  /* first non-null
                                                                                      entry above;
                                                                                      compatibility
                                                                                      accessor */
        public InputIconSet KeyboardIconSet     { get; }
        public InputIconSet XboxIconSet         { get; }
        public InputIconSet PlayStationIconSet  { get; }
        public InputIconSet NintendoIconSet     { get; }
        public InputIconSet FallbackIconSet     { get; }

        /* Control Scheme Detection group (5 keys). */
        public bool  AutoDetectionEnabled     { get; }   /* default true */
        public float SchemeSwitchCooldown     { get; }   /* default 0.3 s, range 0.1-2.0 */
        public float GamepadStickThreshold    { get; }   /* default 0.2, range 0.05-0.5 */
        public float GamepadTriggerThreshold  { get; }   /* default 0.1, range 0.05-0.5 */
        public float MouseDeltaThreshold      { get; }   /* default 5 px, range 1-20 */

        /* Input Buffering group (3 keys). */
        public bool  BufferingEnabled         { get; }   /* default false, so buffering is off
                                                            until it is switched on */
        public float DefaultBufferWindow      { get; }   /* default 0.15 s, range 0.05-1.0 */
        public int   MaxBufferedInputs        { get; }   /* default 10, range 1-20 */

        /* Nested settings groups. The properties are read-only; the classes hold
           public serialized fields. */
        public BindingStorageSettings BindingStorage { get; }
        public RebindSettings         Rebind         { get; }
        public InputLoggingSettings   Logging        { get; }

        /* Icon set lookup by scheme or gamepad family. */
        public InputIconSet GetIconSetForGamepad(GamepadType gamepadType);
        public InputIconSet GetIconSetForScheme (ControlSchemeType schemeType,
                                                 GamepadType gamepadType = GamepadType.Generic);

        /* Push the current values into the running module again. The module reads the
         * configuration during initialization without calling this; the Inspector calls
         * it when the asset is edited during Play mode. */
        public override void Apply();

        /* Overrides of ScyllaConfiguration. */
        public override string     GetConfigFileName();
        public override int        ApplyConfigFileOverrides(ConfigFile configFile);
        public override ConfigFile ExportToConfigFile();
        public override ConfigurationValidationResult[] Validate();
        public override void       ResetToDefaults();

        /* Inherited per-build gate (Config File in DBG / PRD switches). */
        public virtual bool IsConfigFileEnabledForCurrentBuild();

        /* Resources fallback loader. */
        public static ScyllaInputConfiguration LoadDefault();
    }

    [Serializable] public class BindingStorageSettings
    {
        public BindingStorageType StorageType       = BindingStorageType.JSONFile;
        public string             JSONStorageFolder = "Scylla/Input";
        public string             DefaultProfileID  = "default";
        public bool               AutoLoadBindings  = true;
        public bool               AutoSaveBindings  = true;
    }

    [Serializable] public class RebindSettings
    {
        public float  Timeout              = 5f;                    /* range 1-30 */
        public string DefaultCancelPath    = "<Keyboard>/escape";
    }

    [Serializable] public class InputLoggingSettings
    {
        public bool LogBindingChanges = true;
        public bool LogContextChanges = true;
        public bool LogSchemeChanges  = true;
    }

    [ScyllaCreateAsset("Input/Context Configuration", FileName = "Scylla Input Context Configuration")]
    public sealed class ScyllaInputContextConfiguration : ScyllaConfiguration
    {
        public IReadOnlyList<InputContextDefinition> ContextDefinitions { get; }

        public static ScyllaInputContextConfiguration LoadDefault();
        public static List<InputContextDefinition>     CreateDefaultContextDefinitions();
        public override void ResetToDefaults();
    }
}

See the API reference for the full surface, including the constants that define the JSON key names.

Settings reference

Every knob, organized by group, with the JSON group name and the default.

Control Scheme Detection

JSON group name: Control Scheme Detection.

KeyTypeDefaultRange / accepted valuesEffect
AutoDetectionEnabledbooltruetrue or falseWhen true, the control scheme manager samples device input every frame and switches schemes automatically. When false, only programmatic switches work.
SchemeSwitchCooldownfloat0.30.1 to 2.0 secondsMinimum gap between auto-switches. Prevents thrashing when both devices register input in quick succession.
GamepadStickThresholdfloat0.20.05 to 0.5Minimum analog stick magnitude that counts as gamepad activity. Filters analog drift.
GamepadTriggerThresholdfloat0.10.05 to 0.5Minimum trigger pressure that counts as gamepad activity. Filters resting-finger contact.
MouseDeltaThresholdfloat51 to 20 pixelsMinimum mouse movement per frame that counts as keyboard/mouse activity. Filters optical sensor noise.

Input Buffering

JSON group name: Input Buffering.

KeyTypeDefaultRange / accepted valuesEffect
BufferingEnabledboolfalsetrue or falseWhen true, action presses recorded via BufferAction are queued in the ring buffer. When false, all buffer operations are no-ops.
DefaultBufferWindowfloat0.150.05 to 1.0 secondsDefault age limit for buffered entries. Overridden per-action via SetActionBufferWindow.
MaxBufferedInputsint101 to 20Ring 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 BindingStorageSettings class.

KeyTypeDefaultAccepted valuesEffect
StorageTypeenumJSONFileJSONFile, PlayerPrefsSelects the active IBindingStorage backend. JSON writes files under JSONStorageFolder; PlayerPrefs uses Unity’s registry.
JSONStorageFolderstringScylla/InputAny non-empty relative pathSubdirectory under Application.persistentDataPath where binding JSON files are written. Only used when StorageType = JSONFile.
DefaultProfileIDstringdefaultAny non-empty stringProfile ID used as the implicit target for SaveBindings / LoadBindings when none is specified.
AutoLoadBindingsbooltruetrue or falseWhen true, the default profile is loaded automatically during module initialization.
AutoSaveBindingsbooltruetrue or falseWhen true, bindings are saved automatically after every successful rebind operation.

Rebind Settings

JSON group name: Rebind Settings. Settings live on the RebindSettings class.

KeyTypeDefaultRange / accepted valuesEffect
Timeoutfloat51 to 30 secondsMaximum seconds a rebind operation waits for input before auto-canceling. A JSON value outside the range is clamped into it, so a configured rebind always times out.
DefaultCancelPathstring<Keyboard>/escapeAny Input System path or emptyControl path that immediately cancels an active rebind. An empty string disables the cancel path (timeout only). Applies to Unity’s interactive rebind; the keyboard and mouse-delta polling modes always cancel on Escape.

A rebind never captures the mouse position or mouse movement, so moving the mouse toward a “Press a key” prompt does not become the new binding. This needs no setting. A binding that expects mouse movement, such as a camera look binding, is still captured when the player moves the mouse.

Input Logging

JSON group name: Input Logging. Settings live on the InputLoggingSettings class.

KeyTypeDefaultEffect
LogBindingChangesbooltrueLogs rebinds and binding overrides that are applied, cleared, reset, loaded, saved, imported or deleted.
LogContextChangesbooltrueLogs context stack changes: push, pop, remove and clear, at Debug level.
LogSchemeChangesbooltrueLogs control scheme switches and changes of the detected gamepad type.

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 and the asset’s per-build config-file switches.
  • 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.
  • Start from a profile or from the defaults. The Input Wizard writes a configuration tuned for the chosen game profile, and a configuration created from the Create menu starts at the defaults documented on this page. 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 AutoLoadBindings and AutoSaveBindings on 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.
  • Control Input log volume with the logging toggles. Turn off the categories a shipping build does not need. Routine context changes log at Debug level, so a build whose logger leaves out Debug output stays quiet about them even with the toggle on.
  • Choose BindingStorage.StorageType per platform. Default JSONFile for desktop (modding-friendly, easy for support), PlayerPrefs for 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 BufferingEnabled as 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.
  • Use the per-build switches for “JSON overrides only in development”. Turn off Config File in PRD on the asset. ScyllaInputConfiguration is sealed, so subclassing is not an option.

Pitfalls