Forum rules - please read before posting.

Optimizing for Keyboard+mouse makes controller not work for selecting conversation options

edited January 2019 in Technical Q&A

Sorry for the badly worded title.

So my game comes out in less than 10 days, and I intend to release it without controller support as I can't figure out how to make all keyboard, mouse and controller work in tandem.

Unity -
AC -

The game is Direct controlled. The player can move around with the keyboard (or controller) and press "E" when near a hotspot to bring up an interaction wheel. From this wheel, players can select look, use, talk etc by pressing up, down, left, right etc on the keyboard (or A, B, X, Y on the controller) The player can also click on a hotspot and then on an interaction option using the mouse, but movement is not done by mouse (as intended) The mouse can also select menu options/ conversations.

At first, the game only supported keyboard and controller, with no mouse support. This worked perfectly, but when I included mouse as a control option due to player feedback, this created issues with controller (and pure keyboard) controls, specifically when selecting menu/ conversation options not highlighting. This is solved by using the mouse to highlight one of the options, after which the player can use the controller to move up/ down among options, but of course, this isn't ideal.

After switching to mouse interaction support, I still had some issues where the mouse would randomly not work for selecting hotspots. I enforced mouse support by running three actions on every OnStart, OnLoad cutscene (and on game start action list) The three actions are these - Player Constrain - cursor lock (disabled) + Engine: Manage Systems - Cursor, Input, Menus (enabled) + Custom: Keyboard and Mouse Input

The custom action is this (I'm not sure where I got this script from, but it was from AC forums/ wiki for sure)

    using UnityEngine;
    using System.Collections;

    #if UNITY_EDITOR
    using UnityEditor;
    #endif

    namespace AC
    {

        [System.Serializable]
        public class ActionMouseInputMethod : Action
        {

            // Declare variables here


            public ActionMouseInputMethod()
            {
                this.isDisplayed = true;
                category = ActionCategory.Custom;
                title = "KB&M Input Method";
                description = "This is a blank Action template.";
            }


            override public float Run()
            {
                KickStarter.settingsManager.inputMethod = InputMethod.MouseAndKeyboard;


                if (!isRunning)
                {
                    isRunning = true;
                    return defaultPauseTime;
                }
                else
                {
                    isRunning = false;
                    return 0f;
                }
            }


    #if UNITY_EDITOR

            override public void ShowGUI()
            {
                // Action-specific Inspector GUI code here

                AfterRunningOption();
            }


            public override string SetLabel()
            {
                // Return a string used to describe the specific action's job.

                string labelAdd = "";
                return labelAdd;
            }

    #endif

        }

    }

I'd like it to possibly be InputMethod.MouseAndKeyboardANDController

Any tips? :)

