Skip to content

NEW: Support entering playmode with Domain Reload disabled ("Faster Enter Playmode")#2343

Open
K-Tone wants to merge 45 commits intodevelopfrom
anthony/faster-enter-playmode
Open

NEW: Support entering playmode with Domain Reload disabled ("Faster Enter Playmode")#2343
K-Tone wants to merge 45 commits intodevelopfrom
anthony/faster-enter-playmode

Conversation

@K-Tone
Copy link
Collaborator

@K-Tone K-Tone commented Feb 11, 2026

Description

This branch aims to enable entering the play mode with Domain Reload disabled, it's also called Faster Enter Playmode sometimes.

The change is a bit non-trivial because we seem to have quite a bunch of statics, and all of them have to be reset the right way when Domain Reload is disabled.

The branch is basically a straightforward merge of the current develop branch into Hakan's #2016 branch, which in turn is based on Tim's incredible original branch: #1915.

Testing status & QA

Barely tested at this stage of affairs, but appears to be running kinda alright on Anthony's mac locally.

Overall Product Risks

  • Complexity: High
  • Halo Effect: High

Comments to reviewers

Please describe any additional information such as what to focus on, or historical info for the reviewers.

Checklist

Before review:

  • Changelog entry added.
    • Explains the change in Changed, Fixed, Added sections.
    • For API change contains an example snippet and/or migration example.
    • JIRA ticket linked, example (case %%). If it is a private issue, just add the case ID without a link.
    • Jira port for the next release set as "Resolved".
  • Tests added/changed, if applicable.
    • Functional tests Area_CanDoX, Area_CanDoX_EvenIfYIsTheCase, Area_WhenIDoX_AndYHappens_ThisIsTheResult.
    • Performance tests.
    • Integration tests.
  • Docs for new/changed API's.
    • Xmldoc cross references are set correctly.
    • Added explanation how the API works.
    • Usage code examples added.
    • The manual is updated, if needed.

During merge:

  • Commit message for squash-merge is prefixed with one of the list:
    • NEW: ___.
    • FIX: ___.
    • DOCS: ___.
    • CHANGE: ___.
    • RELEASE: 1.1.0-preview.3.

timkeo and others added 24 commits June 14, 2024 08:09
- Rework InputSystem's Init functions to handle optional domain reloads
- Bypass InitializeInPlayer() "Reset" and "Restore" functions if DRs disabled

Only the first step to getting this working, but enables FEPM support for golden path scenarios.
- Move Reset/Restore state functionality out of InputSystem to the Test assembly (InputTestStateManager.cs)
- Refactor InputManager Init/Dispose to be cleaner and better abstracted:
    * Adds CreateAndInitialize static method
    * Replaces Destroy() with IDisposable implementation
    * InputManager creates "default" InputSettings object if none provided
    * Runtime, Settings, and Metrics fields now private
- Update InitializeInEditor() to incorporate changes
- Update and fix tests

For the most part, the logic should be mostly preserved. InitializeInEditor() has the biggest (logical)
change because Reset() (moved to Tests) contained some actual init calls that needed to be pulled out.
However, we *should* be making the same calls in the same order.

