Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions Assets/Tests/InputSystem/CoreTests_Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2802,6 +2802,46 @@ public void Actions_ControlsUpdateWhenDeviceIsRemoved()
Assert.That(action.controls, Has.Count.Zero);
}

[Test]
[Category("Actions")]
public void Actions_ActionListenerWillNotThrowWhenDeviceIsRemoved()
{
var gamepad = InputSystem.AddDevice<Gamepad>();

float triggerValue = 0.0f;
bool canceled = false;
bool performed = false;
var action = new InputAction();
action.AddBinding("<Gamepad>/leftTrigger");

action.canceled += ctx =>
{
canceled = true;
triggerValue = ctx.ReadValue<float>();
};

action.started += ctx =>
{
performed = true;
triggerValue = ctx.ReadValue<float>();
};
action.Enable();

InputSystem.QueueStateEvent(gamepad, new GamepadState {leftTrigger = 1.0f});
InputSystem.Update();

Assert.That(triggerValue, Is.EqualTo(1.0f));
Assert.That(performed, Is.True);
Assert.That(canceled, Is.False);
performed = false;

InputSystem.RemoveDevice(gamepad);

Assert.That(triggerValue, Is.EqualTo(0.0f));
Assert.That(performed, Is.False);
Assert.That(canceled, Is.True);
}

[Test]
[Category("Actions")]
public void Actions_ControlsUpdateWhenDeviceIsRemoved_WhileActionIsDisabled()
Expand Down
54 changes: 54 additions & 0 deletions Assets/Tests/InputSystem/CoreTests_Actions_Interactions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using UnityEngine.InputSystem.Interactions;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Scripting;

internal partial class CoreTests
{
Expand Down Expand Up @@ -485,4 +486,57 @@ public void Actions_CanCustomizeButtonPressPointsOfInteractions()
Assert.That(trace, Started<HoldInteraction>(holdAction));
}
}

[Preserve]
private class CancelingTestInteraction : IInputInteraction
{
public void Process(ref InputInteractionContext context)
{
if (context.ControlIsActuated())
{
context.Performed();
context.Canceled();
}
}

public void Reset()
{
}
}

[Test]
[Category("Actions")]
public void Actions_ValueIsDefaultWhenActionIsCanceled()
{
InputSystem.RegisterInteraction<CancelingTestInteraction>();

var gamepad = InputSystem.AddDevice<Gamepad>();

var action = new InputAction("test", binding: "<Gamepad>/leftTrigger", interactions: "CancelingTest");
int performedCount = 0;
float performedValue = -1;
action.performed += ctx =>
{
performedValue = ctx.ReadValue<float>();
performedCount++;
};

int canceledCount = 0;
float canceledValue = -1;
action.canceled += ctx =>
{
canceledValue = ctx.ReadValue<float>();
canceledCount++;
};

action.Enable();

Set(gamepad.leftTrigger, 1.0f);

Assert.That(performedCount, Is.EqualTo(1));
Assert.That(performedValue, Is.EqualTo(1.0));

Assert.That(canceledCount, Is.EqualTo(1));
Assert.That(canceledValue, Is.EqualTo(0.0));
}
}
5 changes: 2 additions & 3 deletions Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -577,9 +577,8 @@ public void PlayerInput_CanAutoSwitchControlSchemesInSinglePlayer_WithDevicePlug
Is.EquivalentTo(new[]
// This looks counter-intuitive but what happens is that when switching from gamepad1 to gamepad2,
// the system will first cancel ongoing actions. So it'll cancel "Move" which, given how PlayerInput
// sends messages, will simply come out as another "Move". And it's still bound to gamepad2's leftStick
// at that point, so the value we record is (0.234,0.345).
{new Message("OnMove", new StickDeadzoneProcessor().Process(new Vector2(0.234f, 0.345f))),
// sends messages, will simply come out as another "Move" with a zero value.
{new Message("OnMove", new StickDeadzoneProcessor().Process(new Vector2(0.0f, 0.0f))),
new Message("OnMove", new StickDeadzoneProcessor().Process(new Vector2(0.345f, 0.456f)))}));
}

Expand Down
1 change: 1 addition & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ however, it has to be formatted properly to pass verification tests.

#### Actions

- Fixed `CallbackContext.ReadValue` throwing when invoked during device removal
- Setting timeouts from `IInputInteraction.Process` not working as expected when processing happened in response to previous timeout expiring (#714).
- Pending timeouts on a device not being removed when device was removed.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ public TValue ReadValue<TValue>()
where TValue : struct
{
var value = default(TValue);
if (m_State != null)
if (m_State != null && phase != InputActionPhase.Canceled)
value = m_State.ReadValue<TValue>(bindingIndex, controlIndex);
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2008,7 +2008,6 @@ internal TValue ReadCompositePartValue<TValue>(int bindingIndex, int partNumber,
var value = ReadValue<TValue>(index, thisControlIndex, ignoreComposites: true);

////REVIEW: not great that we do ButtonControl typechecks all the time even when they are not necessary

if (isFirstValue)
{
result = value;
Expand Down