snozbot / fungus

An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
MIT License
1.63k stars 290 forks source link

When using gamepad input to select a menu option, next menu option also gets selected as if submit was performed twice #900

Closed TheEmbracedOne closed 3 years ago

TheEmbracedOne commented 3 years ago

Describe the bug I am using the new input system but I'd suspect this is the case with the old one also. When an option is selected by pressing submit on the gamepad, the next set of menus are displayed which happens so fast that the currently pressed submit is selecting the next appearing options. This issue only happens when selecting a menu option leads to more menu options being selected: CCz6FP2Knl

The above gif demonstrates gamepad input. Here is mouse input to demonstrate expected behaviour: mL3QGDApCb

I have adjusted the Input System Package's timings; image

and also the repeat delays on the InputSystemUIInputModule components to no avail (i've tried 2+ secs, no difference); image

I believe this issue is to do with the next menu options appearing too fast; if I place a 1 second wait at the start of the next menu options, it no longer happens, however that should not be necessary to counter this issue. Replicated in builds as well as in editor.

To Reproduce In a scene set up to work with the new input module, set up a flowchart with 2 sets of menus to appear after one another, without say dialogs inbetween. (see example in gif above)

Enter play mode and press submit. Observe the next set of options also being selected as if submit was pressed twice in rapid succession.

Expected behavior Submit only ever selecting 1 menu option. Perhaps the solution is to add a timer similar to the SayEndDelay feature in #895 but for menu options, but I'm not sure if there's a way to apply this delay only to cases where a menu option leads to more menu options... so perhaps another kind of solution would be better.

I suppose the issue could also be approached from an input point of view, where after a new menu option appeared, the system would check whether the submit button is already down - making it so you would have to first release the submit button and press it again to select a newly appeared option.

Perhaps there is another angle here I'm missing, but any solution to this that wouldnt require me hunting down every case like this in our project and putting a Wait command in there would be super appreciated.

Versions & Platform (please complete the following information):

TheEmbracedOne commented 3 years ago

I've since ditched the new input system, and I will re-test this with a controller soon and report back on it.

TheEmbracedOne commented 3 years ago

This is not an issue on the old input system anymore. Closing.

Arylos07 commented 3 years ago

EDIT: Yes, sorry I'm just now seeing this and necroing it.

I'm not sure if this may the problem, but I did have the same issue where hitting an input button would result in the action being performed twice (or 3 times). This is a bug with how the input system was programmed with its events. I was able to fix it by adding a new interaction and assigning my buttons to it. This effectively simulates Input.GetButtonDown() for a single frame. You could see if setting your submit inputs to use this interaction helps.

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using System;
using UnityEditor;

#if UNITY_EDITOR
using UnityEngine.InputSystem.Editor;

[InitializeOnLoad]
#endif
public class KeyPress : IInputInteraction
{
    public void Process(ref InputInteractionContext context)
    {
        switch (context.phase)
        {
            case InputActionPhase.Waiting:
                context.Started();
                break;

            case InputActionPhase.Started:
                context.Waiting();
                break;
        }
    }

    public void Reset()
    {
    }

    static KeyPress()
    {
        InputSystem.RegisterInteraction<KeyPress>();
    }

    [RuntimeInitializeOnLoadMethod]
    private static void Initialize()
    {
        // Will execute the static constructor as a side effect.
    }

#if UNITY_EDITOR
    public class KeyPressEditor : InputParameterEditor<KeyPress>
    {
        public override void OnGUI()
        {
            EditorGUILayout.LabelField("This interaction treats this action as a button and can only be activated. Performed and cancelled steps are skipped.");
        }
    }
#endif

}
TheEmbracedOne commented 3 years ago

Thanks @Arylos07 I think my issue was fixed by using Rewired in the end and reverting back to the default input system. While I no longer need a solution for this myself, this may be useful for others who arent using Rewired!