However, this change does seem to "break" some of the OnScreenTests(); they're now unstable.
This will need to be fixed in a later commit.
- Rework the class so it operates as a Singleton (basically how it's being used)
- Move actions get/set implementations from InputSystem to ProjectWideActions class
    * Combine functionality for tighter cohesion despite being an Editor
    * Update #ifefs to allow Player to access some of these members
- Call EnsureInitialized() from Editor init flows to fix the actual bug

Tested using ProjectWideActions sample and verified could move cube when domain reloads disabled.
Ran Package tests (Edit/Play/Player) to verify no (new) failures.
…ns (ISX-1842)

- Make InputSystem static fields private with read-only accessors
- Add InputSystemTestHooks.cs for "Test Hook" operations that need direct access to fields
- Factor out InputSystemObject (and related State) and rename to InputSystemStateManager
- Factor out "dirty asset tracking" functionality to a separate Utility class

Despite touching a bunch of files, this is a low-risk set of changes; functions are moved
to new files and types renamed, but no real changes to functionality.

Validated changes with Edit/Play/Player tests.
- Most ProjectWideAction changes discarded since feature was re-implemented (no longer relevant)
- Recreate InputSystem "Test Hook" for Enabling/Disabling Actions from tests
- Small fixes from unresolved conflicts or bad merges during rebase
- Various formatting changes (to be more consistant)
- Consolidate functionality into DeferBindingResolutionContext class
- Instantiate Context object as a non-static InputManager field exposed via InputManager methods
- Static field (in each class) initialized via RuntimeInitializeOnLoadMethod() hook
- This functionality is a bit clunky and should be refactored but that's out-of-scope for this work
- Add a flag to guard against re-initializing Plugins within PerformDefaultPluginInitialization()
- Refactor SteamSupport to fix Init/Shutdown flows and improve state management
- Refactor PlayerInput's static fields into a single GlobalState struct (matching other classes)
- Move EnhancedTouch static fields into Touch's GlobalState struct
- Minor refactoring of SteamSupport to improve init/cleanp-up flows (especially with tests)
…ts (ISX-1840)

- Consolidate Touchscreen's cached settings into a separate struct
- Rework NativeInputRuntime initialization to (fully) employ Singleton pattern
- Refactor Actions_CanHandleModification TestCase generator to work without Domain Reloads
- Fix Device static fields not getting reset during SimulateDomainReload()
- Rename some variables
- Add update some comments
- Other small tweaks.
# Conflicts:
#	Packages/com.unity.inputsystem/InputSystem/Actions/InputActionMap.cs
#	Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs
#	Packages/com.unity.inputsystem/InputSystem/InputAnalytics.cs
#	Packages/com.unity.inputsystem/InputSystem/InputManager.cs
#	Packages/com.unity.inputsystem/InputSystem/InputSystem.cs
#	Packages/com.unity.inputsystem/Tests/TestFixture/InputTestFixture.cs
…d from a serialisation thread and force create ScriptableObjects
@K-Tone K-Tone changed the title Anthony/faster enter playmode CHANGE: Support entering playmode with Domain Reload disabled ("Faster Enter Playmode") Feb 18, 2026
@K-Tone K-Tone requested a review from ekcoh February 18, 2026 11:20
@K-Tone
Copy link
Collaborator Author

K-Tone commented Feb 18, 2026

Hey Hakan! Here is my branch that is based on yours really, with just a few minor corrections. Let's take a look at it together and define what are the larger bits of work that are still missing.

@u-pr
Copy link
Contributor

u-pr bot commented Feb 25, 2026

Ask

can you make a new entry to the CHANGELOG.md file describing the change happened in this PR. Make sure to keep it a one-liner in style with the rest in that file.

Answer:

Based on the PR information, here is a suggested entry for the CHANGELOG.md file. Since the PR title is prefixed with CHANGE, this would typically go into the Changed section, though it can also be argued for the Added section as it introduces a new capability.

- Added support for entering Play Mode with Domain Reload disabled ("Faster Enter Playmode") by ensuring internal static state is correctly reset.

🤖 Helpful? Please react with 👍/👎 | Questions❓Please reach out in Slack #ask-u-pr

@K-Tone
Copy link
Collaborator Author

K-Tone commented Feb 25, 2026

/update_changelog

@u-pr
Copy link
Contributor

u-pr bot commented Feb 25, 2026

Changelog updates: 🔄

[2026-02-25] *

Added

  • Added support for entering Play Mode with Domain Reload disabled ("Faster Enter Playmode").

Changed

  • Refactored internal initialization and state management logic to correctly reset the system when domain reloads are bypassed.
  • Improved the handling of static fields and singleton instances to ensure robust state restoration across play mode transitions.

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

Copy link
Collaborator

@ekcoh ekcoh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking through this diff it looks very good in my opinion but it is also difficult to review due to many scattered changes. I left a few smaller comments/questions but what I would recommend as way forward:

  • Test that all our samples work as expected with CEPM on/off. Including samples changing scenes.
  • Test that some external samples, e.g. Warriors or other internal more complex QA test projects work as expected with CEPM on/off.
  • Involve integrating team packages, e.g. XR, Cinemachine to hopefully get QA perspective on this work as well from teams depending on Input System.

When we have built sufficient confidence in that this PR doesn't regress any CEPM off behaviour and support CEPM on with good quality I think this can land which will be beneficial for users suffering from domain reload overhead during their development.

/// The s_ConnectedControllers array is allocated in response to setting event handlers and
/// so it can double as our "is installed" flag.
/// </remarks>
private static bool updateHooksInstalled => s_ConnectedControllers != null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these steam-support related static also be grouped into an object, e.g. struct to reduce to a single static similar to other consolidation of static state?

@Pauliusd01 Pauliusd01 self-requested a review February 26, 2026 07:50
Copy link
Collaborator

@Pauliusd01 Pauliusd01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing a ton of errors on the OnScreenControlsSample scene (Steps: disable domain and scene reloads -> open the scene -> enter play mode -> errors)

Image

@K-Tone
Copy link
Collaborator Author

K-Tone commented Feb 27, 2026

Seeing a ton of errors on the OnScreenControlsSample scene (Steps: disable domain and scene reloads -> open the scene -> enter play mode -> errors)

Image

Awesome, thanks. Taking a look shortly

@u-pr
Copy link
Contributor

u-pr bot commented Mar 3, 2026

Test Plan

  • Test plan approved by PR author
  • Test execution in progress
  • Test execution complete
  • Ready for merge

Summary of Changes & Risk Assessment

Summary of Changes

This PR implements support for entering Play Mode with Domain Reload disabled ("Faster Enter Playmode"). It refactors InputManager and InputSystem to manage static state via InputSystemStateManager, ensuring all internal systems, device lists, and action states are correctly reset or restored when the C# domain is not reloaded by Unity.

Risk Assessment

  • High Risk Areas: Play Mode transition lifecycle, static state management across all input plugins, unmanaged memory safety (potential for leaks/corruption during manual resets).
  • Medium Risk Areas: PlayerInput and InputUser global state handling, Input Debugger state restoration, InputSettings persistence.
  • Low Risk Areas: Analytics event reporting, documentation/XML comments.

Test Scenarios

Functional Testing

  • Faster Enter Playmode Validation: Disable Domain Reload in Project Settings > Editor. Enter and exit Play Mode multiple times. Verify that no devices from the previous session persist and that Gamepad.all (and similar) return correct counts.
  • On-Screen Controls Verification: Open the OnScreenControlsSample scene. Disable Domain and Scene reloads. Enter Play Mode and verify that the reported errors in PR comments are resolved and controls function correctly.
  • Action Asset Dirty State: Modify an InputActionAsset at runtime (e.g., add a binding). Exit Play Mode and verify the asset is correctly reloaded from disk via DirtyAssetTracker.ReloadDirtyAssets.
  • State Restoration: Verify that InputSettings changes made in Edit Mode are preserved when entering Play Mode, and that temporary settings objects are correctly cleaned up.

Regression Testing

  • Standard Play Mode: Run a full battery of CoreTests_Actions and CoreTests_Devices with Domain Reload enabled to ensure no regressions in the default workflow.
  • Input Debugger Window: Open the Input Debugger. Enter/Exit Play Mode. Verify the window remains responsive and correctly "revives" and shows active devices after the transition.
  • Remoting & Test Fixtures: Run tests using InputTestFixture. Verify m_StateManager.SaveAndReset correctly isolates test state from the Editor's global input state.
🔍 Regression Deep Dive (additional risks identified)
  • Memory Leak Check: Monitor the InputManager and InputDevice counts in the Memory Profiler after 20+ Play Mode cycles with Domain Reload disabled.
  • Player Build Safety: Verify IsDomainReloadDisabledForPlayMode returns false in a Standalone build to prevent accidental state wiping during scene loads.
  • Plugin Initialization: Verify that 3rd party plugins (like Steam or HID) only initialize their hooks once, even across play mode transitions.
  • Event Discarding: Verify that input events occurring exactly during the exitEditModeTime to enterPlayModeTime window are correctly discarded by ShouldDiscardEditModeTransitionEvent.

Edge Cases

  • Null Manager in Editor: Test entering Play Mode after a manual TestHook_DestroyAndReset call to ensure InitializeInEditor handles a null s_Manager safely.
  • Empty Input Assets: Test Play Mode entry with an empty or unassigned ProjectWideActionsAsset.

💡 This test plan updates automatically when /test_plan is run on new commits. If you have any feedback, please reach out in #ai-qa


🤖 Helpful? Please react with 👍/👎 | Questions❓Please reach out in Slack #ask-u-pr

@K-Tone K-Tone changed the title CHANGE: Support entering playmode with Domain Reload disabled ("Faster Enter Playmode") NEW: Support entering playmode with Domain Reload disabled ("Faster Enter Playmode") Mar 3, 2026
@K-Tone
Copy link
Collaborator Author

K-Tone commented Mar 3, 2026

@u-pr Attached to this post you can find all the 87 issues that Unity's Project Auditor has found regarding the domain reload in this branch. Can you analyse them and see if any are still legit? I mean that some issues appear to be problems still, but the check itself is somewhat formal and doesn't appear to take into account that statics of a class can be initialised from other classes, not neccessarily from the dedicated methods of the class.
domain_reload.json

@u-pr
Copy link
Contributor

u-pr bot commented Mar 3, 2026

I cannot access the external JSON attachment directly due to tool limitations. However, I have performed a manual audit of the static fields and state management logic in the current PR diff. Based on your description of the Auditor's behavior and the patterns in the code, I've identified several areas that are likely being flagged.

Here is my analysis of which issues are likely False Positives and which ones appear to be Legitimate problems for Domain Reload.

🟢 Likely False Positives

These are fields that the Auditor probably flags because they aren't reset in a standard Initialize or OnEnable method within the same class, but they are actually correctly managed by the InputManager lifecycle.

  • Touchscreen.settings & Touchscreen.s_Settings: You are correct that these are initialized from InputManager.ApplySettings. Since ApplySettings is called every time a new InputManager is created (which happens on every Play Mode entry in this PR), these are safely reset.
  • ButtonControl.s_GlobalDefaultButtonPressPoint / s_GlobalDefaultButtonReleaseThreshold: Similar to Touchscreen, these are updated via InputManager.ApplySettings and are not "leaking" state between sessions.
  • InputControlLayout.s_DefaultVariant: This is a static readonly field. Since it's immutable and essentially a constant, it doesn't represent "state" that needs resetting.
  • NativeInputRuntime.s_Instance: While it persists across reloads, it appears to be a stateless singleton that acts as a bridge to native code. As long as it doesn't hold references to managed objects (like the InputManager), it is safe.

🔴 Legitimate Issues (Still Legit)

These fields or patterns appear to have actual issues where state will persist incorrectly or initialization will fail when Domain Reload is disabled.

  • InputSystem.s_PluginsInitialized: This is a major issue. In PerformDefaultPluginInitialization, you check this static field and return early if it's true. However, since Domain Reload is disabled, this field stays true after the first Play Mode session. When you enter Play Mode a second time, a new InputManager is created, but the plugins (Steam, UI, etc.) are skipped and never hooked to the new manager's events. This will break those plugins after the first session.
  • SteamSupport Statics: s_ConnectedControllers, s_InputDevices, etc., are only reset in Shutdown(), which is currently only called in tests (TearDown). These should be properly reset or the logic should handle the case where they persist but the InputManager is new.
  • InputRemoting Instance: If s_Remote persists across sessions, it holds a reference to the InputManager. When the manager is replaced in InitializeInEditor, the InputRemoting instance is still pointing to the old (disposed) manager.
  • InputEventListener.s_ObserverState: This static field tracks event observers. I don't see it being reset in the main InitializeInEditor path (it's only in InputTestStateManager). This will cause event listeners from previous Play sessions to persist, leading to memory leaks or multiple calls to disposed objects.

