Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Warp Cursor Position Breaks Input Test Fixture

Discussion in 'Input System' started by hedberggames, Nov 20, 2020.

  1. hedberggames

    hedberggames

    Joined:
    Jan 11, 2019
    Posts:
    6
    I'm trying to test my code using the InputTestFixture, but I can't figure out how to accurately move the cursor after the application warps the mouse position. Ordinarily, I move the mouse based on its previous position:
    Code (CSharp):
    1. public void Move(Vector2 delta)
    2. {
    3.     var previousPosition = mouse.position.ReadValue();
    4.     testFixture.Move(mouse.position, previousPosition + delta);
    5. }
    This, of course, does not work when the application warps the cursor, since the position is not updated by the warp command. According to the documentation, the position "will update in the next input update", but I am not seeing that happen in my tests.

    Here is a simple example to show what I mean:
    Code (CSharp):
    1. public class ExampleTest : InputTestFixture
    2. {
    3.     [Test]
    4.     public void MouseWarpShouldUpdatePosition()
    5.     {
    6.         var mouse = InputSystem.AddDevice<Mouse>();
    7.         var expected = new Vector2(10, 10);
    8.  
    9.         //In a real test, this would be a call into application code that itself calls WarpCursorPosition
    10.         mouse.WarpCursorPosition(expected);
    11.  
    12.         //Trying to force the "next input update"
    13.         InputSystem.Update();
    14.         var actual = mouse.position.ReadValue();
    15.        
    16.         //This assert fails: expected is 10,10 but actual is 0,0
    17.         Assert.AreEqual(expected, actual);
    18.     }
    19. }
    I also tried a few other methods to try to force an update of the input system (waiting a frame or sending other, unrelated inputs) but none of them worked. The phrasing in the documentation sounds like there should be something my test can do to wait for the position to be updated, but I can't figure out what that is.

    Am I missing something here? How am I supposed to use the Input Test Fixture after the application warps the cursor position?
     
    rboerdijk likes this.
  2. rboerdijk

    rboerdijk

    Joined:
    Aug 4, 2018
    Posts:
    96
    I cobbled together this little "pearl of wisdom" for manipulating the mouseposition, maybe you can get it to work in your situation too. Looking at the below code I have many thoughts but I'll refrain from further commenting on it.

    Code (CSharp):
    1. private void MousePositioning()
    2. {
    3.     Vector3 mousepos = Camera.main.WorldToScreenPoint( SomePositionInWorldSpace ); // 3D worldpos into 2D
    4.     // 'feature' workaround: https://forum.unity.com/threads/inputsystem-reporting-wrong-mouse-position-after-warpcursorposition.929019/
    5.     InputSystem.QueueDeltaStateEvent(Mouse.current.position,  (Vector2)mousepos);   // required 8 bytes, not 12!
    6.     //InputState.Change(Mouse.current.position, (Vector2)mousepos);
    7. #if !UNITY_EDITOR
    8.         // bug workaround : https://forum.unity.com/threads/mouse-y-position-inverted-in-build-using-mouse-current-warpcursorposition.682627/#post-5387577
    9.         mousepos.Set(mousepos.x, Screen.height - mousepos.y, mousepos.z);
    10. #endif
    11.     Mouse.current.WarpCursorPosition(mousepos);
    12. }
     
    Last edited: Dec 16, 2020
    kuom and unity_96peregon like this.
  3. kuom

    kuom

    Joined:
    Nov 12, 2013
    Posts:
    3
    You are AWESOME!!!
    This Pearl of Wisdom just saved me!
    Thank you Sensei rboerdijk
     
    rboerdijk likes this.