Switch on when detects a controller

● ARCHIVED · READ-ONLY
Started by SutoriTheRat 20 posts View original ↗
  1. Hello, I was wondering if there is a method or plugin that detects when a controller is being used and activates a switch accordingly.

    I made a hud for my game, some of the things it includes are icons and buttons to use those icons.

    I would like that when it detects a controller, the buttons on the hud change to those of a controller.
  2. Try this script:
    navigator.getGamepads()[0] !== null
    Put it in a Conditional Branch. It worked for me.
  3. The problem with what @SangHendrix suggests is that's going to be true if any controllers are plugged in.

    Many gamers will have controllers plugged into their PC all the time, but not necessarily want to use them for a given game.

    If you've played any professional games that support multiple inputs, the standard procedure is to show the icons for whatever the player has actually pressed a button on.

    So if I click or press Enter on the main title, it shows me keyboard buttons. If I pressed A on my Xbox controller, it shows the icons for those buttons.

    I haven't done anything with gamepads, so someone else might have a better answer; but, taking a quick look, I'd try adding a check to the middle of _updateGamepadState().

    Code:
    Input._updateGamepadState = function(gamepad) {
        var lastState = this._gamepadStates[gamepad.index] || [];
        var newState = [];
        var buttons = gamepad.buttons;
        var axes = gamepad.axes;
        var threshold = 0.5;
        newState[12] = false;
        newState[13] = false;
        newState[14] = false;
        newState[15] = false;
        for (var i = 0; i < buttons.length; i++) {
            newState[i] = buttons[i].pressed;
        }
        if (axes[1] < -threshold) {
            newState[12] = true;    // up
        } else if (axes[1] > threshold) {
            newState[13] = true;    // down
        }
        if (axes[0] < -threshold) {
            newState[14] = true;    // left
        } else if (axes[0] > threshold) {
            newState[15] = true;    // right
        }
        for (var j = 0; j < newState.length; j++) {
            if (newState[j] !== lastState[j]) {
                var buttonName = this.gamepadMapper[j];
                if (buttonName) {
    // A valid gamepad button was pressed, turn on a switch
                    $gameSwitches.setValue(X, true);
                    this._currentState[buttonName] = newState[j];
                }
            }
        }
        this._gamepadStates[gamepad.index] = newState;
    };

    In the $gameSwitches line, you'd replace X with the value of the switch to turn on.

    By default, that will go into the game save so it's true for the rest of that player's game; if you wanted it to reset every time the game is started, you'd need an additional plugin to reset the switch on game load.

    What software are you using? I copied the MV function because that's what you have in your profile, but I just noticed you posted this in MZ support.
  4. ATT_Turan said:
    The problem with what @SangHendrix suggests is that's going to be true if any controllers are plugged in.

    Many gamers will have controllers plugged into their PC all the time, but not necessarily want to use them for a given game.

    If you've played any professional games that support multiple inputs, the standard procedure is to show the icons for whatever the player has actually pressed a button on.

    So if I click or press Enter on the main title, it shows me keyboard buttons. If I pressed A on my Xbox controller, it shows the icons for those buttons.

    I haven't done anything with gamepads, so someone else might have a better answer; but, taking a quick look, I'd try adding a check to the middle of _updateGamepadState().

    Code:
    Input._updateGamepadState = function(gamepad) {
        var lastState = this._gamepadStates[gamepad.index] || [];
        var newState = [];
        var buttons = gamepad.buttons;
        var axes = gamepad.axes;
        var threshold = 0.5;
        newState[12] = false;
        newState[13] = false;
        newState[14] = false;
        newState[15] = false;
        for (var i = 0; i < buttons.length; i++) {
            newState[i] = buttons[i].pressed;
        }
        if (axes[1] < -threshold) {
            newState[12] = true;    // up
        } else if (axes[1] > threshold) {
            newState[13] = true;    // down
        }
        if (axes[0] < -threshold) {
            newState[14] = true;    // left
        } else if (axes[0] > threshold) {
            newState[15] = true;    // right
        }
        for (var j = 0; j < newState.length; j++) {
            if (newState[j] !== lastState[j]) {
                var buttonName = this.gamepadMapper[j];
                if (buttonName) {
    // A valid gamepad button was pressed, turn on a switch
                    $gameSwitches.setValue(X, true);
                    this._currentState[buttonName] = newState[j];
                }
            }
        }
        this._gamepadStates[gamepad.index] = newState;
    };

    In the $gameSwitches line, you'd replace X with the value of the switch to turn on.

    By default, that will go into the game save so it's true for the rest of that player's game; if you wanted it to reset every time the game is started, you'd need an additional plugin to reset the switch on game load.

    What software are you using? I copied the MV function because that's what you have in your profile, but I just noticed you posted this in MZ support.
    It actually doesn't register a controller as connected unless you've activated one of the inputs on it since starting the game.
  5. Trihan said:
    It actually doesn't register a controller as connected unless you've activated one of the inputs on it since starting the game.
    That's not what the documentation says?

    1705936749853.png
    And I just fired up a game, entered the command, and got an array with Gamepad objects without having pressed a button.
  6. ATT_Turan said:
    That's not what the documentation says?

    View attachment 292677
    And I just fired up a game, entered the command, and got an array with Gamepad objects without having pressed a button.
    1705937125183.png
    Before and after hitting a button. It returns a GamepadList either way, but until you've registered some input on a connected controller, all the entries are null.
  7. @Trihan
    Having pressed zero buttons :stickytongue:

    1705937228609.png

    So it appears that's gamepad-specific functionality which isn't to be relied on.
  8. ATT_Turan said:
    @Trihan
    Having pressed zero buttons :stickytongue:

    View attachment 292683

    So it appears that's gamepad-specific functionality which isn't to be relied on.
    Ah, interesting. I stand corrected. What sort of gamepad do you have connected? My test was with a PS5 DualSense.
  9. Trihan said:
    What sort of gamepad do you have connected? My test was with a PS5 DualSense.
    An Xbox controller and...I'm guessing the second one must be my Nostromo n52.
  10. ATT_Turan said:
    An Xbox controller and...I'm guessing the second one must be my Nostromo n52.
    I was going to see if I got the same behaviour with an Xbox One controller but I don't have a micro USB cable within distance of my chair and I'm not getting out of it to find one. :p
  11. ATT_Turan said:
    The problem with what @SangHendrix suggests is that's going to be true if any controllers are plugged in.

    Many gamers will have controllers plugged into their PC all the time, but not necessarily want to use them for a given game.

    If you've played any professional games that support multiple inputs, the standard procedure is to show the icons for whatever the player has actually pressed a button on.

    So if I click or press Enter on the main title, it shows me keyboard buttons. If I pressed A on my Xbox controller, it shows the icons for those buttons.

    I haven't done anything with gamepads, so someone else might have a better answer; but, taking a quick look, I'd try adding a check to the middle of _updateGamepadState().

    Code:
    Input._updateGamepadState = function(gamepad) {
        var lastState = this._gamepadStates[gamepad.index] || [];
        var newState = [];
        var buttons = gamepad.buttons;
        var axes = gamepad.axes;
        var threshold = 0.5;
        newState[12] = false;
        newState[13] = false;
        newState[14] = false;
        newState[15] = false;
        for (var i = 0; i < buttons.length; i++) {
            newState[i] = buttons[i].pressed;
        }
        if (axes[1] < -threshold) {
            newState[12] = true;    // up
        } else if (axes[1] > threshold) {
            newState[13] = true;    // down
        }
        if (axes[0] < -threshold) {
            newState[14] = true;    // left
        } else if (axes[0] > threshold) {
            newState[15] = true;    // right
        }
        for (var j = 0; j < newState.length; j++) {
            if (newState[j] !== lastState[j]) {
                var buttonName = this.gamepadMapper[j];
                if (buttonName) {
    // A valid gamepad button was pressed, turn on a switch
                    $gameSwitches.setValue(X, true);
                    this._currentState[buttonName] = newState[j];
                }
            }
        }
        this._gamepadStates[gamepad.index] = newState;
    };

    In the $gameSwitches line, you'd replace X with the value of the switch to turn on.

    By default, that will go into the game save so it's true for the rest of that player's game; if you wanted it to reset every time the game is started, you'd need an additional plugin to reset the switch on game load.

    What software are you using? I copied the MV function because that's what you have in your profile, but I just noticed you posted this in MZ support.
    Oh I forgot to change the info in my profile sorry, I haven't test anything yet, but I use an xbox controller too, i'll reply later when I have some time to test it. Thanks for replying!
  12. It looks like that function is the same in MZ.
  13. wouldn't it better to show just all controllers at once?

    keyboard use, gamepad use etc, everyone wins.

    PS4 doesn't show gamePad either untill pressed, but I think its more
    on the console controller as xbox, psx and earlier doesn't have this check
    in the controller itself?

    so it would register automatically as seen?
  14. ShadowDragon said:
    wouldn't it better to show just all controllers at once?
    No. :stickytongue:

    The first post says:
    starb said:
    I made a hud for my game, some of the things it includes are icons and buttons to use those icons.

    Do you think each HUD element should show the PC key, Xbox button, and PlayStation button stacked on top of it at the same time? :guffaw:
  15. 1 image or 2 to show or show choices what to use?
    if they choose keyboard, keyboard image with buttons layout else
    gamepad if they choose that one.

    but a layout what the buttons do can be showed with or without using gamepad.

    that is what I ment at least.
  16. ATT_Turan said:
    The problem with what @SangHendrix suggests is that's going to be true if any controllers are plugged in.

    Many gamers will have controllers plugged into their PC all the time, but not necessarily want to use them for a given game.

    If you've played any professional games that support multiple inputs, the standard procedure is to show the icons for whatever the player has actually pressed a button on.

    So if I click or press Enter on the main title, it shows me keyboard buttons. If I pressed A on my Xbox controller, it shows the icons for those buttons.

    I haven't done anything with gamepads, so someone else might have a better answer; but, taking a quick look, I'd try adding a check to the middle of _updateGamepadState().

    Code:
    Input._updateGamepadState = function(gamepad) {
        var lastState = this._gamepadStates[gamepad.index] || [];
        var newState = [];
        var buttons = gamepad.buttons;
        var axes = gamepad.axes;
        var threshold = 0.5;
        newState[12] = false;
        newState[13] = false;
        newState[14] = false;
        newState[15] = false;
        for (var i = 0; i < buttons.length; i++) {
            newState[i] = buttons[i].pressed;
        }
        if (axes[1] < -threshold) {
            newState[12] = true;    // up
        } else if (axes[1] > threshold) {
            newState[13] = true;    // down
        }
        if (axes[0] < -threshold) {
            newState[14] = true;    // left
        } else if (axes[0] > threshold) {
            newState[15] = true;    // right
        }
        for (var j = 0; j < newState.length; j++) {
            if (newState[j] !== lastState[j]) {
                var buttonName = this.gamepadMapper[j];
                if (buttonName) {
    // A valid gamepad button was pressed, turn on a switch
                    $gameSwitches.setValue(X, true);
                    this._currentState[buttonName] = newState[j];
                }
            }
        }
        this._gamepadStates[gamepad.index] = newState;
    };

    In the $gameSwitches line, you'd replace X with the value of the switch to turn on.

    By default, that will go into the game save so it's true for the rest of that player's game; if you wanted it to reset every time the game is started, you'd need an additional plugin to reset the switch on game load.

    What software are you using? I copied the MV function because that's what you have in your profile, but I just noticed you posted this in MZ support.
    Where should I put the code? Honestly I don't have much experience with coding in RPG Maker.
  17. starb said:
    Where should I put the code? Honestly I don't have much experience with coding in RPG Maker.
    Create a new text file in your project's js/plugins folder, paste that code into the file, save it as
    MyScripts.js (or anything else with a .js extention) and add it as a plugin in Plugin Manager. Any other scripts like this you can then just add to that file.

    ATT_Turan said:
    Do you think each HUD element should show the PC key, Xbox button, and PlayStation button stacked on top of it at the same time? :guffaw:
    No, that'd be ridiculous. You have to also include the icons for Joy-Cons, 8BitDo and the Steam Deck ;)
  18. ATT_Turan said:
    The problem with what @SangHendrix suggests is that's going to be true if any controllers are plugged in.

    Many gamers will have controllers plugged into their PC all the time, but not necessarily want to use them for a given game.

    If you've played any professional games that support multiple inputs, the standard procedure is to show the icons for whatever the player has actually pressed a button on.

    So if I click or press Enter on the main title, it shows me keyboard buttons. If I pressed A on my Xbox controller, it shows the icons for those buttons.

    I haven't done anything with gamepads, so someone else might have a better answer; but, taking a quick look, I'd try adding a check to the middle of _updateGamepadState().

    Code:
    Input._updateGamepadState = function(gamepad) {
        var lastState = this._gamepadStates[gamepad.index] || [];
        var newState = [];
        var buttons = gamepad.buttons;
        var axes = gamepad.axes;
        var threshold = 0.5;
        newState[12] = false;
        newState[13] = false;
        newState[14] = false;
        newState[15] = false;
        for (var i = 0; i < buttons.length; i++) {
            newState[i] = buttons[i].pressed;
        }
        if (axes[1] < -threshold) {
            newState[12] = true;    // up
        } else if (axes[1] > threshold) {
            newState[13] = true;    // down
        }
        if (axes[0] < -threshold) {
            newState[14] = true;    // left
        } else if (axes[0] > threshold) {
            newState[15] = true;    // right
        }
        for (var j = 0; j < newState.length; j++) {
            if (newState[j] !== lastState[j]) {
                var buttonName = this.gamepadMapper[j];
                if (buttonName) {
    // A valid gamepad button was pressed, turn on a switch
                    $gameSwitches.setValue(X, true);
                    this._currentState[buttonName] = newState[j];
                }
            }
        }
        this._gamepadStates[gamepad.index] = newState;
    };

    In the $gameSwitches line, you'd replace X with the value of the switch to turn on.

    By default, that will go into the game save so it's true for the rest of that player's game; if you wanted it to reset every time the game is started, you'd need an additional plugin to reset the switch on game load.

    What software are you using? I copied the MV function because that's what you have in your profile, but I just noticed you posted this in MZ support.
    This code works beautifully in MV as a plugin, with one small issue. Using MadeWithMV.js as well, if the player presses a gamepad button while the splash screen is being displayed by MadeWithMV, a "TypeError: Cannot read property 'setValue' of null" occurs. (details shown in the image below with Turan's code from this thread as 'ATT_Turan_gamepadcheck.js')

    Screenshot 2024-06-11 192751.png
  19. pineboxgames said:
    This code works beautifully in MV as a plugin, with one small issue. Using MadeWithMV.js as well, if the player presses a gamepad button while the splash screen is being displayed by MadeWithMV, a "TypeError: Cannot read property 'setValue' of null" occurs. (details shown in the image below with Turan's code from this thread as 'ATT_Turan_gamepadcheck.js')

    View attachment 308149
    Looks it it breaks because it expects game switches to exist, but at this stage they don't yet. Replacing that line to check for them should help.

    Replace $gameSwitches.setValue(X, true); with if($gameSwitches) $gameSwitches.setValue(X, true);
  20. Mac15001900 said:
    Looks it it breaks because it expects game switches to exist, but at this stage they don't yet. Replacing that line to check for them should help.

    Replace $gameSwitches.setValue(X, true); with if($gameSwitches) $gameSwitches.setValue(X, true);
    Excellent. Works perfectly. Thank you for that! For others' reference, I added it as follows, in side the if (buttonName) statement...

    if($gameSwitches){
    $gameSwitches.setValue(X, true);
    this._currentState[buttonName] = newState[j];
    }