🟡 Needs Verification

  • InputActionState.s_GlobalState: It is reset via InitializeGlobalActionState (using BeforeSceneLoad). While technically correct, the Auditor might flag it because it doesn't understand the Unity lifecycle attribute. However, verify if this runs correctly when both Domain and Scene reload are disabled.

If you can provide the specific list of flagged fields (even just a few examples of the most common ones), I can give you a more targeted assessment.

🤖 Helpful? 👍/👎

// Plug-ins must only be initialized once, since many of them use static fields.
// When Domain Reloads are disabled, we must guard against this method being called a second time.
private static bool s_PluginsInitialized = false;
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This static flag will persist across Play Mode sessions when Domain Reload is disabled. This means that after the first session, PerformDefaultPluginInitialization will always return early.

Since InitializeInEditor creates a new InputManager on every entry, the plugins will never be hooked to the new manager's events, rendering them inactive in subsequent Play sessions. This should be reset to false when globalReset is true in InitializeInEditor.

🤖 Helpful? 👍/👎

@K-Tone
Copy link
Collaborator Author

K-Tone commented Mar 3, 2026

@u-pr See below all the 87 issues that Unity's Project Auditor has found regarding the domain reload in this branch. Can you analyse them and see if any are still legit? I mean that some issues are reported, but the check itself is somewhat formal and doesn't appear to take into account that statics of a class can be initialised from other classes, not necessarily from the dedicated methods of the class.

{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":207,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":248,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":290,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":332,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":459,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":377,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":503,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":418,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":544,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":146,"path":"Packages/com.unity.inputsystem/InputSystem/Actions/InputBindingComposite.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":585,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":521,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Touchscreen.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":1040,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Touchscreen.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":529,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Touchscreen.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":629,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":673,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":59,"path":"Packages/com.unity.inputsystem/InputSystem/Controls/InputProcessor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":258,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Mouse.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":293,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Mouse.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":2389,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":323,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Pen.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":178,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Pointer.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":342,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/TouchSimulation.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":222,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenControl.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":342,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenControl.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":1166,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/InputDeviceBuilder.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":1165,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/InputDeviceBuilder.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":22,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/Switch/SwitchProControllerHID.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":1348,"path":"Packages/com.unity.inputsystem/InputSystem/InputSystem.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":3384,"path":"Packages/com.unity.inputsystem/InputSystem/InputSystem.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":3385,"path":"Packages/com.unity.inputsystem/InputSystem/InputSystem.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":3364,"path":"Packages/com.unity.inputsystem/InputSystem/InputSystem.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":2864,"path":"Packages/com.unity.inputsystem/InputSystem/InputSystem.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":3056,"path":"Packages/com.unity.inputsystem/InputSystem/InputSystem.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":299,"path":"Packages/com.unity.inputsystem/InputSystem/Actions/IInputInteraction.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":109,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Joystick.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":186,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Joystick.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":185,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Joystick.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":2231,"path":"Packages/com.unity.inputsystem/InputSystem/Controls/InputControlLayout.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":2232,"path":"Packages/com.unity.inputsystem/InputSystem/Controls/InputControlLayout.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":2170,"path":"Packages/com.unity.inputsystem/InputSystem/Controls/InputControlLayout.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":381,"path":"Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":167,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Sensor.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":2340,"path":"Packages/com.unity.inputsystem/InputSystem/InputSystem.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":22,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":69,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/HID/HIDSupport.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":89,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/HID/HIDSupport.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":52,"path":"Packages/com.unity.inputsystem/InputSystem/InputManager.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":152,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":90,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepad.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":170,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/UI/TrackedDeviceRaycaster.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":34,"path":"Packages/com.unity.inputsystem/InputSystem/Events/InputEventListener.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":380,"path":"Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":291,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInputManager.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":1371,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":77,"path":"Packages/com.unity.inputsystem/InputSystem/InputUpdateType.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":78,"path":"Packages/com.unity.inputsystem/InputSystem/InputUpdateType.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":76,"path":"Packages/com.unity.inputsystem/InputSystem/InputUpdateType.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":23,"path":"Packages/com.unity.inputsystem/InputSystem/NativeInputRuntime.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":2603,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/UI/InputSystemUIInputModule.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":206,"path":"Packages/com.unity.inputsystem/InputSystem/IInputRuntime.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":205,"path":"Packages/com.unity.inputsystem/InputSystem/IInputRuntime.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":982,"path":"Packages/com.unity.inputsystem/InputSystem/Events/InputEventTrace.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":132,"path":"Packages/com.unity.inputsystem/InputSystem/State/InputStateBuffers.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":133,"path":"Packages/com.unity.inputsystem/InputSystem/State/InputStateBuffers.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":135,"path":"Packages/com.unity.inputsystem/InputSystem/State/InputStateBuffers.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":134,"path":"Packages/com.unity.inputsystem/InputSystem/State/InputStateBuffers.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":807,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":627,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":806,"path":"Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":404,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/Users/InputUser.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":402,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/XR/XRSupport.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":420,"path":"Packages/com.unity.inputsystem/InputSystem/Actions/InputActionTrace.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":2533,"path":"Packages/com.unity.inputsystem/InputSystem/Actions/InputActionRebindingExtensions.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":89,"path":"Packages/com.unity.inputsystem/InputSystem/Events/InputEventTrace.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":1926,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/Users/InputUser.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":131,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/HID/HIDSupport.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":86,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/EnhancedTouchSupport.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":87,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/EnhancedTouchSupport.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0001","category":"DomainReload","properties":["UDR0001","Unity.InputSystem"],"description":"No method with RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":88,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/EnhancedTouchSupport.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":595,"path":"Packages/com.unity.inputsystem/InputSystem/Events/InputEventTrace.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":1252,"path":"Packages/com.unity.inputsystem/InputSystem/Events/InputEventTrace.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":1316,"path":"Packages/com.unity.inputsystem/InputSystem/Events/InputEventTrace.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":208,"path":"Packages/com.unity.inputsystem/InputSystem/NativeInputRuntime.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":224,"path":"Packages/com.unity.inputsystem/InputSystem/NativeInputRuntime.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0002","category":"DomainReload","properties":["UDR0002","Unity.InputSystem.ForUI"],"description":"Static field/property is not assigned in a method with the RuntimeInitializeOnLoadMethod attribute","location":{"IsValid":true,"line":57,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs"},"severity":"Moderate"},
{"ignored":false,"descriptorId":"UDR0004","category":"DomainReload","properties":["UDR0004","Unity.InputSystem.ForUI"],"description":"Non-static method subscribed to a static event is not deregistered in an OnDisable or OnDestroy method","location":{"IsValid":true,"line":99,"path":"Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs"},"severity":"Moderate"},

