I create a very simple input with a trigger behaviour of “Release only**” but it triggers once when the key is pressed and another time when it’s released**. The button is behaving exactly like in “Press and Release” mode.
public void OnTest(InputAction.CallbackContext context)
{
// if (context.performed == false) return; // adding this line removes the call when the key is pressed. This fixes the problem.
Debug.Log("Test called!");
}
Although, performing a manual check allows to fetch the state prior to the next event.
E.g. if you have a “Hold”, you’ll be able to get an initial “Press” position as well.
You need to check the Callbackcontext values. The event will be triggered 2 times. First after the button crosses the presspoint with context.started = true and context.performed = false. The second time with context.started = false and context.performed = true.
In your case, do this in your event handler: if(context.performed) {…your code…}
context.performed can only appear on the left hand side of -= or += operators. You cannot check against this variable within an if statement, see below screenshot.
I’ve spent the best part of this Sunday trying to solve this problem and it would seem there are no successful work around. There’s talk about setting a boolean to turn on and off flow of logic but I’ve failed to get this working when relying directly from the new input system data. It’s subscribing directly into input and if this is the value you’re relying on despite what logic you have coded in place, it’s going to be unpredictable and therefor unreliable.
Anyway, I screen recorded the code and behavior within the Unity Editor. Using the bottom window you’ll see the print() messages reporting the jump event firing. Sometimes it’s twice at once, sometimes it’s once as wanted.
Additionally whilst i’m here like, the following lambda expression statement is unreachable. This is true for placing in the Awake() and Update() methods.
_inputActions.PlayerControls.Attack.performed += var => _attack = var.ReadValue<float>();
{
// This is a GetKeyDown()
// Your operations go here
_atkKeyDwn = true;
_atkKeyUp = false;
//_state.SetState(PlayerStateData.CurrentState.HoldAttack);
};
_inputActions.PlayerControls.Attack.canceled += var => _attack = var.ReadValue<float>();
{
// This is a GetKeyUp()
// Your operations go here
_atkKeyUp = true;
_atkKeyDwn = false;
//_state.SetState(PlayerStateData.CurrentState.ReleaseAttack);
};
However the _attack variable will reliably be reachable and be fed in the data from input. This is the problem though because this one variable we have to rely on is giving duplicate readings.
The screen recording can be found here. I have nothing else to add, i’m out of problem solving today.
Edit
Falling back onto my Rewired asset, this behavior still happens with hit the SPC button for jumping. lool
So while this is probably the easiest way to handle this, every time update your inputs it will be overwritten.
Theoretically the “PassThrough” type seems like a better fix - setting the Action to PassThrough > Button, since according to documentation it will only fire once
But I can’t get it to work that way for the life of me.
FWIW, I’m finding that if I use “Send Messages” as my behavior under the Player Input component, things only trigger once. If I use Invoke Unity Events as the behavior, I get triple executions with every button press.
Can I just take a second and voice my frustration with this?
You’ve got a setting for “press only”, and it fires off the event 3 different times. Surely this isn’t as designed? We have to write custom bool operations, bloating our code, to simply get a button to fire only once when it’s pressed?
This is pretty ridiculous, Unity. It shouldn’t be anywhere near this complicated to make the absolute MOST basic controller interaction in a game possible.
Get some basic level coders to sit down in front of you, try to use your tools, and watch them. When they stumble on things like this… it has to be a priority.
I am very new to Unity and have no solutions or anything, but I wanted to agree wholeheartedly with this post. I’ve been trying for a while now to make the “Press only” unity event option work as it’s advertised, but whatever I do it’s still doing stuff on release.
I already spent a day trying to make stick deadzone’s processor to work… I’m not going to start again with interactions.
I added a press only interaction on my RightTrigger action and still, it fires the callback on release.
Is there any Unity dev that could tell us what’s going on with those InputActions properties not working ?
Sure, it’s a preview package, but this thread started almost a year ago…
This is driving me nuts. Buf found some usefull info:
if I do
if (context.phase == InputActionPhase.Canceled)
{
Debug.Log(gameObject.name);
}
I got a Player log and a Player(Clone) log
I need to add my script to the player prefab in which the Player Input resides (the one the player input manager component uses).
Is there any workaround? or is there something I missed?
Ok so your comments have been really helpful, thanks yall.
In the end the easiest solution I found is simply to disregard the context.performed value and use an if check on the started and canceled values, like so: