Search Unity

Rewired - Advanced Input for Unity

Discussion in 'Assets and Asset Store' started by guavaman, Sep 25, 2014.

  1. huulong

    huulong

    Joined:
    Jul 1, 2013
    Posts:
    224
    I've just upgraded to Unity 2018.3.12f1 on Linux today and all my various projects get some kind of "no OnValidate method found to override" errors (I had the same with Text Mesh Pro 1.3.0, and now it's Rewired). Fortunately, unlike the embedded packages, I can change the source code of high-level Rewired scripts, so I just added a quick fix for the time being:

    Code (CSharp):
    1.  
    2. // RewiredStandaloneInputModule.cs
    3.  
    4. #if UNITY_EDITOR
    5.         // somewhere between Unity 2018.3.7 and 2018.3.12 has OnValidate become a pure non-virtual message method (as it should)
    6. #    if UNITY_2018_3_12
    7.         private void OnValidate() {
    8.             SetupRewiredVars();
    9.         }
    10. #    else
    11.         protected override void OnValidate() {
    12.             base.OnValidate();
    13.             SetupRewiredVars();
    14.         }
    15. #    endif
    16. #endif
    17.  
    If it helps anybody.

    UPDATE: After a restart of Unity, the problem disappears. If you use the code above, it will warn you that you are hiding OnValidate and should either use `new` or `override` (of course you want to override). Very weird, maybe a Cache or Library issue... Reimporting assets may also fix the issue.
     
    Last edited: Apr 19, 2019
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    The reason it's an override method is that the base class is UIBehaviour, not MonoBehaviour. UIBehaviour defines many of the base MonoBehaviour methods as protected virtual methods for use by inheriting classes. Any issue with this has to be an error in the underlying UnityEngine.UI library that contains UIBehaviour.
     
  3. NobleRobot

    NobleRobot

    Joined:
    Jan 14, 2016
    Posts:
    56
    I'm trying to remove Hardware Maps that I'm not supporting in my game (flight sticks, etc.), and I've just noticed that the master list of supported controllers includes icons which identify which type of device each are, which is great (and not something I knew before today), but would it be possible to surface this kind of information more readily in the editor?

    I know you can create custom asset icons for each scriptable object template script, but that wouldn't help since they're all based on the same script. Would it be possible to make different icons based on some other factor, or maybe just have an editor-only image/icon field or enum so you can glace the information more quickly when looking at the Hardware Joystick Map Editor panel?

    It could be addressed very simply by changing the name of each object, so "FlightStick_SaitekCyborgEvo" "Gamepad_NykoAirflowEX" or something, unless there's a specific identifier that the name is conforming to that shouldn't be messed with.
     
    Last edited: Apr 20, 2019
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Thanks for the suggestion but I don't think this is necessary. Or more accurately, there are many other things on the to-do list that make much better use of my time that provide much wider benefit. Removing controller definitions is a one-time process. They are also mostly grouped together by type in ControllerDataFiles. Back-end stuff like messing with controller definitions is low-level, rarely necessary to do, and therefore doesn't have all the attention to detail of other areas of the application. FYI, it's also possible for a Controller Definition to implement multiple Controller Templates.
     
  5. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    I am changing LoadDefaultMaps to clear the Joystick Controller Map history for Joysticks no longer assigned to the Player. Therefore, the next time the Joystick is assigned, it will load the default maps from the Rewired Input Manager. This will not prevent external saved data from being loaded afterwards.
     
  6. Davood_Kharmanzar

    Davood_Kharmanzar

    Joined:
    Sep 20, 2017
    Posts:
    411
    @guavaman

    hello dear,
    i want to using Rewired on singleplayer game - PS4 platform ...
    i read this [http://guavaman.com/projects/rewired/docs/HowTos.html#ps4-gamepad-special-features] to access to PS4 controller features ...

    but i want to direct access to "Rewired_Core.dll" without using complex scripts to direct access to vibration, changing color/flashing LED, and making touchpad as mouse cursor for singleplayer only ...

    so, does exists an simple way??
    and what about other access like as buttons?? is that difference with default unity input?
    i mean does exists an better method for PS4 controller on rewired against of like this => Input.GetKeyDown(KeyCode.JoystickButton12) ??
    thanks.
     
  7. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    There is no reason to use the extension to set vibration. There are no special vibration features on the PS4 that require you do so. Use the default method:
    http://guavaman.com/projects/rewired/docs/HowTos.html#Vibration-Rumble

    The link you posted also shows this information:

    // Get/Set vibration
    // Note: Vibration can also be set in a generic way through Joystick.SetVibration
    float vibration = ext.GetVibration(PS4GamepadMotorType.WeakMotor);
    ext.SetVibration(PS4GamepadMotorType.StrongMotor, 1.0f); // set vibration on a single motor by type
    ext.SetVibration(1.0f, 1.0f); // set vibration on both motors simultaneously
    ext.StopVibration(); // stop all vibration
     
  8. EHG_Unity

    EHG_Unity

    Joined:
    May 21, 2017
    Posts:
    20
    How can we put rewired's widow into a custom UI panel?
     
  9. Shturmovik

    Shturmovik

    Joined:
    Nov 5, 2014
    Posts:
    29
    After spending about an hour trying to track down what I thought was a problem with my Rewired input definitions, I just realised it's a problem with my fancy new keyboard ("great for typing, sucks for gaming") as described here:

    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#keyboard-ghosting

    Turns out this particular Logitech turkey won't handle W+shift+space ... :mad:

    I diagnosed it with this handy online tool:

    https://drakeirving.github.io/MultiKeyDisplay/

    Leaving a note here so others might spend less time on this issue in the future.
     
  10. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    You will have to be more specific about exactly what window you're asking about.
     
  11. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    This is why I have so much extraneous, tangential information like this in the documentation. There are countless issues that, at first glance, appear to be a problem with the input system which are actually caused by something entirely unrelated in the (huge) technology stack. This leads to me chasing down non-existent issues for users on nearly a daily basis. Thank you for finding the information without reporting it as a bug to me. However, your post here, just like the information in the documentation, will be buried in the stream and the next person is just going to have to go searching again. In reality, this issue isn't related in any way to input systems, Rewired, or software. The hardware you are using doesn't behave how you expect, but that's all on the hardware. Truth be told, this information doesn't belong in the documentation or in this thread about Rewired.
     
    Last edited: Apr 24, 2019
  12. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Rewired 1.1.25.2 is now available on the Unity Asset Store.

    Please see Updating Rewired before updating.

    Release Notes

    1.1.25.2:

    Changes:
    - Joystick polling system now ignores Axis Calibration Sensitivity settings when polling axes so a very low Multiply sensitivity value doesn't prevent users from assigning axes to Actions.
    - Player.ControllerHelper.MapHelper.LoadDefaultMaps now clears Joystick Map history for Joysticks that were previously assigned to the Player but are currently not assigned at the time the method is called. This is done so that the next time a Joystick is re-assigned after LoadDefaultMaps is called while the Joystick is not present, the Joystick will load the default Joystick Maps from the Rewired Input Manager instead of loading from its history.

    Bug Fixes:
    - Controller.Button double press method overloads with no Speed argument now work correctly.
    - Fixed incorrect Whammy Bar axis calibration in XInput Guitar controller definition.
     
  13. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    Thanks for this update. I am tempted to get a xinput guitar now.
     
    guavaman likes this.
  14. jason07

    jason07

    Joined:
    May 10, 2011
    Posts:
    34
    I'm running into an issue when I use an Xbox One controller where after I let go of one of the sticks, that axis still remains active returning very small values like 0.01 or lower even when I set the controller down and no other input is happening. Occasionally these small values will spike when only one of the sticks is being pushed which causes unintentional movement like rotating the player when I am just activating the axis to move forward and not touching the stick to rotate.

    When the game starts all of the axis values are 0 as expected, it's only when I activate an axis is when this issues starts.

    I've tried adjusting my calibration settings and then just resetting the calibration to default. This helped some, but the issue still comes up. Does anyone have any idea what might be causing this? Thanks.
     
  15. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Setting a larger dead zone in the axis calibration is the only thing that will stop drift when the stick is at rest. You can easily view the raw and calibrated values for the axis in Debug Information:
    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#debug-information
     
  16. jason07

    jason07

    Joined:
    May 10, 2011
    Posts:
    34
    Hmm, I'm still having the issue even after cranking the dead zones all the way to 0.8. I should clarify that the small values I mentioned in my previous post are the raw axis values and occasionally when they spike it raises the normal values too causing unintentional movement. Regular values are mostly at 0 when nothing is touched, but the raw values have a tendency to keep returning low values, which makes me think this is the cause of the problem. Do you have any other suggestions? Thanks.
     
  17. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    No because this should not be happening. I've never seen or heard anything like it before. It is very possibly a hardware problem with your controller or some other software/driver installed interfering with the input values.
    1. What platform is this?
    2. What is the Primary Input source setting for the platform?
    3. If Windows, is Use XInput enabled?
    4. What version of Rewired is this?
    5. What is the raw value of the axis when it spikes?
    6. Is the controller USB or Bluetooth?
     
    Last edited: Apr 25, 2019
  18. jason07

    jason07

    Joined:
    May 10, 2011
    Posts:
    34
    Turns out it is an issue with my controller. I tried it out on a couple of different games and I get the same behavior. At least I know the problem isn't my game. Thanks!
     
  19. Pacosmico

    Pacosmico

    Joined:
    Jan 16, 2014
    Posts:
    14
    Hola, @guavaman I want to thank you for your work. I wonder if you are a a single person or a group but nevertheless this work is awesome. I wish my project had this from the start, but well, it was not a problem at all to just inject it and get going.
    I have a suggestion, since I had to walk a while to find a way to get the XBOX template without having to add more references (I'm trying to have input systems the least possible interdependency with the game) and after a while I did find it with "GetJoystickMapInstance" and the correct GUID... Actually "GetJoystickMapInstance" is right in de docs, but it was not obvious to me where to get the correct GUID. Then I found it through the ControllerDataFiles asset, and though, ¿you know that Tool to Bake actions, categories and stuff into CS Constants? ¿Wouldnt it be cool to have that too for Hardware->GUID? So I could then go like GetJoystickMapInstance( ControllerGUID.XboxOne, ThisMap, ThisLayout )

    Anyway, it's just a minimal suggestion, not really a thing that this needs

    So, again, thank you and congratulations for the great work. Oh, BTW I was thinking in sticking your logo in the credits ¿Would you mind that?

    ¡Un abrazo!
     
  20. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Hi,

    There's only one Guavaman here at Guavaman Enterprises. :D Glad you're liking Rewired.

    If you're referring to a Controller Template, you would use:
    http://guavaman.com/projects/rewire...ngHelper_GetControllerTemplateMapInstance.htm

    And would pass it the GUID for the Controller Template, which can be found in its concrete static class, such as this in the GamepadTemplate class:
    http://guavaman.com/projects/rewired/docs/api-reference/html/F_Rewired_GamepadTemplate_typeGuid.htm

    If you are referring to identifying a Joystick by hardware type (that sounds like what you're actually doing), then it's documented here:
    http://guavaman.com/projects/rewired/docs/HowTos.html#identifying-recognized-controllers

    You will find a CSV file with all the current GUIDs there.

    I do not want to export these to a CS file because this file would have to be regenerated whenever you (or I) add or remove Joysticks.

    You need to be aware of this caveat with Xbox controllers when loading map instances like that:
    http://guavaman.com/projects/rewired/docs/ControllerMaps.html#xinput-devices-windows

    As for including Rewired in the credits, sure! Much appreciated! You can find some logos here:
    https://www.dropbox.com/s/pzwjrb0amzcxe78/Rewired-Logos-PNG.zip?dl=0
     
    Pacosmico likes this.
  21. Pacosmico

    Pacosmico

    Joined:
    Jan 16, 2014
    Posts:
    14
    Thanks for your immediate response, and thanks for all the links
    My problem was that I was adapting the input controller configuration menu that was already in my project to fit the Rewired Gamepads, but when using the GamePad Template the Elements have the id but no text description, so I had to create a "disconnected" map thing, hence the need to find the GUID for XBox (because we like that one)... but... eh it's just a mess.
    After working in that solution for a while I think it's better to just go with a "You need to have at least one Gamepad connected to be able to rebind" notification and get a better compatibility with your system, I can even use your save load feature that way, not sure if the other way it was possible
    anyway, cheers!
     
  22. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    166
    Hi, I just bought rewired, and it seems pretty nice so far. However, I have a problem already.

    Rewired is picking up two controllers when only one is plugged in, so the ID is wrong, and the actions aren't playing. I *think* it's picking up my Logitech g13 as controller 1, but this is really just a mini-keyboard thing. I seem to remember a couple of pc games having this problem, where I would have to literally unplug the g13 in order to play the game, but this only happens maybe 1/100 games.

    How can I avoid this problem? If I'm right about the g13, how can I tell Rewired that the g13 is a keyboard and not a controller?
     
  23. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    1) View all Rewired objects live including controllers: http://guavaman.com/projects/rewired/docs/Troubleshooting.html#debug-information

    2) If the Logitech g13 is reporting through its HID information that it is a Gamepad or Joystick, then Rewired's going to see it as such because it uses the HID information given to it to determine what a device is. This being seen as a Joystick is Logitech's fault, or perhaps it's even intentional so their device can be used by games that support joysticks.

    3) See Joystick Auto-Assignment: http://guavaman.com/projects/rewired/docs/Controllers.html#joystick-auto-assignment

    >> How can I avoid this problem? If I'm right about the g13, how can I tell Rewired that the g13 is
    >> a keyboard and not a controller?

    You can't. All you can do is either assign multiple Joysticks to your Player or unassign the Logitech and assign something else. It would be impossible to maintain a perfect blacklist of all the possible devices (real and virtual) that might appear on your system as a joystick/gamepad. This is one of a billion reasons you must provide your players a way to 1) reassign controllers and 2) rebind controllers as stated on the Best Practices page.
     
    Last edited: Apr 30, 2019
  24. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    It's certainly possible to allow users to rebind controls for a not-present Joystick or Controller Template. That's what those ...Instance functions were made to do. But it is much more straightforward to bind using the current controller.
     
    Pacosmico likes this.
  25. daven8989

    daven8989

    Joined:
    Jan 25, 2014
    Posts:
    29
    Hello guavaman, I have a problem with the Controllers.GetButtonDown and GetButtonDownById. I think that the GamepadTemplate.elementId_center2 (or elementId_start) are wrong mapped on xbox one controller. I tryied with two differente hw version of the pad and in both cases this Id is mapped with the right stick button.
    Is it possibile that the index has been mismatched in one of the last update?

    Edit: GamepadTemplate.elementId_rightStickButton seems to not be associated with no physical button.
     
  26. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    There isn't any problem with Controller Template Element ids. You're passing the wrong value to the Controller functions. Controller Template Element Ids are not the same as Controller Element ids. Controller Templates are entirely separate from Controllers and exist as an additional layer on top of Controllers. Think of a Controller Template as wrapper that maps generic Template elements to Controller elements. GamepadTemplate.elementId_rightStickButton is the Element Id on the Controller Template, not the Controller. This would be used to get the Right Stick Button Controller Template element for functions in the Controller Template API that require the element id like ControllerTemplate.GetElement. You have to use other means to get the Controller element ids from the Template element if you want them. A Controller Template Element may point to more than one Controller element, for example two halves of a joystick axis pointing to two different D-Pad buttons on a controller that has no analog sticks. There is no 1:1 relationship so there is no list of constants mapping this relationship. There are various ways to back and forth between Controller Template elements and Controller Elements. Some are shown in the documentation and in the example.

    If you have the actual Controller Template (ie: it's connected), each IControllerTemplateElement has a source property such as IControllerTemplateButton.source which returns an IControllerElementTaget. This is only one way of making the connection. There are many other ways to go back and forth depending on the exact usage.
     
    Last edited: May 2, 2019
  27. daven8989

    daven8989

    Joined:
    Jan 25, 2014
    Posts:
    29
    Hello guavaman, thank you for the answer. What I'm trying to do is to associate controllers to player. Before I was using GetAnyButtonDown, but right know I must associate the controllers only with the menu button (the one that is mapped in the controller template with the element center 2). These are the exactly lines of code I'm using:
    Code (CSharp):
    1. for (int i = 0; i < controllersDetected.Length; i++) {
    2.             if (!ReInput.controllers.IsControllerAssigned (ControllerType.Joystick , controllersDetected[i])) {
    3.                 if (controllersDetected[i].GetButtonDownById (GamepadTemplate.elementId_start)) {
    4.                    ReInput.players.GetPlayer (currentPlayerIdToAssignController).controllers.AddController (controllersDetected[i] , true);
    5.                     canCheckController = false;
    6.                     Debug.Log ("Controller associated");
    7.                     eventHandlerManager.Broadcast (eventChannels.menu , menuEvents.controllerAssociated , e);
    8.                 }
    9.             }
    10.         }
    Basically when the controller association starts, I unbind all the controller detected and I start listening all the controllers. I was thinking that the GetButtonDownById was different from ButtonDown because can get the template Id of the button and auotmatically match the physical one of the controller connected.

    Have you got any suggestion about how to get the correct id to pass in GetButtonDownById? The physical controller can be any controller supported by your plugin.

    Thank you very much,
    Davide.
     
  28. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Thanks for the explanation.

    If you only allow player assignment via Controller Template elements, then you prevent any controller being used to assign a player that is not 1) a recognized controller 2) a controller compatible with the Gamepad Template. I do not recommend this approach.

    There are various ideas on how to implement a press start to join system here, including one about using the Gamepad Template Start button.
    http://guavaman.com/projects/rewired/docs/HowTos.html#press-start-to-join

    If you really want to use this method, you are going to have to have 2 code paths -- one that checks if the controller implements the Gamepad Template and one that is a fallback for all other controllers.

    You do not call GetButtonDown on the controller to get the value of a template element. You get the value directly from the Template as shown on the Controller Templates page:

    Code (csharp):
    1. // Get the Gamepad Template from the Controller
    2. IGamepadTemplate gamepad = controller.GetTemplate<IGamepadTemplate>();
    3.  
    4. // If the result is null, the Controller does not implement the Gamepad Template
    5. if (gamepad == null) continue;
    6.  
    7. // Read values directly from the elements
    8. // Note that most elements on the Gamepad Template have aliases
    9. // available such as a, b, x, y, back, start for elements which correspond to
    10. // Xbox controller naming standards for your convenience.
    11. // The standard names of actionBottomRow1, leftShoulder2, etc., are also available.
    12. Vector2 moveVector = gamepad.leftStick.value;
    13. Vector2 lookVector = gamepad.rightStick.value;
    14. float fire = gamepad.rightTrigger.value;
    15. // Any Axis can also be queried as a Button using the AsButton convenience property
    16. bool fireJustPressed = gamepad.rightTrigger.AsButton.justPressed;
    17. bool punch = gamepad.b.justPressed;
    18. bool reload = gamepad.y.justPressed;
    19. bool aim = gamepad.leftStick.press.value;
    20. bool jump = gamepad.x.justPressed;
    21. bool start = gamepad.start.justPressed;
    22. bool up = gamepad.dPad.up.value;
    23. bool down = gamepad.dPad.down.value;
    24. Vector2 dPadVector = gamepad.dPad.value;
     
  29. daven8989

    daven8989

    Joined:
    Jan 25, 2014
    Posts:
    29
    Hello guavaman, thanks for your amazing support.
    This solution is working as expected.

    Thank you very much,
    Davide.
     
  30. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
    Hi @guavaman

    Is there a way to differentiate the keyboard "button" versus the Xbox "button" ?

    I tried using the string and actionID, but Unity still thinks "player.GetButtonDown" is coming from the keyboard.

    I'd like Rewired to tell Unity, the button press is from my xbox controller.
    http://guavaman.com/projects/rewired/docs/api-reference/html/M_Rewired_Player_GetButtonDown.htm

    Thanks for the help

    Belows the code
    Code (CSharp):
    1.            if (Input.GetKeyDown(KeyCode.Space))
    2.             {
    3.                       //detect keyboard
    4.             }
    5.  
    6.             if (player.GetButtonDown(4))
    7.             {
    8.                       //detect xbox controller
    9.             }
    10.  
     
  31. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    http://guavaman.com/projects/rewired/docs/HowTos.html#get-contributing-input-sources
     
    KarlKarl2000 likes this.
  32. XimuNFD

    XimuNFD

    Joined:
    Apr 5, 2019
    Posts:
    1
    Hi guavaman

    I'm useing Rewired versioin 1.1.24.0 with Unity 2017.1.5f1 on a Windows 10 desktop.

    I went through a problem than sometimes the "C" key of the keyboad was marked pressed when what I did was only draging the mouse and then realse.

    When the problem occured, I tried every combination of RawInput, DirectInput and enabling native keyboard handle, nothing helps.

    The only solution is to restart the Unity editor, sometimes even to restart the computer.

    Do you have any idea about that?

    Thanks for your help.
     
  33. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    No, there's no way there could be any sort of interaction between the keyboard and mouse at the low level in Rewired. The two systems are completely different, independent, and get messages directly from Windows.

    Possible sources:
    1) Hardware issues.
    2) Other software installed creating key events for the mouse.
    3) If what you are seeing is the Action you have bound to C is getting activated and not the actual C key on the Keyboard controller object (use Debug Information), then this could be some kind of controller mapping issue. If that's not the case, then it cannot be happening at the Rewired level and would be happening at the OS/driver/hardware level.

    If native keyboard handling is disabled or native input is disabled, the keyboard data comes from UnityEngine.Input directly -- two completely different code paths -- yet you're reporting the same issue. That points to an OS or hardware level issue.
     
  34. Josh1billion

    Josh1billion

    Joined:
    Apr 4, 2017
    Posts:
    6
    When I change my C# code while the game is running, Rewired seems to never reinitialize. What I mean by that is that "ReInput.isReady" is always false, until I stop the game and restart it. Is there a fix / way around that? (Unity version 2018.2.16f1)

    EDIT: Nevermind, finally got it working. There are a couple of parts to it, but the main thing is to put this before the code that polls Rewired for input:



    Code (CSharp):
    1.  
    2.         if (UnityEditor.EditorApplication.isCompiling)
    3.         {
    4.             return;
    5.         }
    6.  
    7.         if (!ReInput.isReady)
    8.         {
    9.             if (!reinitializing)
    10.             {
    11.                 reinitializing = true;
    12.                 Instantiate(prefabReinputManager);
    13.             }
    14.             return;
    15.         }
    16.  
    17.         reinitializing = false;


    The rest depends on your game. Basically, you will lose all your static variables' values whenever the reinitialization happens, so you'll need to set their values again if they're not set.

    EDIT 2: Wrote a blog post with a more thorough explanation here http://fordesoft.com/blog/posts/hot-reloading-hot-deployment-in-unity-when-using-rewired
     
    Last edited: May 5, 2019
  35. Carr77

    Carr77

    Joined:
    May 17, 2013
    Posts:
    7
    Hi,
    This is a great plugin. I'm very close to buying it. There's just one little thing I have a hard time figuring out:

    So I'm making a platform game where the player has a gun that needs to be rotated around smoothly to aim well. The dead zones are in the way, and need to be put to "radial" so no weird snapping happens when the player aims up or to the sides. There's an option to do this in the global settings. That's great, and I've changed it. Now to the problem.

    When an unkown controller is used, the dead zones are still there and the snapping still happens. After reading the documentation I found this:

    "This setting only applies to joysticks on recognized controllers."

    My question is basically: is there any other way to get smooth rotations on an unrecognized joystick? Is it possible to remove this snapping/dead zone issue for those controllers as well?

    Thank you!
     
  36. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    This is already outlined here:
    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#null-reference-during-recompile
     
  37. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    No because there is no way to know 2 axes represent a single joystick on an unknown controller. There is no metadata to know this. That's what controller definitions are for. Radial dead zones require you know the value of 2 separate axes to determine the final value of both.
     
    Last edited: May 6, 2019
  38. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    What you state in your blog post that Rewired must be reinstantiated after a recompile isn't true and the documentation is not incomplete about this topic. Rewired explicitly watches for and detects the editor compile state change and reinitializes itself, or perhaps some update to Rewired that broke this. I will have to look into it. If this is not working in some new version of Unity, then I will have to make a workaround for it. You are not supposed to have to reinstantiate Rewired after a recompile. It has never been required and is not supposed to be required now.
     
  39. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    I can find no issue with recompile causing isReady to never return to true EXCEPT in the following scenario:

    Do you happen to have the new Unity option Edit -> Preferences -> General -> Recompile After Finished Playing enabled?

    This is bugged due to a Unity bug and it's a known issue with no known workaround.
    1. When this option is enabled in Unity, Rewired will never be able to resume after a change in a script is detected.
    2. This is because Unity sets EditorApplication.isCompiling to True when a script change is detected regardless of the fact that the scripts will not actually compile until after Play mode is stopped.
    3. Rewired cannot know this. All it knows is EditorApplication.isCompiling just turned True and stayed True forever. As far as Rewired knows, Unity is still compiling, so it stays deinitialized forever, waiting for Unity to finish so it can initialize again.
    If you do not have this option enabled, then you have discovered some new, unknown vector for Rewired failing to respond to recompilation end that may be caused by some setting you have changed in Unity. I cannot reproduce the issue in my testing.

    Either way, your workaround, while it works, is a hack which is working around some kind of bug and certainly not the intended way of dealing with runtime compilation.

    To rule out some weird script execution order issue with the GameObjects in your scene, try recompiling while playing the Rewired/Examples/EightPlayers project at runtime.
     
    Last edited: May 6, 2019
  40. Josh1billion

    Josh1billion

    Joined:
    Apr 4, 2017
    Posts:
    6
    My setting is set to something else: "Recompile And Continue Playing"

    I'm not sure what else would cause it, but the one other developer I've talked to about this told me he also has always had trouble with hot reloading when using Rewired and just gave up on using hot reloading.
     
  41. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    That's the default setting. There should be zero issues doing this. Did you try the EightPlayers test? I can't really do anything about figuring out what might be happening without help by someone who is getting this issue because I cannot reproduce it.
     
    Last edited: May 7, 2019
  42. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Does rewired handle two identical joysticks in a reasonable way? I have two thrustmaster t16000m sticks, one for each hand.

    I have tried unitys new input system but although both sticks are detected, it seems like passing this info around wasn't given much thought, and requires some really ugly workarounds that invalidate most of the design benefits anyway. I hope they improve this at some point.


    In general, i wish to also use a throttle, rudder pedals, and two vr controllers. Do you see this as something rewired can easily support?

    Are people still buying rewired now that unitys input system is becoming available? I haven't been very impressed with it tbh but I'm concerned that rewired will be obsolete by the time i need it.

    Right now I just need to read my input devices, but in a few months I probably need to start looking at supporting other devices and having remappable controls and doing it properly. I target only windows.

    Some advice would be great :)
     
  43. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Depends on what your expectations of reasonable are.

    1) A Player can use as many Controllers as you want.
    2) Each Controller can have and save its own mappings if the user maps them in-game.
    3) You cannot define separate default mappings for 2 identical controllers to be assigned to the same Player in the Rewired Input Manager.

    Throttle and rudder pedals are no issue:
    http://guavaman.com/projects/rewired/docs/SupportedControllers.html#flight-controllers

    VR Controllers are their own beast. See the FAQ:
    http://guavaman.com/projects/rewired/docs/FAQ.html#does-rewired-support-vr-controllers

    Unity's new input system is not scheduled for final roll out until 2019.2. Anything before that is just a WIP.

    Download the trial and see if it fits your needs:
    http://guavaman.com/projects/rewired/trial.html
     
  44. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Can you explain briefly what that actually means in practice? Can I just create two players, called Left Hand Stick and Right Hand Stick? Can I assign different mappings to each stick as long as they are not default ones? Will I be able to add a Learn feature so my player can pick an action and then just move the button or switch on one of the sticks to have it get assigned? I had to jump through so many hoops with Unitys new system to do this that I had to bypass the entire action mapping stuff... :/

    What will happen then, do you see a continued use and future for Rewired?
     
  45. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    You have to understand how Rewired's Joystick and Controller Map works in order for me to explain it:
    http://guavaman.com/projects/rewired/docs/Controllers.html
    http://guavaman.com/projects/rewired/docs/ControllerMaps.html

    1. All Joysticks (non keyboard/mouse controllers) attached to the system are attempted to be matched to Controller Definitions to determine if the Controller has metadata that can be used to determine what it is and what the mappings, calibration, element names, etc. are on a specific platform + input source used.

    2. Joystick that have matching Controller Definitions are considered "recognized":
    http://guavaman.com/projects/rewired/docs/SupportedControllers.html

    3. The Rewired Editor provides a means to define default developer-defined Controller Maps for Controllers and Controller Templates. These Controller Maps will be loaded for a Player when a compatible Controller is assigned to it:
    http://guavaman.com/projects/rewired/docs/RewiredEditor.html

    4. The Rewired Editor allows you to create default Controller Maps for any recognized controller or the universal Unknown controller. These Controller Maps can be categorized through the use of Map Categories and Layouts.

    5. You assign to the Player which Controller Maps to use on the Players page of the Rewired Editor based on the Map Category and Layout.

    6. If when a Controller is assigned to a Player a compatible Controller Map is found in the Map Categor(ies) and Layout(s) specified for that Player to use, it will be loaded from the developer-defined defaults in the Rewired Input Manager.

    7. Since you can only assign Controller Maps to be loaded in a Player by their Map Category and Layout, if you have 2 identical Controllers assigned to a Player, it will load the same Controller Map for both of those Controllers. One solution if the game is 1-player is to just use two separate Players and have different default mappings for each. Otherwise, you just have to detect for the presence of the two identical controllers, hook the controller assignment event, and load Controller Maps in different Layouts for the two devices through a script.

    8. Saving / loading user data is an entirely separate layer and does not modify anything in the Rewired Input Manager. Data can be saved and loaded from XML or JSON, or you could scrape and save whatever data you want in whatever format you want manually.

    9. The default optional user data management component, UserDataStore_PlayerPrefs, can save separate user data for multiple identical controllers assigned to a Player.

    I have no plans to ever deprecate Rewired. I cannot predict what will happen to sales when Unity's system is fully released.
     
  46. AdamParker

    AdamParker

    Joined:
    Sep 29, 2017
    Posts:
    11
    Hey Guavaman!

    First I would like to say Rewired is by far the best asset I have ever bought for Unity, an absolute must have. In fact, it was one of my best buys ever, period. It is tremendously good, does everything I want it to do and much more. For the price, it's an absolute steal, and I cannot even imagine making games without it, especially multiplayer games

    However, I seem to be having a problem (which might be expected behavior, but seems weird).

    I have been using Rewired on my game for a very long time now, without updating it. Recently, since my game is coming close to the launch date, I decided to update Rewired, simply to have the latest version, expecting it to have better support for even more controllers. And the newer version seems to behave differently concerning a few things.

    On my game, the character input checking takes place in FixedUpdate. When I pause the game, I set Time.Timescale to 0, and I deactivate the "Player" controller map. When I unpause the game, I set Time.Timescale back to 1, and reactivate the "Player" controller map. In my previous version of Rewired, this worked perfectly fine. In this newest version, however, a problem pops up, but only when using buttons as a virtual axis.

    Consider an Action called "Action0", which has been mapped to an axis controlled by W (positive) and S (negative). Now, if I pause the game, press and release W, and then unpause, Rewired's debug tools show me the axis value as being 0 throughout the whole process (which is what I expect/want and happened in the previous version). However, immediately after unpausing, Rewired's GetAxis function returns descending values from 1 for a few frames. This does not happen when the same Action is controlled by an actual axis (such as a controller's analog). Since there seems to be a discrepancy between what the debugging tool shows me and what the GetAxis function returns, I thought perhaps this was not intended behavior.

    If I do the same process but press and release S, I get ascending values from -1. If I pause, press and release W, then press and release S, then unpause, I get 0. Note that, in this last case, the value immediately goes to 0, even if it was at 1 when I paused (in which case I would expect it to slowly go to 0, using the digital axis simulation).

    I apologize if I'm missing something. I did notice a chat about pausing causing unintended behavior in the last page and I did read through it, and saw that you addressed it in version 1.1.25.1. Perhaps it was something you did to address that that changed this behavior?

    Here is the code I used to test this on a separate project with nothing other than Rewired, performing the process above and comparing the Debug Logs and the Rewired debugging tool.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Rewired;
    5.  
    6. public class test : MonoBehaviour {
    7.  
    8.     public float input;
    9.     public Player player;
    10.  
    11.     void Start () {
    12.         player = ReInput.players.GetPlayer("SYSTEM");
    13.     }
    14.  
    15.     void Update () {
    16.         if (Input.GetKeyDown("space"))
    17.         {
    18.             if (Time.timeScale == 1)
    19.             {
    20.                 Time.timeScale = 0;
    21.                 player.controllers.maps.SetAllMapsEnabled(false);
    22.             }
    23.             else
    24.             {
    25.                 Time.timeScale = 1;
    26.                 player.controllers.maps.SetAllMapsEnabled(true);
    27.             }
    28.         }
    29.     }
    30.  
    31.     private void FixedUpdate()
    32.     {
    33.         input = player.GetAxis("Action0");
    34.         Debug.Log("Input: " + input);
    35.     }
    36. }
    Thank you for your time and attention.
     
  47. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Many different things are responsible for the results you're showing.

    1. I am going to assume you are referring to the Windows Standalone or Windows editor.

    2. Extremely old versions of Rewired (you didn't say what version) may not have had Native Keyboard Handling or Native Mouse Handling support which was added a very long time ago. Native Keyboard Handling and Native Mouse Handling do not function exactly the same way non-native Unity keyboard and mouse handling.

    3. When Time.timeScale is set to 0, Rewired cannot update anything in FixedUpdate. It is completely unable to update its functions, clear values, or check or update anything at all because Unity is not executing the Fixed Update loop. There is no special handling in Rewired whatsoever to handle the special case of setting Time.timeScale to 0 at this point. You are literally pausing Rewired's FixedUpdate loop when you do that.

    4. Using Native Keyboard or Mouse handling, the values are being queued up on the main thread before Update or FixedUpdate ever run due to how Raw Input messages are delivered. Values are queued for both Update and FixedUpdate at this time. The fact that Fixed Update cannot run to process them when Time.timeScale is 0 means these values stay queued until you set Time.timeScale back to 1 at which time they will be evaluated. (Most values in Rewired are stored as values and not actual events, but special handling is done to catch button down events so as to never miss those -- this is what is causing the issue. Axis values are not affected. An ancient version of Rewired may not even have this button down catching code.) If a button was detected as down anywhere in the queue when processed, it is considered down, resulting in button returning True for one frame if you pressed it while the Time.timeScale was 0 and then unpaused time

    5. Just like with Native Keyboard/Mouse Handling, extremely old version of Rewired did not have mutli-threaded input handling for XInput devices. Something similar happens here, again due to the fact there is no special case code for blocking input from being queued for Fixed Update when Time.timeScale is set to 0 and Rewired is unable to do its normal processing. Events are queued for FixedUpdate and processed after Time.timeScale is set to 1.

    6. The Action value ramping down after unpause when activated by a button/key is entirely due to the fact that your Input Behavior assigned to the Action in question has Digital Axis Simulation enabled:
    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#digital-axis-smoothing
    If you did not have this enabled, you would only see the Action's axis value (driven by a hardware button) become 1 for one single frame after being unpaused.

    I just had a long email support thread about this issue a few weeks ago with someone else discovering an edge case issue when pausing the game using Fixed Update and unpausing using Update. There is no solution to this but to add a lot of special case code to all the low-level input managers for all platforms / input sources to detect and explicitly manage what happens when Time.timeScale is set to 0 and when it is returned to 1. This is going to take some time to figure out and implement it across all the platforms and input sources Rewired supports, all of which work differently, which is why an update has not been released. So far I have only looked into Windows, XInput. There are also other possible side effects that discarding input events/values may have so everything with FixedUpdate will have to be thoroughly tested again in all possible usage scenarios.
     
    Last edited: May 8, 2019
  48. AdamParker

    AdamParker

    Joined:
    Sep 29, 2017
    Posts:
    11
    Hey Guavaman!

    Thank you for the fast and extensive support. It is very much appreciated.

    I apologize, I was indeed referring to standalone Windows builds and the Windows editor. I am also using Unity version 5.5.6. As for the previous version of Rewired I was using, it was 1.1.10.0.

    I understand what you are saying. My doubt was mostly because of the fact the debugging tool indicated one value and the function returned a different value. Does the debugging tool simply work differently? If so, is there a way to directly access the values being shown by the tool? I was also confused by the fact the value immediately jumped to 1; if the button returns true for only one frame when unpausing, and it was a digital axis, shouldn't it only approach 1?

    Another reason for my doubt was that I believed that, since the map was disabled during the Time.Timescale = 0 interval, nothing from that map would be queued in the first place, but I suppose that is not how it works.

    I understand that Rewired is a very complicated piece of software and this is not a trivial issue. I would understand if a "fix" wasn't even possible. For now, I am simply delaying turning on the map by one frame as an imperfect solution.
     
  49. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Thanks for the info.

    The Debug Information tool always runs in Update. Your game is consuming input in Fixed Update. Update and Fixed Update maintain their own independent values. That's the only way ButtonDown and ButtonUp can work in FixedUpdate. Update is not affected by Time.timeScale.

    You would think so. So I looked into it and here's why it does that:
    • If the underlying button feeding Action0 is True when paused, it records the digital axis simulation start time.
    • The frame you unpause it, digital axis simulation sees that the start time occurred a very long time ago, also sees that the underlying button value is still True, and calculates the current value to be a full 1.
    • The next frame, the underlying button value pops back to False and digital axis simulation starts decreasing the value based on gravity.
    The reason here is digital axis simulation is based on time since True or False, not a frame-by-frame addition/subtraction of value.

    However, when the Controller Map is disabled this "last state changed time" value should be being set then and the Action value cleared. This may be some new edge case requiring special code to handle. Is the Controller Map you're disabling the only one in the Player that maps this Action? Because if you have multiple Controller Maps in the Player that map the same Action, the Action itself will not be disabled/cleared when you disable only one of those owning Controller Maps. It is only disabled when all the Controller Maps in the Player that map it are disabled (no more contributors to that Action.)

    But this is not affecting the underlying Controller. The issue is happening at the low-level in the input source managers that feed the Controller element values. The result is the Controller button is returning a value of True on the first frame after unpause. The Controller Map isn't doing anything during that time. And the special handling in Rewired to silence Button Down events that occur to enable a Controller Map only affects Button Down events, it does not artificially silence Button On states. So in that 1 frame, Action0's button down value == false, but it's button on value == true. Being on, digital axis simulation applies. It's nothing more than cascading effects coming from the queuing down events while paused I explained before because no explicit handling was ever added to detect Time.timeScale being set to 0 and execute different code based on this fact.

    I was going to suggest something like that until I can figure out how to deal with it. FixedUpdate was never intended to be used for input or anything other than Physics by Unity. Making it work against its intended purpose isn't always straightforward. Also, consuming input in FixedUpdate isn't particularly beneficial since you do not gain any sort of increase in responsiveness at low frame rates when consuming input in FixedUpdate because of how it works, and in fact decrease responsiveness at high frame rates.
     
    Last edited: May 8, 2019
  50. AdamParker

    AdamParker

    Joined:
    Sep 29, 2017
    Posts:
    11
    Thank you for the response.

    I understand. I know all about the pitfalls of getting input in FixedUpdate; I had my own (dumb) reasons for doing it. It was simply the easiest solution to make it "play nice" with some other bits of code in the game, but it might be time to revisit that decision and make a more proper solution. However, I do want to discuss this:

    I am pretty sure. In the example code I was using to test it, for example, I was enabling/disabling all maps during the pause, which should, I expect, unequivocally disable the action. However, when unpausing, the value returned always immediately jumped to 1, -1 or 0, depending on the buttons pressed during the pause. In fact, I think this is the only difference in behavior between the previous version of Rewired I was using (1.1.10.0) and the current version, now that I think about it and check an older build; the "returning true" for one frame after the unpause always worked like so, but previously it merely acted as a contribution to the digital axis and worked like we expect it to, making the value approach 1, -1 or 0. This contribution was so minor it was barely noticeable when playing. However, on the current version, this causes an immediate spike in the returned value, which is much more noticeable in gameplay.

    I tested a bit more and this discontinuity in the digital axis simulation is definitely not caused merely by turning a map on and then off. However, if doing so together with setting Time.timescale = 0 as described above, these spikes happen. I don't know if this is something you are interested in looking into or not, of course.

    Again, thank you for the outstanding support.

    Edit: I forgot to mention that, even now, with my solution of delaying turning on the map for one extra frame, what happens is that when I turn on the map, the value immediately jumps to 0 (regardless of buttons pressed during the pause and the previous state of the input).
     
    Last edited: May 8, 2019