Search Unity

button trigger behaviour: "release only" triggers twice!?

Discussion in 'Input System' started by FeastSC2, Jul 8, 2019.

  1. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    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.

    Is this a bug?

    upload_2019-7-8_15-33-36.png

    upload_2019-7-8_15-33-53.png

    Here's the code:


    Code (CSharp):
    1.     public void OnTest(InputAction.CallbackContext context)
    2.     {
    3.         // if (context.performed == false) return; // adding this line removes the call when the key is pressed. This fixes the problem.
    4.         Debug.Log("Test called!");
    5.     }
     
    Last edited: Jul 8, 2019
    RSprogramming, pango and xVergilx like this.
  2. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Yeah, it seems like the case (un)fortunately.

    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.
     
    Last edited: Jul 22, 2019
  3. OMGOMGXAXA

    OMGOMGXAXA

    Joined:
    Apr 2, 2016
    Posts:
    10
    Same problem.
     
  4. zhuxianzhi

    zhuxianzhi

    Joined:
    Mar 30, 2015
    Posts:
    122
    Same problem.+1
     
    barabaridze likes this.
  5. philippelabalette

    philippelabalette

    Joined:
    Mar 23, 2019
    Posts:
    14
    Hi, this functionality is intended, please look at https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Interactions.html#press

    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...}
     
  6. Rickywild

    Rickywild

    Joined:
    May 20, 2015
    Posts:
    52
    @philippelabalette

    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.



    The same goes for using the if check within Lambda expression.
     
  7. FynnLevy

    FynnLevy

    Joined:
    Apr 7, 2017
    Posts:
    2
    I am also having this problem.
     
    Necron99 likes this.
  8. Rickywild

    Rickywild

    Joined:
    May 20, 2015
    Posts:
    52
    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.

    There's more you can read over on this thread.

    Additionally whilst i'm here like, the following lambda expression statement is unreachable. This is true for placing in the Awake() and Update() methods.

    Code (CSharp):
    1.        
    2.         _inputActions.PlayerControls.Attack.performed += var => _attack = var.ReadValue<float>();
    3.         {
    4.             // This is a GetKeyDown()
    5.             // Your operations go here
    6.             _atkKeyDwn = true;
    7.             _atkKeyUp = false;
    8.             //_state.SetState(PlayerStateData.CurrentState.HoldAttack);
    9.         };
    10.  
    11.         _inputActions.PlayerControls.Attack.canceled += var => _attack = var.ReadValue<float>();
    12.         {
    13.             // This is a GetKeyUp()
    14.             // Your operations go here
    15.             _atkKeyUp = true;
    16.             _atkKeyDwn = false;
    17.             //_state.SetState(PlayerStateData.CurrentState.ReleaseAttack);
    18.         };
    However the
    Code (CSharp):
    1. _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
     
    Last edited: Mar 28, 2020
  9. Rickywild

    Rickywild

    Joined:
    May 20, 2015
    Posts:
    52
    I got around this using bool checks and a timer.
     
    NickFrushour likes this.
  10. OMGOMGXAXA

    OMGOMGXAXA

    Joined:
    Apr 2, 2016
    Posts:
    10
    My solution : Go into PlayerInput.cs and comment those two lines :
    my solution.png
     
    ggl3dde likes this.
  11. Metron

    Metron

    Joined:
    Aug 24, 2009
    Posts:
    1,137
    I'm really struggling with this, too. When I press the shoulder buttons of my XBox Controller, I get 2 times the performed action in my callback.

    Anyone got a hint how to fix this?

    Edit: Currently, my code looks like this and the debug output is still logged twice:

    Code (CSharp):
    1. public bool hasShot;
    2. public void OnShoot(InputAction.CallbackContext _context)
    3.     {
    4.         if (_context.performed && !hasShot)
    5.         {
    6.             hasShot = true;
    7.             Debug.Log("Shoot performed");
    8.         }
    9.  
    10.         if (_context.canceled)
    11.         {
    12.             Debug.Log("Shoot canceled");
    13.             hasShot = false;
    14.         }
    15.  
    16.         if (_context.started)
    17.         {
    18.             //            Debug.Log("Shoot");
    19.         }
    20.     }
     
    Last edited: Apr 5, 2020
    anycolourulike likes this.
  12. ggl3dde

    ggl3dde

    Joined:
    Apr 8, 2020
    Posts:
    1
    By default all interactions will fire the 3 callbacks - start, performed, canceled.

    https://docs.unity3d.com/Packages/c.../manual/Interactions.html#default-interaction

    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.
     
    Filip8429 and jonte24680 like this.
  13. LeePerry

    LeePerry

    Joined:
    Aug 27, 2013
    Posts:
    7
    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.
     
    Last edited: Apr 18, 2020
  14. DavidRodMad

    DavidRodMad

    Joined:
    Jan 26, 2015
    Posts:
    13
    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.
     
  15. Chefty

    Chefty

    Joined:
    Jun 17, 2015
    Posts:
    43
    Same for me, it's really discouraging.

    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...

    Cheers,
     
    Psychiatrist and CoCoNutti like this.
  16. chusux

    chusux

    Joined:
    Nov 15, 2016
    Posts:
    1
    This is driving me nuts. Buf found some usefull info:
    if I do
    Code (CSharp):
    1.  if (context.phase == InputActionPhase.Canceled)
    2.         {
    3.             Debug.Log(gameObject.name);
    4.         }
    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?

    Cheers
     
    m0ty0 likes this.
  17. CastrDev

    CastrDev

    Joined:
    Feb 28, 2018
    Posts:
    1
    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:

    Code (CSharp):
    1. if(context.started == true)
    2.         {
    3.             Debug.Log("Key Press");
    4.         }
    5.  
    6.         if(context.canceled == true)
    7.         {
    8.             Debug.Log("Key Release");
    9.         }
    It might be an intended behavior on the devs part, but I find it revealing to see that line in the PlayerInput.cs code:
    Code (CSharp):
    1. ////REVIEW: really wish we had a single callback
    Hope that helps
     
  18. CoCoNutti

    CoCoNutti

    Joined:
    Nov 30, 2009
    Posts:
    513
    I thought this new input system was meant to make things easier.

    It's not.
     
    davidnibi and Vagabond_ like this.
  19. CoCoNutti

    CoCoNutti

    Joined:
    Nov 30, 2009
    Posts:
    513
    Thinking I might roll back to old system.
     
    anycolourulike likes this.
  20. tinnystudios

    tinnystudios

    Joined:
    Oct 27, 2016
    Posts:
    18
    Hey guys, so I was also playing around.

    I think following their setup using PlayerInput isn't useful and rather Clunky.

    What I found works fine instead is to just make class of your own and use InputAction.

    Code (CSharp):
    1.     private void Awake()
    2.     {
    3.         ShiftAction.performed += _ => _shiftPressed = true;
    4.         ShiftAction.canceled += _ => _shiftPressed = false;
    5.  
    6.         JumpAction.performed += Jump;
    7.         ButtonOneAction.performed += BasicAttack;
    8.         MoveAction.performed += Move;
    9.         MoveAction.canceled += _ => _moveInput = Vector2.zero;
    10.     }

    upload_2020-6-23_18-4-24.png
     

    Attached Files:

    FullMe7alJacke7 likes this.
  21. isr5

    isr5

    Joined:
    May 21, 2020
    Posts:
    3
    What do you mean by "make your own class"? Are you saying to keep the generated actions asset and create a custom class to drive it?
     
  22. LexGear

    LexGear

    Joined:
    Sep 24, 2012
    Posts:
    11
    Yeah, this issue is really bugging me and wasting my time. Doesn't matter if you set it to Press or Press and Release, it calls the function multiple times. What is really interesting is that I've found only player ONE to have this issue. Any player that joins after it calls once. What's that about??? Here's my code.

    Code (CSharp):
    1.  
    2.     public void GetInteractValues( InputAction.CallbackContext value )
    3.     {
    4.         if ( value.started )
    5.             print("foo");
    6.     }
     
  23. destrozates

    destrozates

    Joined:
    Nov 7, 2013
    Posts:
    26
    I hope this helps someone. I was getting the same behavior of the button triggering the event 3 times, I was testing this with the PlayerInput component using the Behavior "Invoke Unity Events", when pressing the south button on a gamepad or space on the Keyboard it was supposed to make my character jump once. But it was activating the action 3 times, what I did to fix this is using the check of the Callbackcontext.performed like this:
    Code (CSharp):
    1.     public void Jump(InputAction.CallbackContext context)
    2.     {
    3.         if (context.performed)
    4.         {
    5.             Debug.Log(context.control.device.displayName);
    6.             myRB.AddForce(Vector3.up*jumpForce, ForceMode.Impulse);
    7.         }
    8.     }
    Doing it this way, it makes everything work when using the interactions Properties such as "Press and Release", "Release Only" or "Press Only". Everything just works now.
     
    M4R5, DigitalSpirit, DemTsag and 2 others like this.
  24. LexGear

    LexGear

    Joined:
    Sep 24, 2012
    Posts:
    11
    The reason you were getting it three times is because of the three stages in a button press. "Started", "Performed", and "Cancelled". In my case, this would fire SIX times. Your code is basically the same as mine except you are firing at "Performed", and I'm firing at "Started". The result is the same. For whatever reason, you don't have this "Bug" we're all referring too. Instead you just had the wrong condition in your statement.

    That being said, I'm glad it's fixed for you. I'm still banging my head against the wall here.
     
    anycolourulike and Jar_Coding like this.
  25. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    So.. this seems unclear when working with it imo.

    The inspector help message of the PlayerInputInputAction asset says this when adding a Press interaction:

    "Note the press interaction is only necessary when wanting to customize button press behaviour. For default behaviour, simply set the action type to 'Button' and use the action without interactions added to it".

    Leaving both Action and Binding without interactions like the message urges should thus result in the default behaviour - and the default behaviour for a button press i 3 callbacks?

    I also can't get it down to 1 callback using the Trigger Behaviour "Press Only". Should this not make the space key trigger once?

    How can I get the expected OnActionHappened callback only once? Must I parse it like the latest posts in this thread urges?
     
    Last edited: Jul 8, 2020
  26. LexGear

    LexGear

    Joined:
    Sep 24, 2012
    Posts:
    11
    Literally what I just said in my last post. You aren't experiencing a bug. This is the standard "Started", "Performed", "Cancelled" stages.Read above.
     
    FullMe7alJacke7 and Jar_Coding like this.
  27. cbanacka

    cbanacka

    Joined:
    Jul 13, 2020
    Posts:
    4
    I am having the same issue. Brand new to unity, looked up all the tuts on input, then saw there is a new input system. Saw how it works and ran into this. Spent 6 hours trying to figure out why my single on PRESS spacebar as calling 3 times, then if i double tapped spacebar i would get like 5 calls. Finally found this post! At least i am not crazy!

    I tried to follow the simple IF statements provided above to only run the debug.log on the canceled or performed, but i was not able to get any output when i do that. It is as if i am not using the right InputAction.CallbackContext.

    Was wondering if anyone else was not able to get this work around to work?
     
  28. Struct2

    Struct2

    Joined:
    Jan 14, 2017
    Posts:
    2
    Hi i had same problem try this
    public void Submit(InputAction.CallbackContext context) {

    switch (context.phase)
    {
    case InputActionPhase.Performed:
    Debug.Log("Submit Performed");
    break;
    case InputActionPhase.Started:
    Debug.Log("Submit Started");
    break;
    case InputActionPhase.Canceled:
    Debug.Log("Submit Canceled");
    break;
    }
    }
     
  29. Michal_Stangel

    Michal_Stangel

    Joined:
    Apr 17, 2017
    Posts:
    151
    I solved this problem same way. Unity Events, Press Only Interaction (Release only to mimic GetMouseButtonUp) and code something like this:

    Code (CSharp):
    1.        
    2. public void Event_LeftClick_Press(InputAction.CallbackContext context)
    3. {
    4.             if (context.performed == true)
    5.             {
    6.                 var value = context.ReadValue<float>();
    7.                 Debug.LogWarning("Left mouse button down: " + value);
    8.  
    9.                 // Do something
    10.             }
    11. }
     
    BillShackleton and sarynth like this.
  30. Jar_Coding

    Jar_Coding

    Joined:
    Oct 5, 2017
    Posts:
    17
    Have the same bug, its just happend for the first player in an local multiplayer setup. My events get called 6 times. I know it is by design that the method get called 3 times for "started" "performed" and "canceled" that is fine. But it should not double everything.
     
  31. rsosa2k

    rsosa2k

    Joined:
    Feb 11, 2015
    Posts:
    1
    After a few stumbles on this matter (and evaluating your contributions, thanks for it), I think this is intentional behavior to give us the opportunity to execute code according to the phase in which the action is.
    In my project I have done something like the following (using behavior "Invoke Unity Events" in the PlayerInput Component):

    ...
    switch(callbackContext.phase)
    {
    case InputActionPhase.Started:
    Debug.Log("Started"); //for review only, can be removed
    //your code;
    break;
    case InputActionPhase.Performed:
    Debug.Log("Performed"); //for review only, can be removed
    //your code if you need; //for nothing use return;
    break;
    case InputActionPhase.Canceled:
    Debug.Log("Canceled"); //for review only, can be removed
    //your code if you need; //for nothing use return;
    break;
    }
    ...

    as suggested by Struct2
     
    Last edited: Jul 24, 2020
  32. Michal_Stangel

    Michal_Stangel

    Joined:
    Apr 17, 2017
    Posts:
    151
    After some testing...
    Release event can be filtered to get only one trigger if you use "context.performed" and have only ONE binding in your input action.
    Unfortunately once you add more bindings (for example another for GamePad) it fires twice and I see no way to filter it based on "context". Context Value is 0 in both cases.

    Code (CSharp):
    1.         public void Event_WorldSelect_Release(InputAction.CallbackContext context)
    2.         {
    3.             if (context.performed == true)
    4.             {
    5.                 // do something
    6.             }
    7.         }
    Setup: Pass Through, Button, Interaction: Release Only
     
    Last edited: Jul 28, 2020
    KwahuNashoba likes this.
  33. bpodraza

    bpodraza

    Joined:
    Jun 2, 2020
    Posts:
    1
    I wanted my XBox controller / keyboard input to execute an Action only once when I pressed the button or key.

    I was struggling with this too, but I got it working by setting up the Input Action as:

    Action: Pass Through, Button
    Interaction: Press Only

    And then in my script, I used a boolean to disable a switch (line 13). The code executes only once, unless the button is released and pressed again. I believe that is the behavior everyone is looking for.

    Code (CSharp):
    1. bool Change;
    2.  
    3. public void OnChange(InputAction.CallbackContext context)
    4. {
    5.     Change = (context.phase == InputActionPhase.Performed);
    6. }
    7.  
    8. private void Update()
    9. {
    10.    if (Change)
    11.    {
    12.        //do something
    13.        Change = false;
    14.    }
    15. }
    This was not clear at all, but it is nice in the sense that if you want the button to keeping firing, no additional programming is required.
     
    Last edited: Aug 17, 2020
  34. djweaver

    djweaver

    Joined:
    Jul 4, 2020
    Posts:
    105
    I am having a similar issue now, and it just started happening and I'm not sure why. I'm doing a check on the callback context for performed only, yet performed fires TWICE now instead of one time. And if I remove the check, all three events: started, performed, and canceled trigger twice each, giving me 6 callback hits each keystroke.

    Its a button, and I've tried it with press only interaction and no interactions:
    Code (CSharp):
    1.         public void OnShoot(InputAction.CallbackContext context)
    2.         {
    3.             if (context.performed) print("shooting");
    4.         }
    EDIT: Silly me. I accidently added the script to the prefab when there was already the same script on the object in-scene, so I had the same script executing twice. o_O:rolleyes:
     
    Last edited: Sep 8, 2020
  35. PlayCreatively

    PlayCreatively

    Joined:
    Jan 25, 2016
    Posts:
    94
    I've been reading multiple solutions but they weren't working for me (on build specifically) until I discovered some weren't sharing the whole solution. So what worked for me is to do like many said and set the Action type to pass through and below to button
    upload_2020-9-18_16-56-22.png
    Then make sure the trigger behaviour is set to press only
    upload_2020-9-18_16-57-17.png
    Then also make sure you're subscribing to the OnStarted event, opposed to the OnPerformed
    inputs.Default.Interact.started += OnInteractDown;

    Now it works in build for me. This was only a controller problem btw. Using the controller wirelessly still results in the button events having a seizure, sadly.
     
  36. anthonov

    anthonov

    Joined:
    Sep 24, 2015
    Posts:
    160
    From what I understand so far, the inputs events from the Player Input component are designed to work with phases interaction, but they are really overkill. If you want to bind a press button event to a function, you have to filter fom both .inputActions asset AND phases in your script.
    So now my script, with function without parameters, how were not directly related to input, but still time to time get call from player, obligatory has to deal with contex-callback-inputAction parameter...and filter phases, for a simple press button.
    And now if another class want to call the same simple function in this script, it has to simulate an event, or another solution is to write two functions : on for the Player Input call, and one without parameter for call from the other class, for the same result. It force you to breaks good coding practice such as keeping your code as simple as possible, and doing its work withour care about other classes. (separating responsabilities : my script don't need to know inputs class exist).
    One last solution is to write an intermediate class dedicated for filtering the "phases" mess from playerInput events, then redirect calls to scripts by parameterless events.

    This is strange they decided to use UnityEvent for input response (very good idea to separate input logic from your code logic) but at the same time force you to use a "god" context class as parameter in which you have to filter through, in order to not get your functions fired multiple time, even when its not needed. This is off, something looks wrong to me.

    I would rather like to see an easy way to build your own event parameters to really fit your needs.
     
    Last edited: Sep 22, 2020
    hooksun likes this.
  37. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    Lots of different discussion here, but the first handful of posts seemed to miss this, so I wanted to leave it here in case it's helpful to some folks.

    Attached to performed, then check context.ReadValueAsButton(). For example...

    Code (CSharp):
    1.         _playerControls.MainGameplay.Dialogs.performed +=
    2.             context =>
    3.             {
    4.                 Debug.Log("Reads 1 when button pressed:" + context.ReadValue<float>());
    5.                 if (context.ReadValueAsButton())
    6.                 {
    7.                     // performed is called twice.
    8.                     // Once when ReadValueAsButton() is true (button down)
    9.                     // And, once when it is false. (button up).
    10.                     DoToggle();
    11.                 }
    12.             };
    13.  
     
    BitsAndSpaces and Jar_Coding like this.
  38. Xstyler

    Xstyler

    Joined:
    Nov 5, 2015
    Posts:
    9
    I have the same problem and I found this solution:
    Code (CSharp):
    1. public void OnPickup(InputAction.CallbackContext context)
    2. {
    3.         if(context.performed && gameObject.scene.IsValid()) {
    4.                 print("Picked");
    5.         }
    6. }
    For me, this looks like a bug and I don't see any interest in fixing this.
    I assume nobody is writing inputs this way?
     
  39. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    It's generally fine once you know about it. It's just annoying the first time you run into it and it would be much better if the QuickStart went more in-depth into the issue, that you basically need a switch statement on context.phase. Actually, while writing this, I went ahead and submitted the request on the page, stating that I felt that information was missing. So hopefully it will be updated or something.

    I also agree with @inputchaos - it wouldn't have been a bad idea to have two events for each button action on PlayerInput, one for OnButtonPressed and the other for OnButtonReleased.
     
    ProceduralCatMaker likes this.
  40. AronTD

    AronTD

    Joined:
    Aug 31, 2013
    Posts:
    22
    My solution was to remove the interaction on the Action. Like this:
    upload_2020-11-15_20-31-24.png
    upload_2020-11-15_20-31-59.png

    Then the two bindings look like this:
    upload_2020-11-15_20-32-19.png
     
  41. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,148
    I got a solution as well, well it's mostly a hack but does the work in my case. As the cancel action gets invoked in a couple of frames or so, i just reset the value using a coroutine waiting the next frame.
    I am having a singleton "UserInput" and all objects are checking for property values.

    It's not elegant in any way but it does work!

    Code (CSharp):
    1.  
    2.  
    3.     private void OnEnable()
    4.     {
    5.         inputActions.Menus.MenuBack.performed += MenuBack_performed;
    6.         // Cancel is not even needed in this case
    7.         inputActions.Menus.MenuBack.canceled += x => menuBack = false;
    8.         inputActions.Menus.MenuBack.Enable();
    9.     }
    10.     private void MenuBack_performed(InputAction.CallbackContext obj)
    11.     {
    12.         menuBack = true;
    13.         StartCoroutine("CancelBackButton");
    14.     }
    15.  
    16.     IEnumerator CancelBackButton()
    17.     {
    18.         yield return null;
    19.         menuBack = false;
    20.     }
     
  42. BrunoBelmonte

    BrunoBelmonte

    Joined:
    Jan 16, 2013
    Posts:
    7
    Guys, I was having the same problem and make it work on really simple way.


    Code (CSharp):
    1. public void Anything (InputAction.CallbackContext context)
    2. {
    3.         if (!context.started)
    4.         {
    5.               //Do something with "context.performed"
    6.         }
    7. }
     
  43. amarillosebas

    amarillosebas

    Joined:
    Feb 28, 2013
    Posts:
    44
    It just blows my mind how Unity ships a broken system meant to replace the old one, and just never fixes it. It's as if they've given up. Makes me strongly consider migrating to Unreal.
     
  44. B3Designs

    B3Designs

    Joined:
    Apr 11, 2019
    Posts:
    6
    I know I'm really late to this party, but I'd like to throw my tuppence into the ring. I was also getting the double behaviour issue (as the OP) and was debug logging stuff to try and track down an answer. It wasn't until I logged the name of the GO that had the callback attached that I spotted that it was also getting called on the un-instantiated prefab!
    I wasn't aware that this was even possible, but it definitely was. I added the following line to the callback handler :
    Code (CSharp):
    1. if(!this.gameObject.activeInHierarchy) return;
    and now it only gets called the once.

    Just thought I'd throw that one out there...

    Danny
     
    Last edited: Feb 14, 2021
  45. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Thanks so much, Danny! This saved me quite some debugging and head scratching.
     
  46. The-NightflyAZ

    The-NightflyAZ

    Joined:
    Apr 27, 2015
    Posts:
    17
     
    quibit likes this.
  47. quibit

    quibit

    Joined:
    Jan 1, 2019
    Posts:
    12
    I'd like to thank the people who shared their work-arounds in here as it did save me many hours of frustration.

    I cannot think this was intended behavior from Unity, given that if you set it to Invoke Unity Events, you have a single event source, which will fire multiple times, when the Interaction is set to "Press Only" for example. This would only make sense if they had multiple event sources for each type of event (Press, Release, Hold). Adding your own logic to parse and figure out the type of events are work-arounds and should not be required.

    Alas, I did get it to work adding my own logic, so that's that, but I do hope they improve this system to be more predictable and intuitive.
     
    Psychiatrist and amarillosebas like this.
  48. Metron

    Metron

    Joined:
    Aug 24, 2009
    Posts:
    1,137
    This S*** has been going on since almost 2 years. I don't understand how they still haven't solved this.
     
    florianBrn and amarillosebas like this.
  49. sch4ffen

    sch4ffen

    Joined:
    Feb 11, 2018
    Posts:
    1
    Hi I found it while thinking about the same problem.

    public bool canceled { get; }
    public bool started { get; }
    public bool performed { get; }

    use :

    if (context.started)
    debug.Log("shoot");

    When I checked the definition, I found it, and I was convinced by debugging. i think this issue is intended.
     
    Last edited: Mar 28, 2021
  50. Natzely

    Natzely

    Joined:
    Sep 9, 2017
    Posts:
    3
    The issue I'm running into is that if I set the interaction as Release Only, it will only give the actual value of a 1D axis or Vector2 on the "Started" event which triggers when the button is pressed. The "Performed" event, which triggers on release sends a value of 0 or (0,0) as well the "Cancelled" event. This only happens with Release Only. Both Press Only and Press and Release have the proper value during the "Started" and "Performed" events.
     
    squigglebucket likes this.