Skip to content

Conversation

@jfreire-unity
Copy link
Collaborator

Description

Please fill this section with a description what the pull request is trying to address and what changes were made.

Testing status & QA

Please describe the testing already done by you and what testing you request/recommend QA to execute. If you used or created any testing project please link them here too for QA.

Overall Product Risks

Please rate the potential complexity and halo effect from low to high for the reviewers. Note down potential risks to specific Editor branches if any.

  • Complexity:
  • Halo Effect:

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.

- Move InputSystem/* to Runtime/ (preserving history)
- Move InputSystem/Editor to Editor/ (preserving history)
- Add meta files for new folder structure
- Follows Unity package layout conventions
- All file history preserved via git mv
Also exposes the required internals between assemblies.
This is done to avoid calling into Edito specific code. Instead, it will
be called if Editor code has registered a callback.
Due to refactoring, a lot of paths still contained the InputSystem folder path that no longer exists. We only have Editor and Runtime folders.
using UnityEngine.InputSystem.Editor;
using UnityEngine.InputSystem.HID.Editor;

namespace UnityEngine.InputSystem.HID
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This should probably be changed to UnityEngine.InputSystem.HID.Editor

@josepmariapujol-unity josepmariapujol-unity marked this pull request as ready for review January 30, 2026 10:37
@u-pr
Copy link
Contributor

u-pr bot commented Jan 30, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪

The PR involves significant architectural changes separating Runtime and Editor assemblies, with many files added, moved, or modified, and contains a large amount of commented-out code that requires cleanup.
🏅 Score: 40

The PR is explicitly marked as DRAFT and contains a significant amount of code (implementation and tests) that is commented out rather than functioning, rendering the build potentially incomplete or untested.
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Disabled Tests

The entire content of this test file (and others like UITests.cs partially) has been commented out. This significantly reduces test coverage and hides potential regressions introduced by the assembly split.

// using System;
// using System.Collections.Generic;
// using System.Linq;
// using NUnit.Framework;
// using UnityEngine;
// using UnityEngine.InputSystem;
// using UnityEngine.InputSystem.Controls;
// using UnityEngine.InputSystem.EnhancedTouch;
// using UnityEngine.InputSystem.LowLevel;
// using UnityEngine.InputSystem.Utilities;
// using UnityEngine.TestTools.Utils;
// using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
// using Property = NUnit.Framework.PropertyAttribute;
// using TouchPhase = UnityEngine.InputSystem.TouchPhase;
//
// #if UNITY_EDITOR
// using UnityEngine.InputSystem.Editor;
// #endif
//
// internal class EnhancedTouchTests : CoreTestsFixture
// {
//     private TouchSimulation m_OldTouchSimulationInstance;
//
//     public override void Setup()
//     {
//         base.Setup();
//
//         // Disable() will not reset this so default initialize it here.
//         Touch.s_GlobalState.historyLengthPerFinger = 64;
//
//         if (!TestContext.CurrentContext.Test.Properties.ContainsKey("EnhancedTouchDisabled"))
//         {
//             InputSystem.AddDevice<Touchscreen>();
//             EnhancedTouchSupport.Enable();
//         }
//
//         // Make sure we don't run into interference with a TouchSimulation instance that may
//         // already be in place.
//         m_OldTouchSimulationInstance = TouchSimulation.s_Instance;
//         TouchSimulation.s_Instance = null;
//     }
//
//     public override void TearDown()
//     {
//         EnhancedTouchSupport.Disable();
//
//         // Make sure cleanup really did clean up.
//         Assert.That(Touch.s_GlobalState.touchscreens.length, Is.EqualTo(0));
//         Assert.That(Touch.s_GlobalState.playerState, Is.EqualTo(default(Touch.FingerAndTouchState)));
//         #if UNITY_EDITOR
//         Assert.That(Touch.s_GlobalState.editorState, Is.EqualTo(default(Touch.FingerAndTouchState)));
//         #endif
//
//         // Some state is kept alive in-between Disable/Enable. Manually clean it out.
//         Touch.s_GlobalState.onFingerDown = default;
//         Touch.s_GlobalState.onFingerUp = default;
//         Touch.s_GlobalState.onFingerMove = default;
//
//         TouchSimulation.Destroy();
//         TouchSimulation.s_Instance = m_OldTouchSimulationInstance;
//         m_OldTouchSimulationInstance = null;
//
//         base.TearDown();
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [Property("EnhancedTouchDisabled", 1)]
//     public void EnhancedTouch_IsDisabledByDefault()
//     {
//         Assert.That(EnhancedTouchSupport.enabled, Is.False);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [Property("EnhancedTouchDisabled", 1)]
//     public void EnhancedTouch_ThrowsExceptionWhenNotEnabled()
//     {
//         Assert.That(() => Touch.activeFingers, Throws.InvalidOperationException);
//         Assert.That(() => Touch.activeTouches, Throws.InvalidOperationException);
//         Assert.That(() => Touch.fingers, Throws.InvalidOperationException);
//         Assert.That(() => Touch.screens, Throws.InvalidOperationException);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [Property("EnhancedTouchDisabled", 1)]
//     public void EnhancedTouch_CanBeDisabledAndEnabled()
//     {
//         InputSystem.AddDevice<Touchscreen>();
//
//         EnhancedTouchSupport.Enable();
//         Assert.That(EnhancedTouchSupport.enabled, Is.True);
//
//         EnhancedTouchSupport.Disable();
//         Assert.That(EnhancedTouchSupport.enabled, Is.False);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [Property("EnhancedTouchDisabled", 1)]
//     public void EnhancedTouch_CanBeDisabledAndEnabled_WithoutTouchscreenPresent()
//     {
//         EnhancedTouchSupport.Enable();
//         Assert.That(EnhancedTouchSupport.enabled, Is.True);
//
//         EnhancedTouchSupport.Disable();
//         Assert.That(EnhancedTouchSupport.enabled, Is.False);
//     }
//
//     // The following tests deal with the fact that the input system potentially maintains more than one view on input
//     // because it concurrently supports input state queries in fixed update, dynamic/manual update, and editor updates.
//     // For the touch system, this means that we have to potentially track several different versions of state, too.
//     // The tests here go through the various combinations and make sure that Touch captures information correctly.
//     #region Update Types / Modes
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [TestCase(InputSettings.UpdateMode.ProcessEventsManually, InputUpdateType.Manual)]
//     [TestCase(InputSettings.UpdateMode.ProcessEventsInDynamicUpdate, InputUpdateType.Dynamic)]
//     [TestCase(InputSettings.UpdateMode.ProcessEventsInFixedUpdate, InputUpdateType.Fixed)]
//     public void EnhancedTouch_SupportsInputUpdateIn(InputSettings.UpdateMode updateMode, InputUpdateType updateType)
//     {
//         ResetTime();
//
//         InputSystem.settings.updateMode = updateMode;
//         runtime.currentTimeForFixedUpdate += Time.fixedDeltaTime;
//         BeginTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         InputSystem.Update(updateType);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].screenPosition,
//             Is.EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance));
//     }
//
//     #if UNITY_EDITOR
//     [Test]
//     [Category("EnhancedTouch")]
//     [TestCase(InputSettings.UpdateMode.ProcessEventsManually)]
//     [TestCase(InputSettings.UpdateMode.ProcessEventsInDynamicUpdate)]
//     [TestCase(InputSettings.UpdateMode.ProcessEventsInFixedUpdate)]
//     public void EnhancedTouch_SupportsEditorUpdates(InputSettings.UpdateMode updateMode)
//     {
//         ResetTime();
//
//         InputSystem.settings.editorInputBehaviorInPlayMode = default;
//
//         // To better observe that play mode and edit mode state is indeed independent and handled
//         // correctly, suppress resetting of the touch device when focus is lost to the player.
//         runtime.runInBackground = true;
//         SetCanRunInBackground(Touchscreen.current);
//
//         InputSystem.settings.updateMode = updateMode;
//         runtime.currentTimeForFixedUpdate += Time.fixedDeltaTime;
//         // Run one player update with data.
//         BeginTouch(1, new Vector2(0.123f, 0.234f));
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//
//         // And make sure we're not seeing the data in the editor.
//         runtime.PlayerFocusLost();
//         InputSystem.Update(InputUpdateType.Editor);
//
//         Assert.That(Touch.activeTouches, Is.Empty);
//
//         // Feed some data into editor state.
//         BeginTouch(2, new Vector2(0.234f, 0.345f), queueEventOnly: true);
//         InputSystem.Update(InputUpdateType.Editor);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(2));
//
//         // Switch back to player.
//         runtime.PlayerFocusGained();
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//     }
//
//     #endif
//
//     #endregion
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanGetActiveTouches()
//     {
//         // Begin and move in same frame.
//         BeginTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.234f, 0.345f), queueEventOnly: true);
//         // Begin only.
//         BeginTouch(2, new Vector2(0.345f, 0.456f), queueEventOnly: true);
//         // Begin, move, and end in same frame.
//         BeginTouch(3, new Vector2(0.456f, 0.567f), queueEventOnly: true);
//         MoveTouch(3, new Vector2(0.111f, 0.222f), queueEventOnly: true); // This one should get ignored.
//         EndTouch(3, new Vector2(0.567f, 0.678f), queueEventOnly: true);
//         // Begin only but reusing previous touch ID.
//         BeginTouch(3, new Vector2(0.678f, 0.789f), queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(4));
//
//         // When we begin and move a touch in the same frame, the phase should be Began, *NOT* Moved.
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Began)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Began)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.345f, 0.456f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         // A touch that begins and ends in the same frame, will see a Began in the current frame and a separate Ended in the next
//         // (even though there was no actual activity on the touch that frame).
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Began)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.456f, 0.567f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Began)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.678f, 0.789f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(4));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Moved)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.234f, 0.345f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(new Vector2(0.111f, 0.111f)).Using(Vector2EqualityComparer.Instance));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.345f, 0.456f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         // Ended record for touch touch #3 that began and ended in previous frame.
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Ended)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.567f, 0.678f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(new Vector2(0.111f, 0.111f)).Using(Vector2EqualityComparer.Instance));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.678f, 0.789f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(3));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.234f, 0.345f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.345f, 0.456f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.678f, 0.789f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(3));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.234f, 0.345f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.345f, 0.456f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.678f, 0.789f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(default(Vector2)));
//
//         EndTouch(3, new Vector2(0.111f, 0.222f), queueEventOnly: true);
//         EndTouch(2, new Vector2(0.222f, 0.333f), queueEventOnly: true);
//         EndTouch(1, new Vector2(0.333f, 0.444f), queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(3));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Ended)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.333f, 0.444f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(new Vector2(0.099f, 0.099f)).Using(Vector2EqualityComparer.Instance));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Ended)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.222f, 0.333f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(new Vector2(-0.123f, -0.123f)).Using(Vector2EqualityComparer.Instance));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Ended)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.111f, 0.222f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("delta").EqualTo(new Vector2(-0.567f, -0.567f)).Using(Vector2EqualityComparer.Instance));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Is.Empty);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_DeltasInActiveTouchesAccumulateAndReset()
//     {
//         // Only Began in frame.
//         BeginTouch(1, new Vector2(0.111f, 0.222f), queueEventOnly: true);
//         // Began and Moved in same frame.
//         BeginTouch(2, new Vector2(0.222f, 0.333f), queueEventOnly: true);
//         MoveTouch(2, new Vector2(0.333f, 0.444f), queueEventOnly: true);
//         // Began and Ended in same frame.
//         BeginTouch(3, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         EndTouch(3, new Vector2(0.234f, 0.345f), queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(3));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Began)
//             .And.With.Property("delta").EqualTo(default(Vector2))
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.111f, 0.222f)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Began)
//             .And.With.Property("delta").EqualTo(default(Vector2))
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.222f, 0.333f)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Began)
//             .And.With.Property("delta").EqualTo(default(Vector2))
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.123f, 0.234f)));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(3)); // Touch #3 ends this frame.
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("delta").EqualTo(default(Vector2))
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.111f, 0.222f)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Moved)
//             .And.With.Property("delta").EqualTo(new Vector2(0.111f, 0.111f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.333f, 0.444f)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(3)
//             .And.With.Property("phase").EqualTo(TouchPhase.Ended)
//             .And.With.Property("delta").EqualTo(new Vector2(0.111f, 0.111f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.234f, 0.345f)));
//
//         MoveTouch(1, new Vector2(0.444f, 0.555f), queueEventOnly: true); // Generates delta to (0.111,0.111)!
//         MoveTouch(1, new Vector2(0.555f, 0.666f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.666f, 0.777f), queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(2));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Moved)
//             .And.With.Property("delta").EqualTo(new Vector2(0.555f, 0.555f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.666f, 0.777f)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("delta").EqualTo(default(Vector2))
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.333f, 0.444f)));
//
//         MoveTouch(1, new Vector2(0.777f, 0.888f), queueEventOnly: true);
//         EndTouch(1, new Vector2(0.888f, 0.999f), queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(2));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(1)
//             .And.With.Property("phase").EqualTo(TouchPhase.Ended)
//             .And.With.Property("delta").EqualTo(new Vector2(0.222f, 0.222f)).Using(Vector2EqualityComparer.Instance)
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.888f, 0.999f)));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("delta").EqualTo(default(Vector2))
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.333f, 0.444f)));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//
//         Assert.That(Touch.activeTouches, Has.Exactly(1)
//             .With.Property("touchId").EqualTo(2)
//             .And.With.Property("phase").EqualTo(TouchPhase.Stationary)
//             .And.With.Property("delta").EqualTo(default(Vector2))
//             .And.With.Property("screenPosition").EqualTo(new Vector2(0.333f, 0.444f)));
//     }
//
//     // Unlike when looking at activeTouches (given that "active" is a frame-to-frame concept here)
//     // when looking at touch history, we're looking at values the touches had when they were reported.
//     // Thus we don't want accumulation and resetting (which again are frame-to-frame kind of mechanics).
//     [Test]
//     [Category("EnhancedTouch")]
//     [TestCase(false)]
//     [TestCase(true)]
//     public void EnhancedTouch_DeltasInTouchHistoryDoNotAccumulateAndReset_WithEventMergingSetTo(bool mergeRedundantEvents)
//     {
//         InputSystem.settings.disableRedundantEventsMerging = !mergeRedundantEvents;
//
//         BeginTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.234f, 0.345f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.345f, 0.456f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.456f, 0.567f), queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeFingers[0].touchHistory.Count, Is.EqualTo(mergeRedundantEvents ? 3 : 4));
//
//         if (mergeRedundantEvents)
//         {
//             // Event merging adds deltas inside
//             Assert.That(Touch.activeFingers[0].touchHistory[0].delta,
//                 Is.EqualTo(new Vector2(0.222f, 0.222f)).Using(Vector2EqualityComparer.Instance));
//             Assert.That(Touch.activeFingers[0].touchHistory[1].delta,
//                 Is.EqualTo(new Vector2(0.111f, 0.111f)).Using(Vector2EqualityComparer.Instance));
//         }
//         else
//         {
//             Assert.That(Touch.activeFingers[0].touchHistory[0].delta,
//                 Is.EqualTo(new Vector2(0.222f, 0.222f)).Using(Vector2EqualityComparer.Instance));
//             Assert.That(Touch.activeFingers[0].touchHistory[1].delta,
//                 Is.EqualTo(new Vector2(0.111f, 0.111f)).Using(Vector2EqualityComparer.Instance));
//             Assert.That(Touch.activeFingers[0].touchHistory[2].delta,
//                 Is.EqualTo(new Vector2(0.111f, 0.111f)).Using(Vector2EqualityComparer.Instance));
//         }
//
//         Assert.That(Touch.activeFingers[0].touchHistory.Last().delta,
//             Is.EqualTo(new Vector2()).Using(Vector2EqualityComparer.Instance));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanCheckForTaps()
//     {
//         BeginTouch(1, new Vector2(123, 234));
//
//         Assert.That(Touch.activeTouches[0].isTap, Is.False);
//         Assert.That(Touch.activeTouches[0].tapCount, Is.EqualTo(0));
//
//         EndTouch(1, new Vector2(123, 234));
//
//         Assert.That(Touch.activeTouches[0].isTap, Is.True);
//         Assert.That(Touch.activeTouches[0].tapCount, Is.EqualTo(1));
//         Assert.That(Touch.fingers[0].touchHistory, Has.Count.EqualTo(2));
//         Assert.That(Touch.fingers[0].touchHistory[0].isTap, Is.True);
//         Assert.That(Touch.fingers[0].touchHistory[1].isTap, Is.False);
//         Assert.That(Touch.fingers[0].touchHistory[0].tapCount, Is.EqualTo(1));
//         Assert.That(Touch.fingers[0].touchHistory[1].tapCount, Is.EqualTo(0));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanGetStartPositionAndTimeOfTouch()
//     {
//         currentTime = 0.111;
//         BeginTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.234f, 0.345f), queueEventOnly: true);
//         currentTime = 0.222;
//         MoveTouch(1, new Vector2(0.345f, 0.456f), queueEventOnly: true);
//         BeginTouch(2, new Vector2(0.456f, 0.567f), queueEventOnly: true);
//         currentTime = 0.333;
//         EndTouch(2, new Vector2(0.567f, 0.678f), queueEventOnly: true);
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches[0].startScreenPosition,
//             Is.EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[1].startScreenPosition,
//             Is.EqualTo(new Vector2(0.456f, 0.567f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].startTime, Is.EqualTo(0.111).Within(0.0001));
//         Assert.That(Touch.activeTouches[1].startTime, Is.EqualTo(0.222).Within(0.0001));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [TestCase(false)]
//     [TestCase(true)]
//     public void EnhancedTouch_CanAccessHistoryOfTouch_WithEventMergingSetTo(bool mergeRedundantEvents)
//     {
//         ResetTime();
//
//         InputSystem.settings.disableRedundantEventsMerging = !mergeRedundantEvents;
//
//         // Noise. This one shouldn't show up in the history.
//         BeginTouch(2, new Vector2(0.111f, 0.222f), queueEventOnly: true);
//         EndTouch(2, new Vector2(0.111f, 0.222f), queueEventOnly: true);
//         InputSystem.Update();
//         InputSystem.Update(); // The end touch lingers for one frame.
//
//         currentTime = 0.876;
//         BeginTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         currentTime = 0.987;
//         MoveTouch(1, new Vector2(0.234f, 0.345f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.345f, 0.456f), queueEventOnly: true);
//         MoveTouch(1, new Vector2(0.456f, 0.567f), queueEventOnly: true);
//         BeginTouch(3, new Vector2(0.666f, 0.666f), queueEventOnly: true);
//         BeginTouch(4, new Vector2(0.777f, 0.777f), queueEventOnly: true);
//         EndTouch(4, new Vector2(0.888f, 0.888f), queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(3));
//
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].history, Has.Count.EqualTo(mergeRedundantEvents ? 2 : 3));
//         Assert.That(Touch.activeTouches[0].history, Has.All.Property("finger").SameAs(Touch.activeTouches[0].finger));
//         var beganIndex = mergeRedundantEvents ? 1 : 2;
//         Assert.That(Touch.activeTouches[0].history[beganIndex].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.activeTouches[0].history[beganIndex].time, Is.EqualTo(0.876).Within(0.0001));
//         Assert.That(Touch.activeTouches[0].history[beganIndex].startTime, Is.EqualTo(0.876).Within(0.0001));
//         Assert.That(Touch.activeTouches[0].history[beganIndex].startScreenPosition,
//             Is.EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance));
//         for (int index = 0; index < (mergeRedundantEvents ? 1 : 2); ++index)
//         {
//             Assert.That(Touch.activeTouches[0].history[index].phase, Is.EqualTo(TouchPhase.Moved));
//             Assert.That(Touch.activeTouches[0].history[index].time, Is.EqualTo(0.987).Within(0.0001));
//             Assert.That(Touch.activeTouches[0].history[index].startTime, Is.EqualTo(0.876).Within(0.0001));
//             Assert.That(Touch.activeTouches[0].history[index].startScreenPosition,
//                 Is.EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance));
//         }
//
//         Assert.That(Touch.activeTouches[1].touchId, Is.EqualTo(3));
//         Assert.That(Touch.activeTouches[1].history, Is.Empty);
//
//         Assert.That(Touch.activeTouches[2].touchId, Is.EqualTo(4));
//         Assert.That(Touch.activeTouches[2].history, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[2].history[0].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.activeTouches[2].history[0].screenPosition,
//             Is.EqualTo(new Vector2(0.777f, 0.777f)).Using(Vector2EqualityComparer.Instance));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_HasOneFingerForEveryPossibleContactOnScreen()
//     {
//         var touchscreen1 = Touchscreen.current;
//
//         // To mix it up, have a touchscreen with 15 possible contacts instead of
//         // the default ten.
//         const string json = @"
//             {
//                 ""name"" : ""CustomTouchscreen"",
//                 ""extend"" : ""Touchscreen"",
//                 ""controls"" : [
//                     { ""name"" : ""touch"", ""arraySize"" : 15 }
//                 ]
//             }
//         ";
//
//         InputSystem.RegisterLayout(json);
//         var touchscreen2 = (Touchscreen)InputSystem.AddDevice("CustomTouchscreen");
//
//         // Make sure that the system has noticed both screens. One got added before it initialized,
//         // one got added after.
//         Assert.That(Touch.screens.Count(), Is.EqualTo(2));
//         Assert.That(Touch.screens, Has.Exactly(1).SameAs(touchscreen1));
//         Assert.That(Touch.screens, Has.Exactly(1).SameAs(touchscreen2));
//
//         // Make we get a combined 70 fingers.
//         Assert.That(Touch.fingers, Has.Count.EqualTo(touchscreen1.touches.Count + touchscreen2.touches.Count));
//         Assert.That(Touch.fingers, Has.Exactly(touchscreen1.touches.Count).With.Property("screen").SameAs(touchscreen1));
//         Assert.That(Touch.fingers, Has.Exactly(touchscreen2.touches.Count).With.Property("screen").SameAs(touchscreen2));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanTrackActiveFingers()
//     {
//         Assert.That(Touch.activeFingers, Is.Empty);
//
//         BeginTouch(1, new Vector2(0.123f, 0.234f));
//
//         Assert.That(Touch.activeFingers, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeFingers[0].isActive, Is.True);
//         Assert.That(Touch.activeFingers[0].index, Is.EqualTo(0));
//         Assert.That(Touch.activeFingers[0].screen, Is.SameAs(Touchscreen.current));
//         Assert.That(Touch.activeFingers[0].screenPosition,
//             Is.EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance));
//
//         MoveTouch(1, new Vector2(0.234f, 0.345f));
//
//         Assert.That(Touch.activeFingers, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeFingers[0].isActive, Is.True);
//         Assert.That(Touch.activeFingers[0].index, Is.EqualTo(0));
//         Assert.That(Touch.activeFingers[0].screen, Is.SameAs(Touchscreen.current));
//         Assert.That(Touch.activeFingers[0].screenPosition,
//             Is.EqualTo(new Vector2(0.234f, 0.345f)).Using(Vector2EqualityComparer.Instance));
//
//         BeginTouch(2, new Vector2(0.987f, 0.789f));
//
//         Assert.That(Touch.activeFingers, Has.Count.EqualTo(2));
//         Assert.That(Touch.activeFingers[0].isActive, Is.True);
//         Assert.That(Touch.activeFingers[0].index, Is.EqualTo(0));
//         Assert.That(Touch.activeFingers[0].screen, Is.SameAs(Touchscreen.current));
//         Assert.That(Touch.activeFingers[0].screenPosition,
//             Is.EqualTo(new Vector2(0.234f, 0.345f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeFingers[1].isActive, Is.True);
//         Assert.That(Touch.activeFingers[1].index, Is.EqualTo(1));
//         Assert.That(Touch.activeFingers[1].screen, Is.SameAs(Touchscreen.current));
//         Assert.That(Touch.activeFingers[1].screenPosition,
//             Is.EqualTo(new Vector2(0.987f, 0.789f)).Using(Vector2EqualityComparer.Instance));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanTrackActiveFingers_FromMultipleTouchscreens()
//     {
//         var screen1 = Touchscreen.current;
//         var screen2 = InputSystem.AddDevice<Touchscreen>();
//
//         Assert.That(Touch.fingers, Has.Count.EqualTo(screen1.touches.Count + screen2.touches.Count));
//         Assert.That(Touch.fingers, Has.Exactly(screen1.touches.Count).With.Property("screen").SameAs(screen1));
//         Assert.That(Touch.fingers, Has.Exactly(screen2.touches.Count).With.Property("screen").SameAs(screen2));
//
//         BeginTouch(1, new Vector2(0.123f, 0.234f), screen: screen1);
//         BeginTouch(1, new Vector2(0.234f, 0.345f), screen: screen2);
//
//         Assert.That(Touch.activeFingers, Has.Count.EqualTo(2));
//         Assert.That(Touch.activeFingers,
//             Has.Exactly(1).With.Property("screen").SameAs(screen1).And.With.Property("screenPosition")
//                 .EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeFingers,
//             Has.Exactly(1).With.Property("screen").SameAs(screen2).And.With.Property("screenPosition")
//                 .EqualTo(new Vector2(0.234f, 0.345f)).Using(Vector2EqualityComparer.Instance));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_RemovingTouchscreenRemovesItsActiveTouches()
//     {
//         BeginTouch(1, new Vector2(123, 234));
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//
//         InputSystem.RemoveDevice(Touchscreen.current);
//
//         Assert.That(Touch.activeTouches, Is.Empty);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanGetCurrentTouchFromFinger()
//     {
//         BeginTouch(1, new Vector2(0.123f, 0.234f));
//         BeginTouch(2, new Vector2(0.456f, 0.567f));
//
//         Assert.That(Touch.activeFingers, Has.Count.EqualTo(2));
//         Assert.That(Touch.activeFingers[0].currentTouch, Is.Not.EqualTo(default(Touch)));
//         Assert.That(Touch.activeFingers[0].lastTouch, Is.EqualTo(Touch.activeFingers[0].currentTouch));
//         Assert.That(Touch.activeFingers[0].currentTouch.screenPosition, Is.EqualTo(new Vector2(0.123f, 0.234f)));
//         Assert.That(Touch.activeFingers[0].currentTouch.touchId, Is.EqualTo(1));
//
//         EndTouch(1, new Vector2(0.234f, 0.345f));
//
//         // The ended touch should linger for one frame.
//         Assert.That(Touch.activeFingers, Has.Count.EqualTo(2));
//         Assert.That(Touch.activeFingers[0].currentTouch.phase, Is.EqualTo(TouchPhase.Ended));
//         Assert.That(Touch.activeFingers[0].currentTouch.screenPosition, Is.EqualTo(new Vector2(0.234f, 0.345f)));
//         Assert.That(Touch.activeFingers[0].currentTouch.touchId, Is.EqualTo(1));
//         Assert.That(Touch.activeFingers[0].lastTouch, Is.EqualTo(Touch.activeFingers[0].currentTouch));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeFingers, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeFingers[0].currentTouch.touchId, Is.EqualTo(2));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanGetLastTouchFromFinger()
//     {
//         BeginTouch(1, new Vector2(0.123f, 0.234f));
//         EndTouch(1, new Vector2(0.234f, 0.345f));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.fingers[0].currentTouch.valid, Is.False);
//         Assert.That(Touch.fingers[0].lastTouch.valid, Is.True);
//         Assert.That(Touch.fingers[0].lastTouch.screenPosition, Is.EqualTo(new Vector2(0.234f, 0.345f)));
//         Assert.That(Touch.fingers[0].lastTouch.touchId, Is.EqualTo(1));
//         Assert.That(Touch.fingers[0].lastTouch.phase, Is.EqualTo(TouchPhase.Ended));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanAccessTouchHistoryOnFinger()
//     {
//         BeginTouch(1, new Vector2(0.123f, 0.234f));    // Finger #0, touch #3
//         MoveTouch(1, new Vector2(0.234f, 0.345f));     // Finger #0, touch #2
//         MoveTouch(1, new Vector2(0.345f, 0.456f));     // Finger #0, touch #1
//         BeginTouch(2, new Vector2(0.456f, 0.567f));    // Finger #1, touch #4
//         MoveTouch(2, new Vector2(0.567f, 0.678f));     // Finger #1, touch #3
//         InputSystem.Update(); // Noise.
//         MoveTouch(1, new Vector2(0.789f, 0.890f));     // Finger #0, touch #0
//         EndTouch(2, new Vector2(0.111f, 0.222f));      // Finger #1, touch #2
//         BeginTouch(3, new Vector2(0.222f, 0.333f));    // Finger #1, touch #1
//         EndTouch(3, new Vector2(0.333f, 0.444f));      // Finger #1, touch #0
//
//         Assert.That(Touch.fingers[0].touchHistory, Has.Count.EqualTo(4));
//         Assert.That(Touch.fingers[1].touchHistory, Has.Count.EqualTo(5));
//         Assert.That(Touch.fingers[0].touchHistory, Has.All.Property("finger").SameAs(Touch.fingers[0]));
//         Assert.That(Touch.fingers[1].touchHistory, Has.All.Property("finger").SameAs(Touch.fingers[1]));
//
//         Assert.That(Touch.fingers[0].touchHistory[0].touchId, Is.EqualTo(1));
//         Assert.That(Touch.fingers[0].touchHistory[0].phase, Is.EqualTo(TouchPhase.Moved));
//         Assert.That(Touch.fingers[0].touchHistory[0].screenPosition,
//             Is.EqualTo(new Vector2(0.789f, 0.890f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.fingers[0].touchHistory[1].touchId, Is.EqualTo(1));
//         Assert.That(Touch.fingers[0].touchHistory[1].phase, Is.EqualTo(TouchPhase.Moved));
//         Assert.That(Touch.fingers[0].touchHistory[1].screenPosition,
//             Is.EqualTo(new Vector2(0.345f, 0.456f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.fingers[0].touchHistory[2].touchId, Is.EqualTo(1));
//         Assert.That(Touch.fingers[0].touchHistory[2].phase, Is.EqualTo(TouchPhase.Moved));
//         Assert.That(Touch.fingers[0].touchHistory[2].screenPosition,
//             Is.EqualTo(new Vector2(0.234f, 0.345f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.fingers[0].touchHistory[3].touchId, Is.EqualTo(1));
//         Assert.That(Touch.fingers[0].touchHistory[3].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.fingers[0].touchHistory[3].screenPosition,
//             Is.EqualTo(new Vector2(0.123f, 0.234f)).Using(Vector2EqualityComparer.Instance));
//
//         Assert.That(Touch.fingers[1].touchHistory[0].touchId, Is.EqualTo(3));
//         Assert.That(Touch.fingers[1].touchHistory[0].phase, Is.EqualTo(TouchPhase.Ended));
//         Assert.That(Touch.fingers[1].touchHistory[0].screenPosition,
//             Is.EqualTo(new Vector2(0.333f, 0.444f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.fingers[1].touchHistory[1].touchId, Is.EqualTo(3));
//         Assert.That(Touch.fingers[1].touchHistory[1].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.fingers[1].touchHistory[1].screenPosition,
//             Is.EqualTo(new Vector2(0.222f, 0.333f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.fingers[1].touchHistory[2].touchId, Is.EqualTo(2));
//         Assert.That(Touch.fingers[1].touchHistory[2].phase, Is.EqualTo(TouchPhase.Ended));
//         Assert.That(Touch.fingers[1].touchHistory[2].screenPosition,
//             Is.EqualTo(new Vector2(0.111f, 0.222f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.fingers[1].touchHistory[3].touchId, Is.EqualTo(2));
//         Assert.That(Touch.fingers[1].touchHistory[3].phase, Is.EqualTo(TouchPhase.Moved));
//         Assert.That(Touch.fingers[1].touchHistory[3].screenPosition,
//             Is.EqualTo(new Vector2(0.567f, 0.678f)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.fingers[1].touchHistory[4].touchId, Is.EqualTo(2));
//         Assert.That(Touch.fingers[1].touchHistory[4].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.fingers[1].touchHistory[4].screenPosition,
//             Is.EqualTo(new Vector2(0.456f, 0.567f)).Using(Vector2EqualityComparer.Instance));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanReceiveCallbacksOnFingerActivity()
//     {
//         var receivedFingers = new List<Tuple<string, Finger>>();
//
//         Touch.onFingerDown +=
//             finger => receivedFingers.Add(new Tuple<string, Finger>("Down", finger));
//         Touch.onFingerUp +=
//             finger => receivedFingers.Add(new Tuple<string, Finger>("Up", finger));
//         Touch.onFingerMove +=
//             finger => receivedFingers.Add(new Tuple<string, Finger>("Move", finger));
//
//         BeginTouch(1, new Vector2(0.123f, 0.234f));
//         BeginTouch(2, new Vector2(0.234f, 0.345f));
//
//         Assert.That(receivedFingers, Is.EquivalentTo(new[]
//         {
//             new Tuple<string, Finger>("Down", Touch.fingers[0]),
//             new Tuple<string, Finger>("Down", Touch.fingers[1]),
//         }));
//
//         receivedFingers.Clear();
//
//         MoveTouch(1, new Vector2(0.345f, 0.456f));
//         MoveTouch(1, new Vector2(0.456f, 0.567f));
//
//         Assert.That(receivedFingers, Is.EquivalentTo(new[]
//         {
//             new Tuple<string, Finger>("Move", Touch.fingers[0]),
//             new Tuple<string, Finger>("Move", Touch.fingers[0]),
//         }));
//
//         receivedFingers.Clear();
//
//         EndTouch(2, new Vector2(0.567f, 0.678f));
//
//         Assert.That(receivedFingers, Is.EquivalentTo(new[]
//         {
//             new Tuple<string, Finger>("Up", Touch.fingers[1])
//         }));
//     }
//
//     // https://fogbugz.unity3d.com/f/cases/1286865/
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanBeDisabledAndReenabled()
//     {
//         BeginTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         InputSystem.Update();
//         Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Began));
//
//         MoveTouch(1, new Vector2(0.234f, 0.345f), queueEventOnly: true);
//         InputSystem.Update();
//         Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Moved));
//
//         InputSystem.Update();
//         Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Stationary));
//
//         EnhancedTouchSupport.Disable();
//         EnhancedTouchSupport.Enable();
//
//         InputSystem.Update();
//         Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Stationary));
//
//         MoveTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
//         InputSystem.Update();
//         Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Moved));
//
//         InputSystem.Update();
//         Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Stationary));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [Property("EnhancedTouchDisabled", 1)]
//     public void EnhancedTouch_CanEnableAndDisableTouchSimulation()
//     {
//         Assert.That(InputSystem.devices, Has.None.TypeOf<Touchscreen>());
//
//         TouchSimulation.Enable();
//
//         Assert.That(InputSystem.devices, Has.Exactly(1).AssignableTo<Touchscreen>());
//         Assert.That(TouchSimulation.instance, Is.Not.Null);
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen, Is.Not.Null);
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen, Is.SameAs(Touchscreen.current));
//
//         TouchSimulation.Disable();
//
//         Assert.That(InputSystem.devices, Has.None.TypeOf<Touchscreen>());
//
//         // Make sure we can re-enable it.
//         TouchSimulation.Enable();
//
//         Assert.That(InputSystem.devices, Has.Exactly(1).AssignableTo<Touchscreen>());
//
//         TouchSimulation.Destroy();
//
//         Assert.That(TouchSimulation.instance, Is.Null);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [TestCase("Mouse")]
//     [TestCase("Pen")]
//     [TestCase("Pointer")]
//     public void EnhancedTouch_CanSimulateTouchInputFrom(string layoutName)
//     {
//         var pointer = (Pointer)InputSystem.AddDevice(layoutName);
//
//         TouchSimulation.Enable();
//
//         Set(pointer.position, new Vector2(123, 234), queueEventOnly: true);
//         Press(pointer.press);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[0].screenPosition, Is.EqualTo(new Vector2(123, 234)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.activeTouches[0].tapCount, Is.Zero);
//         Assert.That(Touch.activeTouches[0].isTap, Is.False);
//
//         Move(pointer.position, new Vector2(234, 345));
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[0].screenPosition, Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].delta, Is.EqualTo(new Vector2(111, 111)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Moved));
//         Assert.That(Touch.activeTouches[0].tapCount, Is.Zero);
//         Assert.That(Touch.activeTouches[0].isTap, Is.False);
//
//         Release(pointer.press);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[0].screenPosition, Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Ended));
//         Assert.That(Touch.activeTouches[0].tapCount, Is.Zero);
//         Assert.That(Touch.activeTouches[0].isTap, Is.False);
//
//         PressAndRelease(pointer.press);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(2));
//         Assert.That(Touch.activeTouches[0].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[0].screenPosition, Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Began)); // Ended comes in next frame.
//         Assert.That(Touch.activeTouches[0].tapCount, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].isTap, Is.True);
//
//         PressAndRelease(pointer.press);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(2));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(2));
//         Assert.That(Touch.activeTouches[0].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[0].screenPosition, Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Ended));
//         Assert.That(Touch.activeTouches[0].tapCount, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].isTap, Is.True);
//         Assert.That(Touch.activeTouches[1].touchId, Is.EqualTo(3));
//         Assert.That(Touch.activeTouches[1].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[1].screenPosition, Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[1].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[1].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.activeTouches[1].tapCount, Is.EqualTo(2));
//         Assert.That(Touch.activeTouches[1].isTap, Is.True);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(3));
//         Assert.That(Touch.activeTouches[0].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[0].screenPosition, Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Ended));
//         Assert.That(Touch.activeTouches[0].tapCount, Is.EqualTo(2));
//         Assert.That(Touch.activeTouches[0].isTap, Is.True);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Is.Empty);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_CanSimulateTouchInputFromMultiplePointers()
//     {
//         var pointer1 = InputSystem.AddDevice<Pointer>();
//         var pointer2 = InputSystem.AddDevice<Pointer>();
//
//         TouchSimulation.Enable();
//
//         Set(pointer1.position, new Vector2(123, 234), queueEventOnly: true);
//         Set(pointer2.position, new Vector2(234, 345), queueEventOnly: true);
//         Press(pointer1.press, queueEventOnly: true);
//         Press(pointer2.press, queueEventOnly: true);
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(2));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[0].screenPosition, Is.EqualTo(new Vector2(123, 234)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Began));
//         Assert.That(Touch.activeTouches[1].touchId, Is.EqualTo(2));
//         Assert.That(Touch.activeTouches[1].screen, Is.SameAs(TouchSimulation.instance.simulatedTouchscreen));
//         Assert.That(Touch.activeTouches[1].screenPosition, Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[1].delta, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//         Assert.That(Touch.activeTouches[1].phase, Is.EqualTo(TouchPhase.Began));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_TouchSimulation_CanAddAndRemovePointerDevices()
//     {
//         TouchSimulation.Enable();
//
//         var pointer = InputSystem.AddDevice<Pointer>();
//         Press(pointer.press);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//
//         InputSystem.RemoveDevice(pointer);
//
//         ////FIXME: This doesn't work yet as TouchSimulation isn't using events and Touch ignores input that isn't from events
//         //Assert.That(Touch.activeTouches, Is.Empty);
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_TouchSimulation_ProducesOneTouchFromEveryNonSyntheticButton()
//     {
//         const string json = @"
//             {
//                 ""name"" : ""CustomPointer"",
//                 ""extend"" : ""Pointer"",
//                 ""controls"" : [
//                     { ""name"" : ""syntheticButton"", ""layout"" : ""Button"", ""synthetic"" : true },
//                     { ""name"" : ""nonSyntheticButton"", ""layout"" : ""Button"" }
//                 ]
//             }
//         ";
//
//         InputSystem.RegisterLayout(json);
//         var device = (Pointer)InputSystem.AddDevice("CustomPointer");
//
//         TouchSimulation.Enable();
//
//         Press((ButtonControl)device["nonSyntheticButton"]);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//
//         Press((ButtonControl)device["syntheticButton"]);
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_TouchSimulation_ProducesPrimaryTouches()
//     {
//         var mouse = InputSystem.AddDevice<Mouse>();
//
//         TouchSimulation.Enable();
//
//         Set(mouse.position, new Vector2(123, 234));
//         Press(mouse.leftButton);
//
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.press.ReadValue(), Is.EqualTo(1).Within(0.00001));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.primaryTouch.touchId.ReadValue(), Is.EqualTo(1));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.primaryTouch.phase.ReadValue(), Is.EqualTo(TouchPhase.Began));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.position.ReadValue(),
//             Is.EqualTo(new Vector2(123, 234)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.delta.ReadValue(),
//             Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//
//         Set(mouse.position, new Vector2(234, 345));
//
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.press.ReadValue(), Is.EqualTo(1).Within(0.00001));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.primaryTouch.touchId.ReadValue(), Is.EqualTo(1));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.primaryTouch.phase.ReadValue(), Is.EqualTo(TouchPhase.Moved));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.position.ReadValue(),
//             Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.delta.ReadValue(),
//             Is.EqualTo(new Vector2(111, 111)).Using(Vector2EqualityComparer.Instance));
//
//         InputSystem.Update();
//
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.press.ReadValue(), Is.EqualTo(1).Within(0.00001));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.primaryTouch.touchId.ReadValue(), Is.EqualTo(1));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.primaryTouch.phase.ReadValue(), Is.EqualTo(TouchPhase.Moved));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.position.ReadValue(),
//             Is.EqualTo(new Vector2(234, 345)).Using(Vector2EqualityComparer.Instance));
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen.delta.ReadValue(),
//             Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance));
//     }
//
//     // This is mostly for domain reloads.
//     [Test]
//     [Category("EnhancedTouch")]
//     public void EnhancedTouch_TouchSimulation_ReusesSimulatedTouchscreenInstanceIfPresent()
//     {
//         var device = InputSystem.AddDevice<Touchscreen>("Simulated Touchscreen");
//
//         TouchSimulation.Enable();
//
//         Assert.That(TouchSimulation.instance.simulatedTouchscreen, Is.SameAs(device));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     public unsafe void EnhancedTouch_TouchSimulation_DisablesPointerDevicesWithoutDisablingEvents()
//     {
//         var mouse = InputSystem.AddDevice<Mouse>();
//         var pen = InputSystem.AddDevice<Pen>();
//
//         runtime.SetDeviceCommandCallback(mouse, (id, command) =>
//         {
//             Assert.That(command->type, Is.Not.EqualTo(DisableDeviceCommand.Type));
//             return InputDeviceCommand.GenericFailure;
//         });
//
//         TouchSimulation.Enable();
//
//         Assert.That(mouse.enabled, Is.False);
//         Assert.That(pen.enabled, Is.False);
//
//         InputSystem.QueueStateEvent(mouse, new MouseState
//         {
//             position = new Vector2(123, 234),
//         }.WithButton(MouseButton.Left));
//         InputSystem.Update();
//
//         Assert.That(Touchscreen.current.touches[0].isInProgress, Is.True);
//         Assert.That(Touchscreen.current.touches[0].position.ReadValue(), Is.EqualTo(new Vector2(123, 234)));
//     }
//
//     [Test]
//     [Category("EnhancedTouch")]
//     [TestCase(true)]
//     [TestCase(false)]
//     public void EnhancedTouch_ActiveTouchesGetCanceledOnFocusLoss_WithRunInBackgroundBeing(bool runInBackground)
//     {
//         runtime.runInBackground = runInBackground;
//
//         BeginTouch(1, new Vector2(123, 456));
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Began));
//
//         runtime.PlayerFocusLost();
//
//         if (runInBackground)
//         {
//             // When running in the background, next update after focus loss sees touches cancelled
//             // and update after that sees them gone.
//             InputSystem.Update(InputUpdateType.Dynamic);
//         }
//         else
//         {
//             // When not running in the background, the same thing happens but only on focus gain.
//             runtime.PlayerFocusGained();
//             InputSystem.Update();
//         }
//
//         Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
//         Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Canceled));
//
//         InputSystem.Update();
//
//         Assert.That(Touch.activeTouches, Is.Empty);
//     }
// }
Commented Out Implementation

The newly added file TouchSimulation.cs (and others like FastMouse.cs, VirtualMouseInput.cs) consists entirely of commented-out code. This implementation code needs to be properly enabled and compiled, or removed if not ready.

// using System;
// using Unity.Collections.LowLevel.Unsafe;
// using UnityEngine.InputSystem.Controls;
// using UnityEngine.InputSystem.LowLevel;
// using UnityEngine.InputSystem.Utilities;
// #if UNITY_EDITOR
// using UnityEditor;
// using UnityEngine.InputSystem.Editor;
// #endif
//
// ////TODO: add pressure support
//
// ////REVIEW: extend this beyond simulating from Pointers only? theoretically, we could simulate from any means of generating positions and presses
//
// ////REVIEW: I think this is a workable first attempt but overall, not a sufficient take on input simulation. ATM this uses InputState.Change
// ////        to shove input directly into Touchscreen. Also, it uses state change notifications to set off the simulation. The latter leads
// ////        to touch input potentially changing multiple times in response to a single pointer event. And the former leads to the simulated
// ////        touch input not being visible at the event level -- which leaves Touch and Finger slightly unhappy, for example.
// ////        I think being able to cycle simulated input fully through the event loop would result in a setup that is both simpler and more robust.
// ////        Also, it would allow *disabling* the source devices as long as we don't disable them in the backend, too.
// ////        Finally, the fact that we spin off input *from* events here and feed that into InputState.Change() by passing the event along
// ////        means that places that make sure we process input only once (e.g. binding composites which will remember the event ID they have
// ////        been triggered from) may reject the simulated input when they have already seen the non-simulated input (which may be okay
// ////        behavior).
//
// namespace UnityEngine.InputSystem.EnhancedTouch
// {
//     /// <summary>
//     /// Adds a <see cref="Touchscreen"/> with input simulated from other types of <see cref="Pointer"/> devices (e.g. <see cref="Mouse"/>
//     /// or <see cref="Pen"/>).
//     /// </summary>
//     [AddComponentMenu("Input/Debug/Touch Simulation")]
//     [ExecuteInEditMode]
//     [HelpURL(InputSystem.kDocUrl + "/manual/Touch.html#touch-simulation")]
//     #if UNITY_EDITOR
//     [InitializeOnLoad]
//     #endif
//     public class TouchSimulation : MonoBehaviour, IInputStateChangeMonitor
//     {
//         public Touchscreen simulatedTouchscreen { get; private set; }
//
//         public static TouchSimulation instance => s_Instance;
//
//         public static void Enable()
//         {
//             if (instance == null)
//             {
//                 ////TODO: find instance
/...

@u-pr
Copy link
Contributor

u-pr bot commented Jan 30, 2026

PR Code Suggestions ✨


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

@codecov-github-com
Copy link

codecov-github-com bot commented Jan 30, 2026

Codecov Report

Attention: Patch coverage is 17.98942% with 155 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../Actions/Interactions/MultiTapInteractionEditor.cs 0.00% 23 Missing ⚠️
...tor/Actions/Interactions/PressInteractionEditor.cs 0.00% 18 Missing ⚠️
...Controls/Processors/AxisDeadzoneProcessorEditor.cs 0.00% 14 Missing ⚠️
...ontrols/Processors/StickDeadzoneProcessorEditor.cs 0.00% 14 Missing ⚠️
...r/Actions/Interactions/SlowTapInteractionEditor.cs 0.00% 13 Missing ⚠️
...ditor/Actions/Interactions/TapInteractionEditor.cs 0.00% 13 Missing ⚠️
Assets/Tests/InputSystem/CoreTests_Editor.cs 42.85% 12 Missing ⚠️
...itor/Actions/Interactions/HoldInteractionEditor.cs 0.00% 12 Missing ⚠️
...m/Editor/Actions/Composites/AxisCompositeEditor.cs 0.00% 11 Missing ⚠️
...ditor/Actions/Composites/Vector2CompositeEditor.cs 0.00% 11 Missing ⚠️
... and 4 more
@@             Coverage Diff             @@
##           develop    #2321      +/-   ##
===========================================
- Coverage    77.95%   74.63%   -3.33%     
===========================================
  Files          476      856     +380     
  Lines        97453   150083   +52630     
===========================================
+ Hits         75971   112016   +36045     
- Misses       21482    38067   +16585     
Flag Coverage Δ
inputsystem_MacOS_2022.3_project 74.28% <17.98%> (-1.19%) ⬇️
inputsystem_MacOS_6000.0_project 76.23% <17.98%> (-1.13%) ⬇️
inputsystem_MacOS_6000.3_project 76.23% <17.98%> (-1.13%) ⬇️
inputsystem_MacOS_6000.4_project 76.24% <17.98%> (-1.13%) ⬇️
inputsystem_MacOS_6000.5_project 76.25% <17.98%> (-1.12%) ⬇️
inputsystem_Ubuntu_2022.3_project 74.08% <17.98%> (-1.19%) ⬇️
inputsystem_Ubuntu_6000.0_project 76.02% <17.98%> (-1.14%) ⬇️
inputsystem_Ubuntu_6000.3_project 76.03% <17.98%> (-1.14%) ⬇️
inputsystem_Ubuntu_6000.4_project 76.04% <17.98%> (-1.14%) ⬇️
inputsystem_Ubuntu_6000.5_project 76.04% <17.98%> (-1.14%) ⬇️
inputsystem_Windows_2022.3_project 74.42% <17.98%> (-1.18%) ⬇️
inputsystem_Windows_6000.0_project 76.36% <17.98%> (-1.14%) ⬇️
inputsystem_Windows_6000.3_project 76.36% <17.98%> (-1.13%) ⬇️
inputsystem_Windows_6000.4_project 76.36% <17.98%> (-1.13%) ⬇️
inputsystem_Windows_6000.5_project 76.36% <17.98%> (-1.13%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
Assets/Tests/InputSystem/APIVerificationTests.cs 90.19% <100.00%> (+0.39%) ⬆️
Assets/Tests/InputSystem/CoreTests_Analytics.cs 99.36% <ø> (-0.01%) ⬇️
...ts/Tests/InputSystem/Plugins/EnhancedTouchTests.cs 100.00% <ø> (ø)
Assets/Tests/InputSystem/Plugins/UITests.cs 94.33% <ø> (-0.35%) ⬇️
...tor/Analytics/InputActionsEditorSessionAnalytic.cs 85.32% <ø> (ø)
...inputsystem/Editor/Analytics/InputBuildAnalytic.cs 77.52% <ø> (ø)
...m/Editor/Analytics/InputComponentEditorAnalytic.cs 100.00% <ø> (ø)
...putsystem/Editor/Analytics/InputEditorAnalytics.cs 50.00% <ø> (ø)
...stem/Editor/Analytics/InputExitPlayModeAnalytic.cs 82.69% <ø> (ø)
...em/Editor/Analytics/OnScreenStickEditorAnalytic.cs 73.33% <ø> (ø)
... and 47 more

... and 368 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@josepmariapujol-unity josepmariapujol-unity marked this pull request as draft January 30, 2026 14:26
Some files were moved to other folders, after merging conflicts arise but since they showed as removed changes didn't land on the moved files. This commit is fixing this
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.

3 participants