Search Unity

macOS player input selection broken

Discussion in 'macOS' started by xrix4096, May 21, 2017.

  1. xrix4096

    xrix4096

    Joined:
    Sep 29, 2016
    Posts:
    12
    In all versions of 5.6 any project built for macOS has got a broken input selector on the startup dialog. When you choose any entry in the input dialog and try and remap it (both primary and secondary) you get the usual "Press the button or key...." popup but no keyboard, mouse or joystick input it detected. Even pressing ESC to dismiss the popup doesn't work so you need to force quit the application.

    It seems that this is a known issue to Unity since there's the following issue in the tracker:

    https://issuetracker.unity3d.com/is...-entries-makes-the-player-become-unresponsive

    This claims to be fixed in 2017.1 but I've tried all the latest beta builds and see no improvement.

    Is this really happening for *everyone* who is targeting macOS with 5.6? It seems like a show stopper that'd be worth including in a 5.6 patch release if so as it's just not possible to ship macOS software with this bug. If anyone isn't seeing it I wonder if we could compare notes so I can see if there is any possible workaround.

    Cheers

    -- Chris
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    It's not really a show-stopper because most finished games don't use Unity's startup dialog. Better to put those sorts of options actually in your game.

    But if true I agree it's a very serious issue, and they should definitely fix it. I just wanted to point out that you have the option of a work-around.
     
  3. xrix4096

    xrix4096

    Joined:
    Sep 29, 2016
    Posts:
    12
    Thanks. From the superficial reading I'd done I thought that remapping input from your own scripts wasn't currently possible, and I'd need to get one of the 3rd party input managers to make this happen from my own menus & scripts. Do you happen to have any links or similar? I'd also prefer to not use the startup dialog

    Cheers

    -- Chris
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    If you're only using the keyboard, you can do that without any 3rd-party assets. Just check all keys to see what the user is pressing, and then remember that to check for it again during the game.

    But if you need to support joysticks/gamepads, then yeah, you'll need a 3rd-party asset. Lately I have been using but hating Rewired; in the past I have used (and liked, despite some limitations) cInput. There may be others. Spend some time searching the Asset Store, and find one that seems right for you.
     
  5. xrix4096

    xrix4096

    Joined:
    Sep 29, 2016
    Posts:
    12
    Thanks Joe, that makes sense.

    Cheers

    -- Chris
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, correction. I've just discovered that you don't need any third-party plugin to support joysticks after all!

    It turns out that Input.GetKey (and GetKeyDown/GetKeyUp) are not just for keyboard keys. The KeyCode enum includes a gazillion entries for joystick buttons, too. And if you ask for the state of one of these, it'll return true if that joystick button is down.

    It does this even when you hot-swap your joystick/gamepad while the game is running (!). This didn't work in the past, and we are unable to find any release notes about it, but it certainly works in our testing today (on both Mac and Windows).

    Moreover, the Input.GetJoystickNames method returns decent human-readable names for all the joysticks that are plugged in. And this too seems to update instantly when you swap devices in or out.

    The only fly in the ointment is analog axes and D-pads. These don't appear to respond to GetKey. However, there are only so many of them... if you install and set up Rewired, it defines a ton of virtual axes in your Input settings, corresponding to basically all possible joystick axes. I think you'd be safe if you did this for just, say, 4 axes for each of joysticks 1-8 (a total of 32 virtual axes). And then you can check each of those to see what's pressed.

    Here's a quick-and-dirty demo of how you can scan for keys/joystick buttons, as well as axis (assuming you have those virtual axes set up).

    Code (CSharp):
    1.     void Update() {
    2.         // Check all the things!
    3.         // (Iterating over all KeyCodes.)
    4.         foreach (var value in (KeyCode[])Enum.GetValues(typeof(KeyCode))) {
    5.             if (Input.GetKey(value)) {
    6.                 buttonFeedback.text = value.ToString();
    7.             }
    8.         }
    9.      
    10.         // Check all the virtual axes, since these seem to be the only way to get to d-pads/joysticks.
    11.         for (int joynum = 1; joynum<=8; joynum++) {
    12.             for (int axisnum=1; axisnum<=4; axisnum++) {
    13.                 string virtAxisName = string.Format("Joy{0}Axis{1}", joynum, axisnum);
    14.                 float value = Input.GetAxisRaw(virtAxisName);
    15.                 if (Mathf.Abs(value) > 0.1f) buttonFeedback.text = virtAxisName + "=" + value;
    16.             }
    17.         }
    18.      
    19.         joystickText.text = "Joysticks:\n" + string.Join("\n", Input.GetJoystickNames());
    20.     }
    So, you could make your own configurable input system by just doing this sort of scan while asking the user what key/axis they want to use, remembering the KeyCode or axis that you find, and saving that to prefs. Then just check that same key/axis during your game.
     
    Last edited: May 24, 2017
  7. xrix4096

    xrix4096

    Joined:
    Sep 29, 2016
    Posts:
    12
    Nice! Much obliged, I shall give this a go.

    Thanks again

    -- Chris
     
    JoeStrout likes this.
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    And now I've finally finished writing up a little blog post about it (including a Unity package that provides a demo). Read all about it here: Configurable Input in Unity.
     
    xrix4096 likes this.
  9. xrix4096

    xrix4096

    Joined:
    Sep 29, 2016
    Posts:
    12
    I've tried this now and generally it works pretty well so thanks a lot! One thing I have noticed that this particular way of abstracting away the differences between axis, buttons and keys is that you currently can't 'debounce' keyboard or button input by simply using a GetKeyDown or GetButtonDown equivalent to detect only the downstroke. Do you have any thoughts on how best to expose this while keeping the abstraction for where you don't care?

    Thanks again

    -- Chris
     
    JoeStrout likes this.
  10. Souk21

    Souk21

    Joined:
    Dec 28, 2014
    Posts:
    14
    @JoeStrout Thanks for the nice article, but I really feel it should still be fixed.
    Are they waiting for the new input system to release before?

    Still nothing in 2017.1 release notes :(
     
  11. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Off the top of my head, I can think of two approaches. One is to do that in a higher layer, i.e., in whatever code is using the input abstraction. For example if your laser cannon script should only emit a laser blast when the Fire input is pressed, then it could keep its own boolean property to remember whether Fire was pressed last frame, and only emit a blast when Fire is currently pressed by was not pressed before.

    The other (and probably better) approach would be to extend InputElement to keep its previous (i.e. last-frame) value. Then you could add a Pressed() method that would return true only when (say) the current value is >= 0.3f but the previous value is < 0.3f. You could also add a Released() method with the opposite logic.
     
  12. Souk21

    Souk21

    Joined:
    Dec 28, 2014
    Posts:
    14
    I sent a new bug report and was answered this:
    I didn't have the time to try yet. (and still nothing in the release notes)