Search Unity

Resolved What would be the logic to trigger messages when pressing a key?

Discussion in 'Visual Scripting' started by Marou1, Jan 4, 2023.

  1. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    161
    Hi,

    I have 2 strings: StringA and StringB.
    I want to display StringA, wait until the player press space bar, then display stringB.
    So I made this logic:

    upload_2023-1-4_16-22-53.png

    The green line is the flow.

    The problem with this logic is that the Input system Event button On pressed is not 1 "Tick", it keeps firing over time.

    So this is what happens:

    Trigger
    Set X to True
    Display String A

    Then nothing until the player presses Space Bar, then:

    IF Bool = True
    Set X to False
    Set Y to True
    Display String B
    Input system Event button On pressed is still firing.
    IF Bool = True
    Set Y to False

    Result: The player presses Space bar once and StringA and StringB are displayed.

    I tried something else: I replaced Input system Event button On pressed with On update, if SpaceBarPressed = True then Set SpaceBarPressed to False then execute the If BOOL instruction.

    Another script sets SpaceBarPressed to True when the player presses the Space Bar.

    The problem is that I have many messages that could be displayed depending on conditions. This means many DisplayTexts graphs, and therefore many On Update firing. This has a performance impact.

    Thanks
     

    Attached Files:

  2. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    2,076
    There has to be a way to detect input on single "tick". But I'm not that familiar with the new input system.

    Alternatively, you could use "Once" node to execute the text change once, then after button is released - reset the once node so it'll trigger again.
     
  3. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    161
    Where would you place Once?
    I have tried to place it right after the Input Event but it doesn't work. It seems that the Input Events don't fire at the same time.
    So it happens that the second Input Event fires after the first Input Event and VarY was already set to true.
    So 2 messages are displayed.

    The last resort is to add a delay. But for the user, it feels that the messages lack responsiveness.
     
  4. OBiwer

    OBiwer

    Joined:
    Aug 2, 2022
    Posts:
    61
    This _should_ not be the case. from the source code of the Visual Scripting node:

    Code (CSharp):
    1.                 case InputActionChangeOption.OnPressed:
    2.                     shouldTrigger = m_Action.WasPressedThisFrame();
    3.                     break;
    If it actually fires more than once, than it's more likely to be an issue with either the Input system itself or with the inner workings of the Visual Scripting system. But it's definitely a bug, because it's supposed to fire only when the button is pressed in that particular frame.


    1. Have you measured it? or are you fearing the performance impact in advance?
    (Premature optimization is the root of all evil)
    2. If an OnUpdate call is your main performance concern ... OnInputSystemEventButton is also an OnUpdate call internally

    Code (CSharp):
    1.     public abstract class OnInputSystemEvent : MachineEventUnit<EmptyEventArgs>
    2.     {
    3.         protected override string hookName =>
    4.             UnityEngine.InputSystem.InputSystem.settings.updateMode ==
    5.             InputSettings.UpdateMode.ProcessEventsInDynamicUpdate
    6.             ? [B]EventHooks.Update[/B]
    7.             : EventHooks.FixedUpdate;
    3. If performance is actually a concern of yours, you wouldn't use Visual Scripting at all.

    I'm not really getting whats your problem.
    Code (csharp):
    1.  
    2. OnStart => ------------------------------- > Set Text "String A"
    3.  
    4. OnInputSystemEventButton => -------------- > Set Text "String B"
    5.  
    even if the event fires multiple times, it would still show stringB as soon as the button is pressed once.

    Do you want to toggle between the texts (each time the button is pressed)? Or what is it what you want to do?
     
    Last edited: Jan 6, 2023
  5. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    161
    Because I am not a programmer, otherwise I would use C#.

    I am not a the beginning of the project.

    Yes, with deep profiling.

    The graph is much more complex than that and is used in nearly 130 other graphs, that's why I made a drawing and not a screenshot to focus on the issue. It's not 2 strings to be displayed on start, but hundreds coming from a csv file to be displayed through the game.
    The issue is that when 2 graphs are following each other, pressing the key once displays 2 messages.

    I know there are different phases and it fires twice. It's by design but it created an issue as mentioned in other forums. The suggested workaround is to use if(!context.performed) { return; }
    https://forum.unity.com/threads/player-input-component-triggering-events-multiple-times.851959/

    I don't know how to do that in UVS.
     
  6. OBiwer

    OBiwer

    Joined:
    Aug 2, 2022
    Posts:
    61
    the input system has 2 ways of how it can be used. either subscribing a callback function to the events, or checking each frame.
    The UVS node checks each frame. there is no CallbackContext because it does not use the callback approach.


    and it showed that the update node was the bottleneck?
    then you're out of luck, because the InputSystemEvent node is just a Update node in disguise


    Edit

    I did a small test project with this:
    upload_2023-1-6_17-4-25.png

    it fires once, when it is clicked. I can't reproduce it printing the message multiple times.


    maybe it is time to show your graph? or create a minimal example that shows the issue


    This sounds more like an issue in your graph to me. do you have the event TWICE in your graph? once in each subgraph? or something like that?

    don't add the event in the subgraph, chain them via Trigger Inputs: Subgraphs and State Units | Visual Scripting | 1.7.8 (unity3d.com) (see section: "Subgraph inputs and outputs")
     
    Last edited: Jan 6, 2023
  7. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    161
    It's true that the InputSystemEvent is just an update, replacing one by the other won't solve the issue.
    But thanks to @PanthenEye who suggested to use Events instead, the perf are better now.
     
  8. OBiwer

    OBiwer

    Joined:
    Aug 2, 2022
    Posts:
    61
    Just for completeness sake:

    You want to move the event OUT of your subgraphs, and instead add a "Trigger Input" in your subgraph.
    This allows the parent graph to send the event only to the subgraph that should receive it.

    For example this graph:
    upload_2023-1-6_17-24-28.png

    alternates between the 3 subgraphs. Every time the event is fired (e.g. space is pressed) it visits a single subgraph.

    ("next" is a Integer variable with default value "-1")
     
  9. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    161
    This is not the logic of the drawing I posted. You can reproduce it, it's pretty quick. Do not forget that there are 2 subgraphs each wih an InputSystemEvent. You can replace the TRIGGER in green in my drawing by OnStart.

    You'll see that pressing the key once will display both strings.
     
  10. OBiwer

    OBiwer

    Joined:
    Aug 2, 2022
    Posts:
    61
    as I wrote: this is the error in your logic. Your logic is wrong. Fix it.
     
  11. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    161
    Oh my god, this is not an error, i need to use to]he subgraph multiple times...
    Just forget it.
     
  12. OBiwer

    OBiwer

    Joined:
    Aug 2, 2022
    Posts:
    61
    In my image above, I used the subgraph multiple times, too.
    the event triggers "multiple times" in your graph because you listen to it multiple times.