Forum rules - please read before posting.

PS/Xbox Controller support

Hey there,

I'm looking to support two scenarios:

  1. Folks that prefer to plug in a PS/Xbox controller to their PC

  2. My game technically works on the Steam Deck, but the controls are fairly unintuitive, the Steam Deck documentation says that its controls map pretty much one-to-one against PS4/5 controllers

Any good resources on how to map an AC game to something like a PS4 controller?

I'm a bit confused as the AC input method seems to distinguish between "Mouse and keyboard" and "Keyboard or Controller". Shouldn't it rather pick up that a controller is plugged in and respond to those inputs too?

Comments

  • edited April 2022

    My understanding is AC relies on Unity's input manager, so the question better becomes how easy is it to setup Unity input to reflect using a game pad. My experience and answer to that question was "not very easy at all".

    To that end I've started to use Rewired which is a fantastic replacement for Unity's input manager. This makes working with control pads, and forming controls around them, much more intuitive.

    You can then marry AC and Rewired together. There is already an integration script on the wiki and so far the results (and support from Chris) has been great.

    I also wrote a script that will use Rewired to detect changes of input device (for example, a player plugging a PS/Xbox controller into their PC) and then run AC action lists. You can then use those action lists to change any aspect of AC, or do whatever you feel necessary, on an input device change.

    I also did a video that covers the setup of Rewired + AC a bit:

    I'm still working through, with the help of Chris, direct navigation of UI and menus. Hopefully my experience might be of some help to you.

  • Wow, thanks for this, will check it out! 👊

  • edited April 2022

    Did you get Rewired to work with navigating menus and conversations too?

  • I have. I've made a little video to better answer your question (it might need an hour or so to process):

    https://drive.google.com/file/d/16R6OkslHpEYweZkKR1WYTKaZCafRvpHA/view?usp=sharing

  • Wow, I am crazy grateful for you taking the time!

  • edited April 2022

    @ChrisIceBox Might I ask, are there any plans to add gamepads functionality out-of-the-box? I'm thinking basics as moving the cursor and selecting menu items after plugging in a controller?

  • AC supports both controller-cursors and direct-menu navigation via controllers - how/when you use it in conjunction with other inputs and navigation methods is down to your project's needs.

    Being able to separate controller inputs from keyboard/mouse inputs also requires attention to the Input Manager - one approach is to create a series of inputs named e.g. "JoystickButton" that each detect the various joystick buttons (joystick button 0,1,2 etc). A script could then check for this whenever any input has been detected.

    This could then be used to alter the input method - along with any other changes you wanted to make. For example, this script would limit direct-menu navigation to only times that the controller is being used:

    using UnityEngine;
    using AC;
    
    public class SwitchInputs : MonoBehaviour
    {
    
        [SerializeField] private InputMethod defaultInputMethod;
    
        private void Start ()
        {
            SetInputMethod (defaultInputMethod, true);
        }
    
        private void Update ()
        {
            if (Input.anyKeyDown)
            {
                if (Input.GetButtonDown ("JoystickButton"))
                {
                    SetInputMethod (InputMethod.KeyboardOrController);
                }
                else
                {
                    SetInputMethod (InputMethod.MouseAndKeyboard);
                }
            }
        }
    
        private void SetInputMethod (InputMethod inputMethod, bool force = false)
        {
            if (KickStarter.settingsManager.inputMethod != inputMethod || force)
            {
                KickStarter.settingsManager.inputMethod = inputMethod;
    
                switch (inputMethod)
                {
                    case InputMethod.MouseAndKeyboard:
                        KickStarter.menuManager.keyboardControlWhenCutscene = KickStarter.menuManager.keyboardControlWhenPaused = KickStarter.menuManager.keyboardControlWhenDialogOptions = false;
                        break;
    
                    case InputMethod.KeyboardOrController:
                        KickStarter.menuManager.keyboardControlWhenCutscene = KickStarter.menuManager.keyboardControlWhenPaused = KickStarter.menuManager.keyboardControlWhenDialogOptions = true;
                        KickStarter.playerMenus.FindFirstSelectedElement ();
                        break;
    
                    default:
                        break;
                }
            }
        }
    
    }
    
  • Thanks I managed to get the switching working, but for some reason I can't get dragging n dropping inventory items (or even clicking them) to work in "Keyboard and controller" mode. I have registered inputs for CursorHorizontal, CursorVertical, InteractionA & B (they all work).

    I'm thinking it should work as it does using mouse (press key and drag n drop on hotspots).

    Here's a look at my settings manager:
    https://1drv.ms/u/s!Amz_vh8OYDX3vbhxFrD_r9r46YL4yg?e=qqRD82

    Thanks

  • Or preferably, InteractionA would examine an item, and InteractionB would change the cursor to it (as dragging and dropping doesn't feel very natural with a controller).

  • Dragging-and-dropping should work with a controller - I can't recreate an issue.

    You can, however, disable it inside the code above when switching to Keyboard Or Controller input. As with any Manager field, you can get an API reference to it by right-clicking the field's label:

    AC.KickStarter.settingsManager.InventoryDragDrop = false;
    

    You can swap InteractionA/B when over an inventory item by override AC's InputGetButtonDown delegate - see the Manual's "Remapping inputs" chapter for details.

  • edited April 2022

    Thank you for your tips, I managed to switch between the input methods, and I got the cursor and movement working.

    A few things I haven't been able to figure out:

    • Click an item in the inventory to make it become the cursor so it can be used on hotspots
    • Using the 4-way directional buttons during conversations
    • Using the 4-way directional buttons when selecting a hotspot interaction

    I'm finding it very hard to know how to configure the inputs to use a Gamepad for AC to be honest. Perhaps a downloadable working example or a tutorial could be an idea for the future.

    Maybe you could have a look at this repro that contains the parts I got working so far:
    [REDACTED]

    Instructions: Just open Scene1, plug in a gamepad and click any button on it to switch the input mode. Talking to the box on the ground shows a conversation.

    Thanks

  • Link removed. Do not ever post links to AC's source on public forums.

  • I'm so sorry about that (I could have sworn I unchecked the AC folder while making that package).

  • Click an item in the inventory to make it become the cursor so it can be used on hotspots

    If you have a non-zero Minimum drag distance value, then the InteractionA must be held down while the cursor is moved.

    You can alter this value through script at the moment you switch input method - see above. However, I would recommend first playing with Keyboard Or Controller input first, without switching, to learn exactly what settings you want to make use of.

    Using the 4-way directional buttons during conversations

    See the Manual's "Navigating menus directly" chapter. To directly-navigate Conversation menus, you'll need to have Directly-navigate Menus during Conversations? checked in the Menu Manager before the Menu is turned on. Again, see the script above.]

    In the case of Unity UI menus, an additional step is necessary - the Element to first-select when the Menu is opened must be specified at the bottom of the Menu's properties box.

    Your ConversationUI issue also needs to have its Button components to have their Navigation fields set up to support navigation - but this'll be the case by default.

  • If you have a non-zero Minimum drag distance value, then the InteractionA must be held down while the cursor is moved.

    If you try it with the package, setting KickStarter.settingsManager.dragDropThreshold to 0 still doesn't cause InteractionA to change the cursor.

    See the Manual's "Navigating menus directly" chapter. To directly-navigate Conversation menus, you'll need to have Directly-navigate Menus during Conversations? checked in the Menu Manager before the Menu is turned on. Again, see the script above.]

    In the case of Unity UI menus, an additional step is necessary - the Element to first-select when the Menu is opened must be specified at the bottom of the Menu's properties box.

    Your ConversationUI issue also needs to have its Button components to have their Navigation fields set up to support navigation - but this'll be the case by default.

    So I read through those chapters carefully, and unless I'm missing something, all of this should already be setup in the package.

    For the Horizontal and Vertical input axes, could you tell me the names of the positive/negative button in order to map them to the 4-way buttons? Also what type of axis are you using Joystick axis, X axis and Y axis?

    Thanks

  • If you try it with the package, setting KickStarter.settingsManager.dragDropThreshold to 0 still doesn't cause InteractionA to change the cursor.

    I did, and it did - holding down a gamepad input mapped to InteractionA caused the item to become selected in drag-and-drop mode.

    I'm not relying on Rewired as mentioned above, however - just Unity's built in input system.

    So I read through those chapters carefully, and unless I'm missing something, all of this should already be setup in the package.

    They weren't importing as such on my end, but the changes I describe above caused them to work for me.

    For the Horizontal and Vertical input axes, could you tell me the names of the positive/negative button in order to map them to the 4-way buttons? Also what type of axis are you using Joystick axis, X axis and Y axis?

    Unity's default Horizontal and Vertical axes, duplicated and mapped to the Joystick X and Y axes, were enough to get things working - though only to the analogue stick, the DPad is a separate pairing.

    If you're using Unity UI, then these inputs are defined in the EventSystem. AC will spawn its own unless you assign a prefab in the Menu Manager, but Horizontal and Vertical are the default values.

  • I just tried it again, and I just can't get the cursor to change no matter what I do. Perhaps our InputManagers differ in some way, or perhaps we're using different controllers... Also, I'm not using Rewired either.

    I did figure out how to map the DPad of an PS controller to PC, if anyone needs it:
    https://1drv.ms/u/s!Amz_vh8OYDX3vbpATuSx2f26P2mJxA?e=J4iD91

    Thank you for your patience, Chris.

    Gamepad support turned out to be harder than I thought, so personally I'm gonna have to pause that effort until after release for my game.

    I think a lot of folks would find adding gamepad support challenging, perhaps its another place where AC might be able to make things more straightforward? Here's a few ideas that might be worth considering:

    • An AC menu item that adds all suggested inputs to the InputManager
    • The input mappings are different for different controllers/operating systems, maybe AC could build an abstraction over the most common ones (Xbox, PS and Switch), either in the form of InputManager registrations, or an extendible solution in code.

    Feel free to ping me if you wanna bounce around requirements or need feedback in any way.

    Thanks!

  • One more thought: It seems perfectly possible to mix the old input system with the new one, I think switching to the new one when using keyboard/controller might just make things a lot easier (pretty sure it does a better job at abstracting gamepads).

  • Mixing input systems is cause for trouble, IMO. Unity's new Input System is indeed better for gamepads, but it's best to stick to one system.

    It's still the case that switching input method would rely making changes to Manager fields as necessary. Again though, I recommend first getting the behaviour correct for each intended "Input method" in isolation, before looking to combine them with a script that changes the "Input method" based on input.

  • Interesting, I was thinking leaving "mouse and keyboard" as it is (the new system is bypassed), and whenever anyone uses "controller and keyboard", the old system is bypassed. Whether someone switches mode in design-time or run-time probably shouldn't matter.

    Maybe you're right, I just know that it's a bit of a struggle at the moment, so I'm just bouncing around ideas :)

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.