2

I'm busy working on a game where the player can attack by clicking the left mouse button. I have a InputManager class that will check the input events and then invoke a UnityEvent. This is all working while playing the game. But I'm struggling to simulate mouse events in my tests. Here's the test:

[Test]
public void MouseAttackTest()
{
    var attacked = false;
    var inputManagerObject = new GameObject();
    var inputManager = inputManagerObject.AddComponent<InputManager>();
    inputManager.OnAttack.AddListener(() => attacked = true);

    var mouse = InputSystem.AddDevice<Mouse>();
    using (StateEvent.From(mouse, out var eventPtr))
    {
        mouse.leftButton.WriteValueIntoEvent(true, eventPtr); // Fails on this line
        InputSystem.QueueEvent(eventPtr);
    }

    Assert.IsTrue(attacked);
}

And here's the output:

MouseAttackTest (0,091s)
---
System.ArgumentException : Expecting control of type 'Boolean' but got 'ButtonControl'
---
at UnityEngine.InputSystem.InputControlExtensions.WriteValueIntoEvent[TValue] (UnityEngine.InputSystem.InputControl control, TValue value, UnityEngine.InputSystem.LowLevel.InputEventPtr eventPtr) [0x0003f] in C:\Dev\Game\Library\PackageCache\com.unity.inputsystem@1.0.2\InputSystem\Controls\InputControlExtensions.cs:369 
  at Game.Tests.Play.InputSystemTests.MouseAttackTest () [0x00046] in C:\Dev\Game\Assets\Scripts\Tests\Play\InputSystemTests.cs:24 
  at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <9577ac7a62ef43179789031239ba8798>:0

I tried to search for examples online, but there's no real examples or even proper documentation. Any ideas on how I can simulate these events?

Blue
  • 820
  • 4
  • 17
  • I'm on mobile so can't type up a formal answer. I did find this [thread](https://stackoverflow.com/questions/46198428/generate-clickmousebutton0-anywhere-on-display) which might help you. It is similar to the answer I would have given. If this doesn't work I can provide a different answer a bit later – TEEBQNE Apr 10 '21 at 19:33
  • @TEEBQNE No unfortunately that won't work. That is using the old input system. And that is to detect a click on any object. Not really how to force/simulate a click during a test –  Apr 10 '21 at 19:35
  • Sorry about that completely missed that. – TEEBQNE Apr 10 '21 at 19:39
  • Hey! I was doing some reading into the [new docs](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Testing.html), and found a page that might be of help to you. Not sure if you are still having this issue, but thought i'd drop it here just in case. There is some unit testing near the middle of the page for examples. There is also the [Github](https://github.com/Unity-Technologies/InputSystem/tree/stable/Assets/Tests/InputSystem) with tests for the input system. Hope this helps a bit. – TEEBQNE Apr 20 '21 at 21:38
  • I think ButtonControl objects send floats. Try replacing "true" with "1f" and let us know. – Stevens Miller Nov 27 '21 at 22:38

1 Answers1

0

Below codes should work, post an answer for followers.

((ButtonControl)mouse.leftButton).WriteValueIntoEvent(1f, eventPtr);

Change to '1f' works for me.

Sheng
  • 71
  • 1
  • 6