Comments

  • It's still possible to rely on the mouse with "Keyboard Or Controller" input - the big difference is that you need to map your mouse axes/clicks to Unity's input manager, since AC will no longer read the mouse state directly.

    You can create a new instance of e.g. "CursorHorizontal" that maps to the mouse X axis to have the mouse also control the cursor.

    If you're looking to switch between mouse and keyboard controls on the fly, however, you could try just e.g. detecting the presence of mouse movement / keyboard press and switching the "Input method" dynamically, e.g.:

    private void Update ()
    {
        Event currentEvent = Event.current;
        if (currentEvent.isMouse)
        {
            SetInputMethod (InputMethod.MouseAndKeyboard);
        }
        else
        {
            SetInputMethod (InputMethod.KeyboardOrController);
        }
    }
    
    
    private void SetInputMethod (InputMethod inputMethod)
    {
        if (KickStarter.settingsManager.inputMethod != inputMethod)
        {
            KickStarter.settingsManager.inputMethod = inputMethod;
    
            // Plus anything else you may want/need to do when changing input
        }
    }
    
  • edited January 2019

    "It's still possible to rely on the mouse with "Keyboard Or Controller" input - the big difference is that you need to map your mouse axes/clicks to Unity's input manager, since AC will no longer read the mouse state directly.

    You can create a new instance of e.g. "CursorHorizontal" that maps to the mouse X axis to have the mouse also control the cursor."

    By this do you mean that controller will control the mouse cursor? For example pushing the sticks would move the cursor around the screen?

    Alright, I'll try your script, thanks. Is this a replacement/ addition for the script I mentioned above? If not, is it a custom action that I should call in the same way I'd been calling my previous script?

  • I tried adding a new instance of CursorHorizontal to the input manager. Turns out I already had one set to mouse X axis (the first one) and so I duplicated that and created one for the joystick (lower one) Is this correct?

  • So I replaced by custom action with your script as a custom action, but it doesn't seem to do anything. In the settings manager, I've set the input method as Mouse and Keyboard, and I'm expecting to see this change as the custom action is called (I can confirm using my earlier custom action would change this from Keyboard and Controller to Mouse and Keyboard)

    Here's how I've implemented your script:

    using UnityEngine;
    using System.Collections;
    
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class ActionAutoInputMethod : Action
        {
    
            // Declare variables here
    
    
            public ActionAutoInputMethod()
            {
                this.isDisplayed = true;
                category = ActionCategory.Custom;
                title = "Auto Input Method";
                description = "This is a blank Action template.";
            }
    
    
            private void Update()
            {
                Event currentEvent = Event.current;
                if (currentEvent.isMouse)
                {
                    SetInputMethod(InputMethod.MouseAndKeyboard);
                }
                else
                {
                    SetInputMethod(InputMethod.KeyboardOrController);
                }
            }
    
    
            private void SetInputMethod(InputMethod inputMethod)
            {
                if (KickStarter.settingsManager.inputMethod != inputMethod)
                {
                    KickStarter.settingsManager.inputMethod = inputMethod;
    
                    // Plus anything else you may want/need to do when changing input
                }
            }
    
    
    #if UNITY_EDITOR
    
            override public void ShowGUI()
            {
                // Action-specific Inspector GUI code here
    
                AfterRunningOption();
            }
    
    
            public override string SetLabel()
            {
                // Return a string used to describe the specific action's job.
    
                string labelAdd = "";
                return labelAdd;
            }
    
    #endif
    
        }
    
    }
    
  • 2 There is also a related issue, which I'm not sure if I should post here as it might make the discussion confusing. But it's very related so here goes:

    When using my original Mouse+Keyboard system only, with the three actions called as mentioned in the OP, everything works perfectly. Except - the first scene after loading a game. Here, you can use the mouse for everything (conversations etc) except for the interact options (use, look at etc) clicking on these buttons (Unity UI) does nothing, and you are forced to use the alternative - arrow keys on the keyboard.

    Once you exit this scene however, the mouse controls start working perfectly for the interact options as well. This is odd because loading into scene A causes this issue, but switching to scene B fixes it for the rest of the game. BUT if you loaded a save game into scene B first, you'd experience the same issue, and it would be fixed by switching to scene A. So it's not the scenes which have any issue. It would seem like there's something wrong with my OnStart and OnLoad actions, but that's not true as well, they're all correct.

    Any way to "force" allow mouse function for interact option?
    (Issues like this are another reason I'm scared to introduce controllers into the mix. Forcing mouse functionality would end up overwriting controller functionality, so it seems to me the safest route is just stick to KBM OR KB/C?)

  • Oops didn't mean to make that a heading :) Was just using the hash symbol to write "no. 2"

  • By this do you mean that controller will control the mouse cursor? For example pushing the sticks would move the cursor around the screen?

    I was assuming that was already the case for you. However you want to control the cursor, I'm just saying that it's possible using Unity's inputs when using "Keyboard Or Controller" input.

    Alright, I'll try your script, thanks. Is this a replacement/ addition for the script I mentioned above? If not, is it a custom action that I should call in the same way I'd been calling my previous script?

    No, it's not a custom Action. It features an Update function which needs to run every frame. Create a new C# script, paste it inside (removing the default Start/Update functions) and add it to your scene. You will need to ensure this runs before AC, so set its Script Execution Order value to something negative.

    When using my original Mouse+Keyboard system only, with the three actions called as mentioned in the OP, everything works perfectly. Except - the first scene after loading a game

    It may be that the Menus need to be refreshed in order to accept the new input method. Try checking Always reload scene when loading a save file? in your Settings Manager.

    Any way to "force" allow mouse function for interact option?

    I'm not entirely sure what you mean by this. You're saying that you only want the user to interact with Hotspots via the mouse? To do that, you should just have to remove any "InteractionA" inputs you have that are mapped to anything that's not the mouse.

  • edited January 2019
    1. > No, it's not a custom Action. It features an Update function which needs to run every frame. Create a new C# script, paste it inside (removing the default Start/Update functions) and add it to your scene. You will need to ensure this runs before AC, so set its Script Execution Order value to something negative.

    So I pasted the code, and had to add "Using AC" to make Kickstarter and SetInputMethod work. In the script execution order, I set this script on top, at -1100.

    Just to be certain, this is how my code looks - https://pastebin.com/rEQJWKYw

    But doing this had no effect. Am I correct in assuming you'd see the AC settings manager reflect this and switch the Input Method to **Keyboard or Controller ** while playing the scene in the editor?

    To be clear, the game can always be controlled using a Joystick, even when the Input Method is set to Mouse and Keyboard i.e - you can move the character and interact with hotspots using the joystick even when the mode is not set to Keyboard and Controller. ONLY, menus can't be controlled by a joystick (conversation menus, only. Pause menus CAN be controlled by Joystick in KBM mode) This is intended behavior, right?

    I only want the conversation menus to also be controlled by Joystick/ keyboard. This means that they would also have to automatically be highlighted from the start (they're not until I put the mouse cursor over one of the options. But even after highlighting with the mouse, the controller or keyboard can't control this menu. The conversation menu is an AC menu btw, not Unity)

    So is that what your script would do?

    I was assuming that was already the case for you. However you want to control the cursor, I'm just saying that it's possible using Unity's inputs when using "Keyboard Or Controller" input.

    I'll get to this aspect later. At the moment I don't want to use the Joystick to control the cursor.

    1. Now the second problem is to do with an issue that comes up only when a game is loaded, and it fixes itself as soon as you switch scenes as mentioned before. In the game, you can use the mouse to interact with hotspots. You can also press E on the keyboard or A on an Xbox controller near hotspots to bring up the interaction wheel. From this wheel, you can either click on each interaction option (Use, talk etc), or you can press one of the arrow keys on the keyboard or even press the face buttons on a controller to trigger one of the interaction options. These all work perfectly simultaneously, and have always worked.

    You can see the mouse functionality for this here: https://twitter.com/Rainswept_Game/status/1079011125184757760

    But, only in a newly loaded scene, the option to click on one of the interaction buttons using a mouse doesn't work. You can click on a hotspot, that brings up the wheel. But once the wheel opens, you can't choose any further options. You're forced to use arrow keys or a controllers face buttons to progress until reaching the next scene.

    You can see this issue in this video: https://drive.google.com/file/d/1I6I-4OtCsh1ITW6fZObMAq913S7Rbn2H/view?usp=sharing

    Let me know if there's any issue with the video's privacy. Also, Always reload scene when loading a save file didn't do anything.

  • I'd say the script is a red-herring, given the rest of your explanation.

    ONLY, menus can't be controlled by a joystick (conversation menus, only. Pause menus CAN be controlled by Joystick in KBM mode) This is intended behavior, right?

    Yes - for AC menus to be directly-navigable, you'll need it set on Keyboard And Controller.

    The conversation menu is an AC menu btw, not Unity

    If you switch to Unity UI, you have control over how your menu is selected. This is done via the EventSystem, a Unity component/concept. AC will provide its own by default but you can supply your own EventSystem prefab in the top of the Menu Manager.

    only in a newly loaded scene, the option to click on one of the interaction buttons using a mouse doesn't work.

    Is your Interaction menu AC or Unity UI? If it's Unity UI, check the GameObjects themeslves for anything amiss - it may be a Unity component setting.

    Please also share the exact Actions you said you're running upon loading a save.

  • So for now I'll focus on issue number 2 (interaction menu/ mouse click problem upon loading a save game)

    My interaction menu is Unity UI. Here's a video going through all the settings of the component and of the AC menu integration:

    Here's a screenshot of my actionlist after loading

    And my OnLoad cutscene inside every scene in the game

  • Thanks for the details, but it's the behaviour of the UI at runtime that is key here.

    If you can create a test scene that shows the issue clearly, PM me a .unitypackage with that and any necessary asset files and I'll take a look.

  • So I guess it wasn't a AC problem after all, as you suggested. This thread [https://answers.unity.com/questions/853655/canvas-buttons-not-working-after-levelload.html] suggested adding an EventSystem to the problematic menu. As of now, this issue seems to be fixed. I'll let you know if it re-occurs.

    As for controller compatibility, I'll return to this thread a little later when I decide to tackle it again!

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.