@u-pr
Copy link
Contributor

u-pr bot commented Mar 3, 2026

I've analyzed the 87 issues reported by the Project Auditor in the context of this PR. Your intuition is correct: many of these are "formal" hits where the auditor's static analysis is too shallow to recognize the consolidated initialization pattern introduced in this branch.

Key Findings

  1. Centralized Reset Logic (UDR0001, UDR0002):
    The PR introduces a centralized initialization flow starting from InputSystem.RuntimeInitialize (which has the [RuntimeInitializeOnLoadMethod] attribute). This calls GlobalInitialize, which in turn triggers resets in major subsystems like InputActionState, InputUser, Touch, and PlayerInput. The auditor flags these because it expects the attribute and assignments to be directly within each class, but the logic is actually covered by the new consolidated handlers.

  2. Manager-based Event Redirection (UDR0004):
    Most system-wide events (like InputSystem.onEvent or onDeviceChange) have been changed from true static events to property wrappers that redirect to the current InputManager instance. When the manager is recreated during a simulated or real domain reload, old subscribers remain attached to the previous manager instance (which is eventually GC'd) rather than leaking into the new session. This effectively solves the "leaking handler" problem that UDR0004 targets, even if the auditor doesn't "see" the unsubscription logic.

  3. Specific Legitimate Concerns:
    While most are false positives, a few static fields in specialized classes might still be "legit" if they aren't part of the InputManager state or the consolidated resets. For example:

    • Touchscreen.current: The PR adds Touchscreen.settings but I don't see an explicit reset for the current static property in the centralized InitializeGlobalTouchState. If Touchscreen.current persists across a "Fast Play Mode" entry, it could point to a destroyed object.
    • Device-specific statics: Classes like Sensor, Mouse, or Keyboard often have a static current or all property. While InputManager attempts to re-sync devices, ensuring these are explicitly nulled out in their respective domains during reset would be safer.

Recommendation

Most of these hits can be safely ignored as "formal" issues. However, it might be worth adding explicit nullification for the current properties of major device types in the centralized GlobalInitialize or their respective InitializeGlobal... methods to be 100% sure they don't leak stale references.

🤖 Helpful? 👍/👎

internal static InputManager s_Manager;
internal static InputRemoting s_Remote;
internal static InputManager manager => s_Manager;
private static InputManager s_Manager;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The auditor flags this as not assigned in a RuntimeInitializeOnLoadMethod. While it is assigned via the GlobalInitialize call chain, the auditor fails to follow the nested calls. This is a false positive.

🤖 Helpful? 👍/👎

@@ -520,6 +520,14 @@ protected TouchControl[] touchControlArray
/// <value>Current touch screen.</value>
public new static Touchscreen current { get; internal set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Touchscreen.current is a static property, it should ideally be reset to null during domain reload to avoid leaking references from a previous session, especially when Domain Reload is disabled. Consider adding current = null; to an initialization method.

🤖 Helpful? 👍/👎

internal static GlobalState s_GlobalState;

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void InitializeGlobalActionState()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This centralized reset is exactly what is needed for Domain Reload safety. The auditor may still flag fields within InputActionState as UDR0002 if it doesn't recognize that ResetGlobals() is called from an attributed method.

🤖 Helpful? 👍/👎

@K-Tone
Copy link
Collaborator Author

K-Tone commented Mar 3, 2026

/improve

@u-pr
Copy link
Contributor

u-pr bot commented Mar 3, 2026

Persistent review updated to latest commit f38866b

@Pauliusd01 Pauliusd01 self-requested a review March 4, 2026 11:03
Copy link
Collaborator

@Pauliusd01 Pauliusd01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested: Parts of the AI test plan here on github, the pre-production test plan, ran all of our sample scenes in all FEPM modes, ran the survival kids project in all modes looking for broken inputs. Checked performance via memory profiler by entering and leaving play mode a lot with reloads disabled, usage did not increase. (Windows and Mac)

If you have any other ideas that need testing let me know

if (handle.IsAllocated)
globalList[i].Free();
globalList.RemoveAtWithCapacity(i);
--i;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does --i here avoid the collection modified during enumeration exception that could occur?

continue;
}

for (var n = 0; n < state.totalMapCount; ++n)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this for loop at the right indentation level? It looks like this will be redone for each iteration of the globalList.length for loop above.

{
if (globalReset)
{
////FIXME: does not preserve action map state
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be done or will it be done in this PR or later on / it's known?

s_TrackedDirtyAssets.Clear();

// reload input assets marked as dirty from disk
DirtyAssetTracker.ReloadDirtyAssets();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really like the separation of logic here into it's own class, we definitely need more of this in classes like these :)


#if UNITY_EDITOR
using UnityEngine.InputSystem.Editor;
using UnityEngine.Tilemaps;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
using UnityEngine.Tilemaps;

{
get
{
Debug.Assert(m_Settings != null);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getter now allowed to return null but setter still throws on null?


// For remoting tests, we need to create a "fake manager" that simulates a remote endpoint.
// In this case don't install globals as this will corrupt the "local" manager state.
if (!fakeManagerForRemotingTests)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of mixing the mocking behaviour for testing. But I guess it's not worth creating a separated a test specific factory.

public void OnBeforeSerialize()
{
// Save current system state.
if (InputSystem.s_Manager != null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably early out if InputSystem.s_Manager is not available.

/// </summary>
internal void ApplySettings()
{
Debug.Assert(m_Settings != null);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it even for m_Settings to be null?

}
}

internal sealed class DeferBindingResolutionContext : IDisposable
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit. Should probably lie in InputManager file as direct dependency, or it's own, but not in an extension file.

ref var globalList = ref InputActionState.s_GlobalState.globalList;

public void Dispose()
for (var i = 0; i < globalList.length; ++i)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop should probably be own by InputActionState.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants