public void Actions_CanPerformHoldInteraction() { var gamepad = InputSystem.AddDevice <Gamepad>(); var action = new InputAction(binding: "<Gamepad>/{primaryAction}", interactions: "hold(duration=0.4)"); action.Enable(); using (var trace = new InputActionTrace(action)) { // Press. Press(gamepad.buttonSouth, time: 10); Assert.That(trace, Started <HoldInteraction>(action, gamepad.buttonSouth, time: 10, value: 1.0)); Assert.That(action.ReadValue <float>(), Is.EqualTo(1)); Assert.That(action.phase, Is.EqualTo(InputActionPhase.Started)); trace.Clear(); // Release in less than hold time. Release(gamepad.buttonSouth, time: 10.25); Assert.That(trace, Canceled <HoldInteraction>(action, gamepad.buttonSouth, duration: 0.25, time: 10.25, value: 0.0)); Assert.That(action.phase, Is.EqualTo(InputActionPhase.Waiting)); Assert.That(action.ReadValue <float>(), Is.Zero); trace.Clear(); // Press again. Press(gamepad.buttonSouth, time: 10.5); Assert.That(trace, Started <HoldInteraction>(action, gamepad.buttonSouth, time: 10.5, value: 1.0)); Assert.That(action.ReadValue <float>(), Is.EqualTo(1)); Assert.That(action.phase, Is.EqualTo(InputActionPhase.Started)); trace.Clear(); // Let time pass but stay under hold time. currentTime = 10.75; InputSystem.Update(); Assert.That(trace, Is.Empty); // Now exceed hold time. Make sure action performs and *stays* performed. currentTime = 11; InputSystem.Update(); Assert.That(trace, Performed <HoldInteraction>(action, gamepad.buttonSouth, time: 11, duration: 0.5, value: 1.0)); Assert.That(action.phase, Is.EqualTo(InputActionPhase.Performed)); Assert.That(action.ReadValue <float>(), Is.EqualTo(1)); trace.Clear(); // Release button. Release(gamepad.buttonSouth, time: 11.5); Assert.That(trace, Canceled <HoldInteraction>(action, gamepad.buttonSouth, time: 11.5, duration: 1, value: 0.0)); } }
public void Actions_CanCustomizeButtonPressPointsOfInteractions() { var gamepad = InputSystem.AddDevice <Gamepad>(); var pressAction = new InputAction("PressAction", binding: "<Gamepad>/leftTrigger", interactions: "press(pressPoint=0.234)"); var tapAction = new InputAction("TapAction", binding: "<Gamepad>/leftTrigger", interactions: "tap(pressPoint=0.345)"); var slowTapAction = new InputAction("SlowTapAction", binding: "<Gamepad>/leftTrigger", interactions: "slowtap(pressPoint=0.456)"); var multiTapAction = new InputAction("MultiTapAction", binding: "<Gamepad>/leftTrigger", interactions: "multitap(pressPoint=0.567)"); var holdAction = new InputAction("HoldAction", binding: "<Gamepad>/leftTrigger", interactions: "hold(pressPoint=0.678)"); pressAction.Enable(); tapAction.Enable(); slowTapAction.Enable(); multiTapAction.Enable(); holdAction.Enable(); // Render the global default inactive. InputSystem.settings.defaultButtonPressPoint = 0; using (var trace = new InputActionTrace()) { trace.SubscribeToAll(); Set(gamepad.leftTrigger, 0.123f); Assert.That(trace, Started <PressInteraction>(pressAction)); trace.Clear(); Set(gamepad.leftTrigger, 0.3f); Assert.That(trace, Performed <PressInteraction>(pressAction)); trace.Clear(); Set(gamepad.leftTrigger, 0.4f); Assert.That(trace, Started <TapInteraction>(tapAction)); trace.Clear(); Set(gamepad.leftTrigger, 0.5f); Assert.That(trace, Started <SlowTapInteraction>(slowTapAction)); trace.Clear(); Set(gamepad.leftTrigger, 0.6f); Assert.That(trace, Started <MultiTapInteraction>(multiTapAction)); trace.Clear(); Set(gamepad.leftTrigger, 0.7f); Assert.That(trace, Started <HoldInteraction>(holdAction)); } }
public void Actions_WhenTransitionFromOneInteractionToNext_GetCallbacks() { var gamepad = InputSystem.AddDevice <Gamepad>(); var action = new InputAction("test", InputActionType.Button, binding: "<Gamepad>/buttonSouth", interactions: "tap(duration=1),slowTap"); action.Enable(); using (var trace = new InputActionTrace(action)) { Press(gamepad.buttonSouth); Assert.That(trace, Started <TapInteraction>(action, gamepad.buttonSouth, time: 0)); trace.Clear(); // Expire the tap. The system should transitioning from the tap to a slowtap. // Note the starting time of the slowTap will be 0 not 2. runtime.currentTime = 2; InputSystem.Update(); Assert.That(trace, Canceled <TapInteraction>(action, gamepad.buttonSouth) .AndThen(Started <SlowTapInteraction>(action, gamepad.buttonSouth, time: 0))); } }
public void Actions_StartedAndCanceledAreEnforcedImplicitly() { var gamepad = InputSystem.AddDevice <Gamepad>(); InputSystem.RegisterInteraction <InteractionThatOnlyPerforms>(); var action1 = new InputAction(name: "action1", type: InputActionType.Button, binding: "<Gamepad>/buttonSouth", interactions: "interactionThatOnlyPerforms(stayPerformed=true)"); var action2 = new InputAction(name: "action2", type: InputActionType.Button, binding: "<Gamepad>/buttonSouth", interactions: "interactionThatOnlyPerforms(stayPerformed=false)"); var action3 = new InputAction(name: "action3", type: InputActionType.Button, binding: "<Gamepad>/buttonSouth"); var action4 = new InputAction(name: "action4", type: InputActionType.Value, binding: "<Gamepad>/buttonSouth"); // Pass-Through is special (as always). var action5 = new InputAction(name: "action5", type: InputActionType.PassThrough, binding: "<Gamepad>/buttonSouth"); var action6 = new InputAction(name: "action6", type: InputActionType.PassThrough, binding: "<Gamepad>/buttonSouth", interactions: "press"); action1.Enable(); action2.Enable(); action3.Enable(); action4.Enable(); action5.Enable(); action6.Enable(); using (var trace1 = new InputActionTrace(action1)) using (var trace2 = new InputActionTrace(action2)) using (var trace3 = new InputActionTrace(action3)) using (var trace4 = new InputActionTrace(action4)) using (var trace5 = new InputActionTrace(action5)) using (var trace6 = new InputActionTrace(action6)) { Press(gamepad.buttonSouth); Assert.That(trace1, Started(action1).AndThen(Performed(action1))); Assert.That(trace2, Started(action2).AndThen(Performed(action2)).AndThen(Canceled(action2))); Assert.That(trace3, Started(action3).AndThen(Performed(action3))); Assert.That(trace4, Started(action4).AndThen(Performed(action4))); Assert.That(trace5, Performed(action5)); Assert.That(trace6, Started(action6).AndThen(Performed(action6))); trace1.Clear(); trace2.Clear(); trace3.Clear(); trace4.Clear(); trace5.Clear(); trace6.Clear(); Release(gamepad.buttonSouth); Assert.That(trace1, Is.Empty); Assert.That(trace2, Is.Empty); Assert.That(trace3, Canceled(action3)); Assert.That(trace4, Canceled(action4)); Assert.That(trace5, Performed(action5)); // Any value change performs. Assert.That(trace6, Canceled(action6)); } }
public void Actions_ReleasedHoldInteractionIsCancelled_WithMultipleBindings() { var keyboard = InputSystem.AddDevice <Keyboard>(); var action = new InputAction(binding: "<Keyboard>/space", interactions: "hold(duration=0.4)"); action.AddBinding("<Keyboard>/s"); action.Enable(); using (var trace = new InputActionTrace(action)) { // Press and hold. Press(keyboard.spaceKey, time: 10); Assert.That(trace, Started <HoldInteraction>(action, keyboard.spaceKey, time: 10, value: 1.0)); Assert.That(action.ReadValue <float>(), Is.EqualTo(1)); Assert.That(action.phase, Is.EqualTo(InputActionPhase.Started)); trace.Clear(); // Exceed hold time. Make sure action performs and *stays* performed. currentTime = 10.5; InputSystem.Update(); Assert.That(trace, Performed <HoldInteraction>(action, keyboard.spaceKey, time: 10.5, duration: 0.5, value: 1.0)); Assert.That(action.phase, Is.EqualTo(InputActionPhase.Performed)); Assert.That(action.ReadValue <float>(), Is.EqualTo(1)); trace.Clear(); // Release. Release(keyboard.spaceKey, time: 10.6); Assert.That(trace, Canceled <HoldInteraction>(action, keyboard.spaceKey, duration: 0.6, time: 10.6, value: 0.0)); Assert.That(action.phase, Is.EqualTo(InputActionPhase.Waiting)); Assert.That(action.ReadValue <float>(), Is.Zero); } }
public void Actions_CanPerformPressInteraction_UsingReleasePointWhenBoundToAxisControl() { var gamepad = InputSystem.AddDevice <Gamepad>(); InputSystem.settings.defaultButtonPressPoint = 0.5f; InputSystem.settings.buttonReleaseThreshold = 0.75f; // Puts release point at 0.375. var action = new InputAction(binding: "<Gamepad>/leftTrigger", interactions: "press"); action.Enable(); using (var trace = new InputActionTrace(action)) { Set(gamepad.leftTrigger, 0.35f); Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.35f)); trace.Clear(); Set(gamepad.leftTrigger, 0.5f); Assert.That(trace, Performed(action, control: gamepad.leftTrigger, value: 0.5f)); trace.Clear(); Set(gamepad.leftTrigger, 0.6f); Assert.That(trace, Is.Empty); Set(gamepad.leftTrigger, 0.4f); Assert.That(trace, Is.Empty); Set(gamepad.leftTrigger, 0.3f); Assert.That(trace, Canceled(action, control: gamepad.leftTrigger, value: 0f)); } }
public void Update() { foreach (var eventPtr in m_ActionTrace) { var phase = eventPtr.phase; var action = eventPtr.action; if (action == controls.gameplay.fire) { var interaction = eventPtr.interaction; switch (phase) { case InputActionPhase.Performed: if (interaction is SlowTapInteraction) { StartCoroutine(BurstFire((int)(eventPtr.duration * burstSpeed))); } else { Fire(); } m_Charging = false; break; case InputActionPhase.Started: if (interaction is SlowTapInteraction) { m_Charging = true; } break; case InputActionPhase.Canceled: m_Charging = false; break; } } else if (action == controls.gameplay.look) { m_Look = eventPtr.ReadValue <Vector2>(); } else if (action == controls.gameplay.move) { m_Move = eventPtr.ReadValue <Vector2>(); } } m_ActionTrace.Clear(); Move(m_Move); Look(m_Look); }
public void Actions_CanPerformDoubleTapInteraction() { var gamepad = InputSystem.AddDevice <Gamepad>(); runtime.advanceTimeEachDynamicUpdate = 0; var action = new InputAction(binding: "<Gamepad>/buttonSouth", interactions: "multitap(tapTime=0.5,tapDelay=0.75,tapCount=2)"); action.Enable(); using (var trace = new InputActionTrace()) { trace.SubscribeTo(action); // Press button. runtime.currentTime = 1; InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South), 1); InputSystem.Update(); var actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(1)); Assert.That(actions[0].phase, Is.EqualTo(InputActionPhase.Started)); Assert.That(actions[0].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[0].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[0].time, Is.EqualTo(1).Within(0.00001)); trace.Clear(); // Release before tap time and make sure the double tap cancels. runtime.currentTime = 12; InputSystem.QueueStateEvent(gamepad, new GamepadState(), 1.75); InputSystem.Update(); actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(1)); Assert.That(actions[0].phase, Is.EqualTo(InputActionPhase.Canceled)); Assert.That(actions[0].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[0].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[0].time, Is.EqualTo(1.75).Within(0.00001)); trace.Clear(); // Press again and then release before tap time. Should see only the start from // the initial press. runtime.currentTime = 2.5; InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South), 2); InputSystem.QueueStateEvent(gamepad, new GamepadState(), 2.25); InputSystem.Update(); actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(1)); Assert.That(actions[0].phase, Is.EqualTo(InputActionPhase.Started)); Assert.That(actions[0].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[0].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[0].time, Is.EqualTo(2).Within(0.00001)); Assert.That(actions[0].ReadValue <float>(), Is.EqualTo(1).Within(0.00001)); trace.Clear(); // Wait for longer than tapDelay and make sure we're seeing a cancellation. runtime.currentTime = 4; InputSystem.Update(); actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(1)); Assert.That(actions[0].phase, Is.EqualTo(InputActionPhase.Canceled)); Assert.That(actions[0].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[0].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[0].time, Is.EqualTo(4).Within(0.00001)); Assert.That(actions[0].ReadValue <float>(), Is.EqualTo(0).Within(0.00001));// Button isn't pressed currently. trace.Clear(); // Now press and release within tap time. Then press again within delay time but release // only after tap time. Should we started and canceled. runtime.currentTime = 6; InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South), 4.7); InputSystem.QueueStateEvent(gamepad, new GamepadState(), 4.9); InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South), 5); InputSystem.QueueStateEvent(gamepad, new GamepadState(), 5.9); InputSystem.Update(); actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(2)); Assert.That(actions[0].phase, Is.EqualTo(InputActionPhase.Started)); Assert.That(actions[0].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[0].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[0].time, Is.EqualTo(4.7).Within(0.00001)); Assert.That(actions[0].ReadValue <float>(), Is.EqualTo(1).Within(0.00001)); Assert.That(actions[1].phase, Is.EqualTo(InputActionPhase.Canceled)); Assert.That(actions[1].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[1].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[1].time, Is.EqualTo(5.9).Within(0.00001)); Assert.That(actions[1].ReadValue <float>(), Is.EqualTo(0).Within(0.00001)); trace.Clear(); // Finally perform a full, proper double tap cycle. runtime.currentTime = 8; InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South), 7); InputSystem.QueueStateEvent(gamepad, new GamepadState(), 7.25); InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South), 7.5); InputSystem.QueueStateEvent(gamepad, new GamepadState(), 7.75); InputSystem.Update(); actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(2)); Assert.That(actions[0].phase, Is.EqualTo(InputActionPhase.Started)); Assert.That(actions[0].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[0].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[0].time, Is.EqualTo(7).Within(0.00001)); Assert.That(actions[0].ReadValue <float>(), Is.EqualTo(1).Within(0.00001)); Assert.That(actions[1].phase, Is.EqualTo(InputActionPhase.Performed)); Assert.That(actions[1].interaction, Is.TypeOf <MultiTapInteraction>()); Assert.That(actions[1].control, Is.SameAs(gamepad.buttonSouth)); Assert.That(actions[1].time, Is.EqualTo(7.75).Within(0.00001)); Assert.That(actions[1].ReadValue <float>(), Is.Zero.Within(0.00001)); } }
public void Actions_CanPerformPressInteraction() { var gamepad = InputSystem.AddDevice <Gamepad>(); // We add a second input device (and bind to it), to test that the binding // conflict resolution will not interfere with the interaction handling. InputSystem.AddDevice <Keyboard>(); // Test all three press behaviors concurrently. var pressOnlyAction = new InputAction("PressOnly", binding: "<Gamepad>/buttonSouth", interactions: "press(behavior=0)"); pressOnlyAction.AddBinding("<Keyboard>/a"); var releaseOnlyAction = new InputAction("ReleaseOnly", binding: "<Gamepad>/buttonSouth", interactions: "press(behavior=1)"); releaseOnlyAction.AddBinding("<Keyboard>/s"); var pressAndReleaseAction = new InputAction("PressAndRelease", binding: "<Gamepad>/buttonSouth", interactions: "press(behavior=2)"); pressAndReleaseAction.AddBinding("<Keyboard>/d"); pressOnlyAction.Enable(); releaseOnlyAction.Enable(); pressAndReleaseAction.Enable(); using (var pressOnly = new InputActionTrace(pressOnlyAction)) using (var releaseOnly = new InputActionTrace(releaseOnlyAction)) using (var pressAndRelease = new InputActionTrace(pressAndReleaseAction)) { runtime.currentTime = 1; Press(gamepad.buttonSouth); Assert.That(pressOnly, Started <PressInteraction>(pressOnlyAction, gamepad.buttonSouth, value: 1.0, time: 1) .AndThen(Performed <PressInteraction>(pressOnlyAction, gamepad.buttonSouth, time: 1, duration: 0, value: 1.0))); Assert.That(releaseOnly, Started <PressInteraction>(releaseOnlyAction, gamepad.buttonSouth, time: 1, value: 1.0)); Assert.That(pressAndRelease, Started <PressInteraction>(pressAndReleaseAction, gamepad.buttonSouth, time: 1, value: 1.0) .AndThen(Performed <PressInteraction>(pressAndReleaseAction, gamepad.buttonSouth, time: 1, duration: 0, value: 1.0))); pressOnly.Clear(); releaseOnly.Clear(); pressAndRelease.Clear(); runtime.currentTime = 2; Release(gamepad.buttonSouth); Assert.That(pressOnly, Canceled <PressInteraction>(pressOnlyAction, gamepad.buttonSouth, value: 0.0, time: 2, duration: 1)); Assert.That(releaseOnly, Performed <PressInteraction>(releaseOnlyAction, gamepad.buttonSouth, value: 0.0, time: 2, duration: 1) .AndThen(Canceled <PressInteraction>(releaseOnlyAction, gamepad.buttonSouth, value: 0.0, time: 2, duration: 1))); Assert.That(pressAndRelease, Performed <PressInteraction>(pressAndReleaseAction, gamepad.buttonSouth, value: 0.0, time: 2, duration: 1) .AndThen(Canceled <PressInteraction>(pressAndReleaseAction, gamepad.buttonSouth, value: 0.0, time: 2, duration: 1))); pressOnly.Clear(); releaseOnly.Clear(); pressAndRelease.Clear(); runtime.currentTime = 5; Press(gamepad.buttonSouth); Assert.That(pressOnly, Started <PressInteraction>(pressOnlyAction, gamepad.buttonSouth, value: 1.0, time: 5) .AndThen(Performed <PressInteraction>(pressOnlyAction, gamepad.buttonSouth, time: 5, duration: 0, value: 1.0))); Assert.That(releaseOnly, Started <PressInteraction>(releaseOnlyAction, gamepad.buttonSouth, time: 5, value: 1.0)); Assert.That(pressAndRelease, Started <PressInteraction>(pressAndReleaseAction, gamepad.buttonSouth, time: 5, value: 1.0) .AndThen(Performed <PressInteraction>(pressAndReleaseAction, gamepad.buttonSouth, time: 5, duration: 0, value: 1.0))); } }
public void Actions_CanPerformPressInteraction() { var gamepad = InputSystem.AddDevice <Gamepad>(); // We add a second input device (and bind to it), to test that the binding // conflict resolution will not interfere with the interaction handling. InputSystem.AddDevice <Keyboard>(); // Test all three press behaviors concurrently. var pressOnlyAction = new InputAction("PressOnly", binding: "<Gamepad>/buttonSouth", interactions: "press"); pressOnlyAction.AddBinding("<Keyboard>/a"); var releaseOnlyAction = new InputAction("ReleaseOnly", binding: "<Gamepad>/buttonSouth", interactions: "press(behavior=1)"); releaseOnlyAction.AddBinding("<Keyboard>/s"); var pressAndReleaseAction = new InputAction("PressAndRelease", binding: "<Gamepad>/buttonSouth", interactions: "press(behavior=2)"); pressAndReleaseAction.AddBinding("<Keyboard>/d"); pressOnlyAction.Enable(); releaseOnlyAction.Enable(); pressAndReleaseAction.Enable(); using (var trace = new InputActionTrace()) { trace.SubscribeToAll(); runtime.currentTime = 1; Press(gamepad.buttonSouth); var actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(5)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressOnlyAction).And.With.Property("phase") .EqualTo(InputActionPhase.Started).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressOnlyAction).And.With.Property("phase") .EqualTo(InputActionPhase.Performed).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressAndReleaseAction).And.With.Property("phase") .EqualTo(InputActionPhase.Started).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressAndReleaseAction).And.With.Property("phase") .EqualTo(InputActionPhase.Performed).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(releaseOnlyAction).And.With.Property("phase") .EqualTo(InputActionPhase.Started).And.With.Property("duration") .EqualTo(0)); trace.Clear(); runtime.currentTime = 2; Release(gamepad.buttonSouth); actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(3)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(releaseOnlyAction).And.With.Property("phase") .EqualTo(InputActionPhase.Performed).And.With.Property("duration") .EqualTo(1)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressAndReleaseAction).And.With.Property("phase") .EqualTo(InputActionPhase.Started).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressAndReleaseAction).And.With.Property("phase") .EqualTo(InputActionPhase.Performed).And.With.Property("duration") .EqualTo(0)); trace.Clear(); runtime.currentTime = 5; Press(gamepad.buttonSouth); actions = trace.ToArray(); Assert.That(actions, Has.Length.EqualTo(5)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressOnlyAction).And.With.Property("phase") .EqualTo(InputActionPhase.Started).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressOnlyAction).And.With.Property("phase") .EqualTo(InputActionPhase.Performed).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressAndReleaseAction).And.With.Property("phase") .EqualTo(InputActionPhase.Started).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(pressAndReleaseAction).And.With.Property("phase") .EqualTo(InputActionPhase.Performed).And.With.Property("duration") .EqualTo(0)); Assert.That(actions, Has.Exactly(1).With.Property("action").SameAs(releaseOnlyAction).And.With.Property("phase") .EqualTo(InputActionPhase.Started).And.With.Property("duration") .EqualTo(0)); } }
public void StartedValidSweepBehavior(SectorInteraction.SweepBehavior sweepBehavior) { var gamepad = InputSystem.InputSystem.AddDevice <Gamepad>(); var action = new InputAction( type: InputActionType.Value, binding: "<Gamepad>/rightStick", interactions: CreateInteractionString(SectorInteraction.Directions.North, sweepBehavior)); action.Enable(); var north = new Vector2(0f, 1f); var east = new Vector2(1f, 0f); var center = Vector2.zero; // Starting below threshold Assert.That(gamepad.rightStick.IsActuated(), Is.False); Assert.That(action.triggered, Is.False); using (var trace = new InputActionTrace()) { trace.SubscribeToAll(); // Actuate above threshold, in valid sector Set(gamepad.rightStick, north); Assert.That(gamepad.rightStick.IsActuated(), Is.True); Assert.That(trace, Started <SectorInteraction>(action).AndThen(Performed <SectorInteraction>(action))); Assert.That(action.triggered, Is.True); trace.Clear(); // Sweep to invalid sector Set(gamepad.rightStick, east); Assert.That(gamepad.rightStick.IsActuated(), Is.True); switch (sweepBehavior) { case SectorInteraction.SweepBehavior.Locked: Assert.That(trace, Is.Empty); break; case SectorInteraction.SweepBehavior.AllowReentry: case SectorInteraction.SweepBehavior.DisallowReentry: case SectorInteraction.SweepBehavior.HistoryIndependent: Assert.That(trace, Canceled <SectorInteraction>(action)); break; default: Assert.Fail($"Unhandled {nameof(SectorInteraction.SweepBehavior)}={sweepBehavior}"); return; } Assert.That(action.triggered, Is.False); trace.Clear(); // Sweep back into valid sector Set(gamepad.rightStick, north); Assert.That(gamepad.rightStick.IsActuated(), Is.True); switch (sweepBehavior) { case SectorInteraction.SweepBehavior.Locked: case SectorInteraction.SweepBehavior.DisallowReentry: Assert.That(trace, Is.Empty); Assert.That(action.triggered, Is.False); break; case SectorInteraction.SweepBehavior.AllowReentry: case SectorInteraction.SweepBehavior.HistoryIndependent: Assert.That(trace, Started <SectorInteraction>(action).AndThen(Performed <SectorInteraction>(action))); Assert.That(action.triggered, Is.True); break; default: Assert.Fail($"Unhandled {nameof(SectorInteraction.SweepBehavior)}={sweepBehavior}"); return; } trace.Clear(); // Return to center, under threshold Set(gamepad.rightStick, center); Assert.That(gamepad.rightStick.IsActuated(), Is.False); Assert.That(trace, Canceled <SectorInteraction>(action)); Assert.That(action.triggered, Is.False); } }