Search Unity

Rewired - Advanced Input for Unity

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

  1. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Which GetAnyButton are you using? Player.GetAnyButton, Controller.GetAnyButton, or ReInput.controllers.GetAnyButton?

    I'll guess player.GetAnyButton.

    player.GetAnyButton will only return true when moving the mouse if you have a Mouse Map assigned to that Player with the X or Y axis mapped to an Action. It can be mapped to ANY Action.

    When it says "This also applies to axes being used as buttons." this does not mean you have to explicitly set up the Axis as a Button. When Player.GetAnyButton is queried, it essentially works the same way as calling player.GetButton on every Action that exists. If an Action is mapped and Player.GetButton("ActionName") returns true, so will player.GetAnyButton. Even if you've mapped some axis-type Action to Mouse X like "Move Horizontal", this will still return TRUE when the mouse is moved because the player.GetButton("Move Horizontal") value returns TRUE. This is what it means by axes used as buttons. All Axes can be queried for both GetButton and GetAxis values. Likewise, all Buttons can be queried for both GetButton and GetAxis values.

    The key difference between player.GetAnyButton and the other two is that the Player version works on mapped Actions, not actual physical buttons. The description in the API reference states: "Player.GetAnyButton : Gets the button held state of all Actions. This will return TRUE as long as any button is held. This also applies to axes being used as buttons." The key part here is "Gets the button held state of all Actions."

    If you want to query for the actual physical buttons and not mapped Actions, you have to either use ReInput.controllers.GetAnyButton (if your game is 1-player, will query all joysticks, keyboard, and mouse buttons), or iterate through the Joysticks assigned to the Player and call Joystick.GetAnyButton on each.

    Code (csharp):
    1. foreach(Joystick joy in player.controllers.Joysticks) {
    2.     if(joy.GetAnyButtonDown()) return true;
    3. }
    The keyboard and mouse can also be queried individually for GetAnyButton.
     
    Last edited: Oct 20, 2016
    Exbleative likes this.
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    To summarize the previously mentioned Xbox One Controller issue for anyone else reading:
    • Windows 10 Anniversary Update carried with it a driver update for the Xbox One controller that caused a number of new issues.
    • Rewired was updated in version 1.0.0.95 to account for these changes and workaround some of the new issues.
    • It appears that it's still possible for the Xbox One controller to fail to work for some users when XInput is disabled for unknown reasons. This is not a mapping issue, but it appears to be that the device is inaccessible for reading at the Windows API level. There isn't any workaround for this issue (apart from using XInput).
    • The solution is to enable XInput. You will also get better device support along with vibration support and working L/R triggers when pressed simultaneously. However, if your game is > 4 player, only 4 XInput-compatible devices can be used at once. If your game is > 4 player and you want to support more than 4 XInput-compatible devices at once and therefore disable XInput, Xbox One controllers may or may not function properly until Microsoft fixes their driver.
    • Enabling XInput does not cause any problems with other controllers like flight sticks, racing wheels, etc. All non-XInput devices will continue to work properly.
    • Most users will never have these issues because Use XInput is enabled by default.
    There are still two known issues with Xbox One controllers on Windows 10 post Anniversary Update:
    These issues are at the Windows driver level and cannot be fixed by Rewired.

    And just to be clear since it seems there was some confusion, this Known Issue:
    Windows Standalone (Unity Fallback, Windows 10): XBox One controller has incorrect mapping
    does not apply unless you are using UnityEngine.Input as the input source (not recommended).
     
    Last edited: Oct 20, 2016
  3. devotid

    devotid

    Joined:
    Nov 14, 2011
    Posts:
    445

    Wow.... I have been using an OLD VERSION of Rewired and never had these new templates in there. I never knew that I had to only map one template and it will cover them all. EUREKA! It makes so much sense that its silly. Thanks for pointing this out for me. I was doing each one. YIKES. Once again. THANKS!

    I also really needed to read the XInput stuff as I was also having some users reporting things with XBone controllers.
    Kevin
     
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Controller Templates are explained in the docs here.

    If you've been making individual maps for all the gamepads you want to support... >_<
     
  5. camel82106

    camel82106

    Joined:
    Jul 2, 2013
    Posts:
    304
    Hello,
    if I add Action that has type Axis in Rewired editor. Three new options will show in input mapping screen. One with Action Description Name, one with Positive Name and one with Negative name.

    So you can map axis, it's positive and negative part. Is it possible to disable creation of this positive and negative row in Input screen? Or in ideal world disable only negative and keep positive etc?

    Thanks
    Peter
     
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    All options are shown in the Control Mapper inspector and in the inspector documentation.

    The only options for changing which axis fields shown are in the inspector right here.

    You cannot disable just the positive or negative side of an axis-type Action. That wouldn't serve any purpose. If you want only one field for an Action, change it to a Button-type Action instead of an Axis-type Action.
     
  7. agentc0re

    agentc0re

    Joined:
    Feb 28, 2014
    Posts:
    77
    Hello! I've been going through the documentation & how to's but I'm extremely confused still.
    I'm not sure if i'd be going about this the wrong way but here's what I'm currently trying to do, if there is a better way I'm all ears. :D

    https://gyazo.com/a9fde97c2ef0210de9ef18ec67997f2c

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4. using Rewired;
    5.  
    6. public class InvertMouse : MonoBehaviour {
    7.  
    8.     public Toggle toggle;
    9.  
    10.     public void Start()
    11.     {
    12.         // Auto Assign the Toggle UI To our toggle variable
    13.         toggle = gameObject.GetComponent<Toggle>();
    14.     }
    15.  
    16.     public void ToggleInvertMouse ()
    17.     {
    18.         if (toggle.isOn)
    19.         {
    20.             // Invert mouse
    21.             Debug.Log("Inverting Mouse");
    22.             //player.controllers.GetController<Joystick>(0);
    23.          
    24.         }  
    25.         else
    26.         {
    27.             // Do not Invert mouse
    28.             Debug.Log("Non-Inverted Mouse");
    29.         }
    30.     }
    31.  
    32. }
    What I don't understand is how I find the right stick y axis and set that to toggle to be inverted or not.

    I've found examples of inverting the axis but it seems like it's inverting all axis because it does not specify which stick and which axis.

    I'm really pretty new to all of this and would very much appreciate an example/help.

    What I think i need to do is:
    Get controller data
    get controller maps
    invert the axis the y-axis for the right stick.
     
  8. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    There are two ways to invert axes:
    1. Invert the hardware axis.
    2. Invert the ActionElementMap.

    These two methods are not equal.
    1. Hardware axis inversion will invert the axis for everything that may use that axis. This will affect all Actions bound to that axis.
    2. ActionElementMap inversion will invert the axis value for only that specific Action binding.

    In your example you first show an image and code attempting to invert the Mouse Y, but then go on to write about trying to get the Right Stick axis. I don't know which you are trying to achieve, so I'll assume the Right Stick Y.

    What you are trying to do -- invert a dual analog gamepad's hardware Right Stick Y axis programmatically -- is not directly possible because Rewired's Joystick is not based on a fixed-gamepad layout. Joystick is not a gamepad, instead it is a type-agnostic joystick with a sequential list of Axes and Buttons. Other input systems standardize all input into a single gamepad layout but Rewired does not. Rewired supports much more than just gamepads. You cannot, for example, get input by coding something like float value = Joystick.LeftStick.X. This isn't how it's done in Rewired. However, the user can easily pick a particular axis to invert or calibrate themselves through a UI as shown in Control Mapper.

    Rewired is based around the Player-Action paradigm, and therefore almost all input operations should be done using Actions, not the physical hardware elements of individual controllers.

    The best way to handle what you're trying to do is to invert the value of the Action by inverting the ActionElementMap binding the Right Stick Y, not the actual hardware axis itself. Examples of inverting ActionElementMap bindings is shown in the ControlRemappingDemo1 and Control Mapper source code.

    Process:
    1. Get the Controller Map in question for the device(s) in question. There are many methods for getting and enumerating Controller Maps here.
    2. Get the ActionElementMap bound to the Action you're tying to invert. ControllerMap contains many methods for iterating and getting contained ActionElementMaps.
    3. Set the ActionElementMap.invert property.

    A shortcut to the process:
    1. Get the first ActionElementMap found for a particular Controller that binds the Action in question.

    Code (csharp):
    1. ActionElementMap aem = player.controllers.maps.GetFirstAxisMapWithAction(ControllerType.Joystick, "Look Vertical", false);
    2. if(aem != null) aem.invert = !aem.invert; // toggle invert property
    Or use player.controllers.maps.AxisMapsWithAction to enumerate all ActionElementMaps with a particular Action if, for example, the player can use more than one joystick.

    However, realize that this inversion will not stick if the user switches to a different joystick. If that is your goal, to invert the value of that Action regardless of which joystick is used, you would have to invert the value outside of Rewired by inverting the final value you get for the particular Action in question. This way, you can have that setting stick when they change to a different joystick.

    There is no method that will invert all axes simultaneously.
     
    Last edited: Oct 21, 2016
    agentc0re likes this.
  9. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    I'm having problems getting my controller (Wireless xbox 360) working under Linux. I've just done a fresh install of Ubuntu 16.04. The controller connects to the wireless receiver, but no input in the game (although keyboard works fine). I'm not super familiar with Linux, but is there any additional drivers I need to install to get it working under Linux, or something I need to do in Rewired to get the controller working?

    The controller works as it should under Windows and OSX, the same build of the game just built for Linux is the only difference in settings.
     
  10. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Most likely reason:

    See the Supported Controllers page.

    Microsoft Xbox 360 Controller (Wireless) -- Linux (May have issues [5])

    5 On Android and Linux, the Microsoft XBox 360 Wireless Receiver shows up as 4 separate joystick entries. Only one of these joystick entries actually represents the joystick, but Rewired will see it as 4 separate joysticks. The user will have to manually choose from the 4 entries to determine the correct one that represents the XBox 360 controller.

    --------------------------------

    If your controller is showing up as 4 devices, then the first device was assigned to your Player and it has no input so therefore you're not getting any input in game.

    If this isn't the problem, the only way to be sure what the problem is is to log information so you know exactly what's happening. Is the controller not appearing at all? Then the problem is somewhere in Linux -- permissions, driver, etc. Is the controller appearing but it's not mapped? Then the controller may not be recognized with whatever driver comes with Ubuntu 16. Rewired is tested on Ubuntu 12 and 14.

    There's debug log info code for you to use on the Troubleshooting page.
     
    DMeville likes this.
  11. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    @guavaman Thanks for the detailed response! I'd added the logs and it turns out the controllers are being detected, but have no input like you said. I think from your explanation I have an idea of how to approach this now, thanks!
     
  12. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    No problem at all. We both appreciate the Rewired racing templates that much more because we both did the individual wheel mapping method previously. I also throw in the Rewired Flight Pedals Template too because some people use the CH Pro Pedals for racing games. Since CH Products explicitly states their pedals can be used for racing too. The CH Pro Pedals have blocks that eliminate the sliding effect in rudder pedals so it does quite well for racing too. Especially when you consider the very basic pedals that come with most low end wheels.

    http://www.chproducts.com/Pro-Pedals-v13-d-716.html

    QUOTE="devotid, post: 2827170, member: 72922"]I also really needed to read the XInput stuff as I was also having some users reporting things with XBone controllers.
    Kevin[/QUOTE]

    Since Microsoft has "some interest" in gaming I would hope they would do a better job on the XBOX ONE drivers in the future. Microsoft definitely has enough resources to do proper testing of the Microsoft XBOX ONE drivers before release.
     
  13. nathanjams

    nathanjams

    Joined:
    Jul 27, 2016
    Posts:
    304
    Hey Everyone,

    I have a really elementary scripting question here. I'm trying to make a script to enable and disable control maps. I'm trying to trigger the changes through an onShow slot from an Inventory Pro window. However, I can not get the onShow to connect to my script. If anyone could explain why this isn't working I'd be so thankful.

    using UnityEngine;
    using Rewired;

    public class ControllerDefaultDisable : MonoBehaviour {


    public int playerId;
    private Player player;

    void onShow()
    {
    player.controllers.maps.SetMapsEnabled(false, "GamePlay");
    }
    }
     
  14. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    I don't know how Inventory Pro works so I cannot tell you what you need to do in order to make that part work. I would post the question in the Inventory Pro forum thread.

    As for the Rewired part, I see nothing in the code that ever sets up the player variable. If that's all the code in your script, if the onShow method ever fires, you will just get a null reference exception because player was never set to anything. See How To's - Getting a Player for information.
     
  15. AshyB

    AshyB

    Joined:
    Aug 9, 2012
    Posts:
    191
    @guavaman what would be the best way to switch between two different rewired input managers? Is it as simple as having both in a scene and then disable one and enable the other?

    I'd like to use one manager for "on foot" running around on the ground and then another for when entering a vehicle. Just to keep them clean and separated.
     
  16. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Don't do this. That isn't how Rewired is meant to be used. You cannot disable one Rewired Input Manager and enable another one because all the static variables are only set up on initialization (Awake). They are not replaced when disabling/enabling. In short, it will fail catastrophically. You could destroy one and instantiate another, but destroying a Rewired Input Manager will completely de-initialize all Rewired objects and input sources invalidating all Player, Controller, and other objects and clearing events. Initializing a new one will require a re-initialization of the system and underlying input sources and is heavy on resource usage. It wouldn't be as big a problem if you were doing it after a level load, but I would not do it mid-game. The documentation states that one and only one Rewired Input Manager may exist in any scene.

    Action Catergories and Controller Map Categories have been provided for you to separate different gameplay tasks and organize your inputs.
     
    Last edited: Oct 26, 2016
  17. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    I wanted to let you know that the issues you were having with the Xbox One controller when not using Use XInput are due to YET MORE driver changes by Microsoft in an update after Windows Anniversary Update. They made some new changes that broke the triggering of my workaround made for the Windows Anniversary Update driver version. These driver changes made the device appear to Raw Input again (it didn't before), but as you mentioned no input is received for the device. These new drivers STILL do not work correctly in Raw Input. I'm making changes to my code to force the workaround in all cases. These changes will roll out in 1.0.0.105.
     
    RedRiverStudio likes this.
  18. docsavage

    docsavage

    Joined:
    Jun 20, 2014
    Posts:
    1,021

    Love this asset and totally recommend it to others I speak to. Works so well and some of best support on the store.

    Don't envy you though with the amount of work from all these companies changing stuff all the time.
     
    guavaman likes this.
  19. RedRiverStudio

    RedRiverStudio

    Joined:
    Sep 8, 2014
    Posts:
    136
    Thanks for the update. I have since been using XInput to handle the controller, which hasn't caused any real issues.
     
  20. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    That is definitely the right way to go. The only reason to not use XInput is if you need to support more than 4 Xbox controllers simultaneously.
     
  21. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Thanks so much! I'm glad you like it. I really appreciate the recommendations! :)

    Neither do I. :mad:
     
    docsavage likes this.
  22. NicoVar

    NicoVar

    Joined:
    Sep 21, 2012
    Posts:
    40
    Hi. I just purchased Rewired after reading all the docs.

    It seems to be an extremely powerful Command pattern system which will definitely prove to be useful.

    I have a quick question that didn't arise from the docs and couldn't find on the editor options:

    Q: If I wanted to create an actions that involves a mouse axis AND a key being press. For instance, Mouse Horizontal axis while the control key is being pressed. Is there a way to set rewired so it will only activate the action when those two conditions apply?

    I know I can check in the Action itself if the Control key is being pressed, but wanted to know if this is possible through the editor.

    Thanks, and great job.
     
  23. guavaman

    guavaman

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

    No, there isn't a way to bind multiple controller elements to an Action except keyboard key + modifier keys. The documentation covers recommendations on this:

    How To's - Handling Multi-Button Actions

    Handling multi-button Actions
    Rewired does not currently have a way to bind multiple Controller elements to a single Action except for keyboard modifier keys and indirectly through the use of Custom Controllers. To handle button combos, they should be handled in code based on your individual needs (timings, which needs to be pressed first, what cancels what out, etc). In these cases, it can help to think of it as if you're using Actions as buttons:

    Code (csharp):
    1. // This example shows a simple handling of a 2-button combo where the
    2. // modifier button must be held down and the primary button pressed
    3.  
    4. bool modifier = player.GetButton("ModifierAction"); // get the "held" state of the button
    5. bool primary = player.GetButtonDown("PrimaryAction"); // get the "just pressed" state of the button
    6.  
    7. if(modifier && primary) { // modifier was held or just pressed and primary was just pressed
    8. // Do something
    9. }
    The constituent Actions can be remapped by the user freely and nothing breaks. You also don't have to worry about the complexities of trying to allow the user to remap actual physical button combos for an Action and worrying about what else may already mapped to the constituent buttons. In addition, this kind of Action combo will work across multiple Controllers and Controller types since Rewired's Player-based input system is largely controller agnostic.
     
  24. NicoVar

    NicoVar

    Joined:
    Sep 21, 2012
    Posts:
    40
    I missed that. Thanks.

    One quick note. It appears in your RewiredStandaloneInputModule, not sure if its intended or not, but the list of player ids enabled to receive the UI input is not checked for all events. For instance, mouse works to click buttons and fields and type on them.

    Since I'd like to fully block UI access to non-playing players, I edited the script.

    I can't make a pull request to change that but here's what I'm doing on the Process method. Lines 4 through 15 below. Do you see any problems with this?
    Code (CSharp):
    1.         public override void Process() {
    2.             if(!ReInput.isReady) return;
    3.  
    4.             //---- Added
    5.             bool allow = false;
    6.  
    7.             for (int i = 0; i < playerIds.Length; i++)
    8.             {
    9.                 Rewired.Player player = ReInput.players.GetPlayer(playerIds[i]);
    10.                 if (player == null) continue;
    11.                 allow |= player.isPlaying;
    12.             }
    13.  
    14.             if (!allow) return;
    15.             //-----------------
    16.  
    17.             bool usedEvent = SendUpdateEventToSelectedObject();
    18.  
    19.             if(eventSystem.sendNavigationEvents) {
    20.                 if(!usedEvent)
    21.                     usedEvent |= SendMoveEventToSelectedObject();
    22.  
    23.                 if(!usedEvent)
    24.                     SendSubmitEventToSelectedObject();
    25.             }
    26.  
    27.             // touch needs to take precedence because of the mouse emulation layer
    28.             if(!ProcessTouchEvents()) {
    29.                 if(isMouseSupported) ProcessMouseEvent();
    30.             }
    31.         }
    Thanks.
     
  25. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    The behavior is intended. Mouse input is not handled by Actions. It's handled in the underlying unmodified PointerInputModule. Mouse clicks are based on the pointer position and directly checking the mouse buttons. It is not based on the Player Action system.

    Your code change will prevent mouse and touch events from working if no Player is set to isPlaying = true. If that's your intention, then I suppose it will work.
     
    Last edited: Oct 29, 2016
  26. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    However, if your intention is to add the ability to prevent non-playing Players from controlling the UI via keyboard/joystick, then the code you want to change is not in the Process() function, but rather in various places around the script such as SendSubmitEventToSelectedObject(), GetRawMoveVector(), and any method that queries input from all the Players. You would need to insert code each time as it loops through the Players to skip non-playing players. For example:

    Code (csharp):
    1.  
    2.         private Vector2 GetRawMoveVector() {
    3.             if(recompiling) return Vector2.zero;
    4.  
    5.             Vector2 move = Vector2.zero;
    6.             bool horizButton = false;
    7.             bool vertButton = false;
    8.  
    9.             // Combine inputs of all Players
    10.             for(int i = 0; i < playerIds.Length; i++) {
    11.                 Rewired.Player player = ReInput.players.GetPlayer(playerIds[i]);
    12.                 if(player == null) continue;
    13.                 if(!player.isPlaying) continue; // <- ADDED THIS LINE
     
  27. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    @NicoVar Here is a modified RewiredStandaloneInputModule that has support for allowing only playing Players to control the UI. There is a new toggle in the inspector to enable this: Use Playing Players Only
     

    Attached Files:

  28. catfink

    catfink

    Joined:
    May 23, 2015
    Posts:
    176
    I dropped you a support ticket but thought I would post here as well as it seems quite active. I've got full version of the code and my users are using a USB dongle that appears to have an 0X1a character in it's hardwareidentifier. This is causing havoc with the save of player prefs as it causes the convert to xml to fail and due to there being no try catch in place for exceptions we then take off down an uncontrolled exit of the code and my menu system end up in an inconsistent state.

    I've captured the exception to stop this happening but am left with a very popular USB device amongst my potential users that just doesn't work and effectively crashes my game (at the moment). I've tried to clean up the hardwareidentifier at save but it's heavily embedded in the underlying rewired classes and so my attempts at sanitation aren't working.

    This is the excerpt of code that fails:

    Code (CSharp):
    1.         private void SaveControllerMaps(Player player, PlayerSaveData playerSaveData) {
    2.             foreach(ControllerMapSaveData saveData in playerSaveData.AllControllerMapSaveData) {
    3.                 string key = GetControllerMapPlayerPrefsKey(player, saveData);
    4.                 PlayerPrefs.SetString(key, saveData.map.ToXmlString()); // save the map to player prefs in XML format
    5.             }
    6.         }
    7.         private void SaveControllerMaps(int playerId, ControllerType controllerType, int controllerId) {
    8.             Player player = ReInput.players.GetPlayer(playerId);
    9.             if(player == null) return;
    10.  
    11.             // Save controller maps in this player for this controller id
    12.             string key;
    13.             if(!player.controllers.ContainsController(controllerType, controllerId)) return; // player does not have the controller
    14.  
    15.             // Save controller maps
    16.             ControllerMapSaveData[] saveData = player.controllers.maps.GetMapSaveData(controllerType, controllerId, true);
    17.             if(saveData == null) return;
    18.  
    19.             for(int i = 0; i < saveData.Length; i++) {
    20.                 key = GetControllerMapPlayerPrefsKey(player, saveData[i]);
    21.                 PlayerPrefs.SetString(key, saveData[i].map.ToXmlString()); // save the map to player prefs in XML format
    22.             }
    23.         }
    It fails with an invalid xml exception due to the special character in the hardwareidentifier stored inside the USB device.
     
  29. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    No need to send it twice. I get and answer support emails every day as fast as they come in as long as I'm at my computer. As active as this forum is, email support is far more active and the better venue for support as I am able to collect vital information up front in the support form that is never posted here on the forum until I ask for it.

    I've investigated your issue and believe that the invalid characters are in the Joystick.hardwareName which is the HID product name provided by the HID device, not the Joystick.hardwareIdentifier. While the hardwareIdentifier does include the hardware name, the hardwareIdentifier is not ever used in the saving of the XML. The only place hardwareIdentifier is used in UserDataStore_PlayerPrefs is the Unity PlayerPrefs key itself, which is not saved to XML.

    I have added code to remove invalid XML characters from the joystick hardware name in the XML creation process. This will be included in the 1.0.0.105 update which will be posted sometime within the next few days. I can send you a beta via email if you'd like to try it now.
     
  30. catfink

    catfink

    Joined:
    May 23, 2015
    Posts:
    176
    perfect, thanks for the fast response .... yes, would like to try beta.
     
  31. Seiraniel

    Seiraniel

    Joined:
    Dec 23, 2014
    Posts:
    13
    I have a minor issue when loading a new scene. I'm working on a a 2D sidescroller and when I load a new scene while holding down the left or right button, ReWired says the button isn't pressed and it's released as a result. It doesn't happen all the time (which is weird) but it's somewhat annoying when it does. Is this normal or is there a way around this?
     
  32. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    What version of Rewired are you using? What operating system (Win/Mac/Linux/etc.) are you using?
     
  33. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Rewired does not clear any input values on level load, therefore the button would still be held down unless something else is clearing it. As @longroadhwy mentioned, platform and input source(s) are very important factors. If this is a UnityEngine.Input fallback platform or you have native input disabled, input values are dependent on Unity. Either way, there isn't any way around this because Rewired isn't doing anything to clear the input values and there isn't any way I can force them to stay as is if A) Unity is clearing it on a Unity fallback platform. or B) The underlying operating system is returning a non-press during the level load for some reason. You didn't mention whether this was a regular level load or an async level load either.

    If the underlying input source is not clearing the input, the only other possible way this could happen is if you are destroying and recreating the Rewired Input Manager on level load. If you have unchecked the option "Don't Destroy On Load" in the Rewired Input Manager inspector, re-check it.
     
    Last edited: Oct 30, 2016
  34. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    I sent you a link via email yesterday. Let me know when you download it.
     
  35. catfink

    catfink

    Joined:
    May 23, 2015
    Posts:
    176
    struggling to find the email, don't appear to have anything, have checked spam folder, nothing found??
     
  36. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    I have resent the email. I know you got my first email because you replied to me.

    Edit: The 2nd email bounced... Apparently it's not liking the fact that I'm sending you a link to Dropbox... PM'ing.
     
    Last edited: Oct 31, 2016
  37. catfink

    catfink

    Joined:
    May 23, 2015
    Posts:
    176
    My reported bug is fixed, very good support provided and super fast ..... nice when you get this sort of response from an asset developer, I'll certainly be recommending you off the back of this.
     
  38. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Glad it works!
     
  39. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Rewired 1.0.0.105 is now available for registered users to download on the website. If you'd like to register to receive early access to updates, please contact me here. The update will be available on the Unity Asset Store in 3-10 business days.

    Please be sure to read Updating Rewired before updating.

    1.0.0.105:

    Changes:
    - Windows Raw Input: Added support for CustomCalculation in axes and buttons in HardwareJoystickMap.
    - Windows Direct Input: Added support for CustomCalculation in axes and buttons in HardwareJoystickMap.
    - Added option to treat all hats as 4-way hats to Rewired Input Manager.
    - *** BREAKING CHANGE *** Changed Compound Element system so Compound Elements are defined per-device instead of per-platform. If you have created your own HardwareJoystickMap files, you must re-create all Compound Elements using the new system.
    - Windows Raw Input, Direct Input: Eliminated frame rate drop when connecting or disconnecting a Joystick.
    - Windows Raw Input: Yet more changes to work around new bugs in the latest Microsoft Xbox One driver update for Windows 10.
    - Windows Direct Input: Improved Bluetooth device disconnection for certain devices.
    - Added Use Playing Players Only option to the Rewired Standalone Input Module.
    - Invalid XML characters are now removed from hardware joystick name when writing ControllerMap save data to XML.
    - Moved export Action constants functionality to the Tools page of the Rewired Input Manager.
    - Added ability to export Map Category Id and Layout Id constants.

    API Changes:
    - Added Controller.Hat class.
    - Added CompoundControllerElementType.Hat.
    - Added ReInput.ConfigHelper.force4WayHats property.
    - Added Joystick.hatCount property.
    - Added Joystick.Hats property.

    New Controller Definitions:
    - Logitech WingMan Attack 2
    - Logitech Attack 3
    - Microsoft SideWinder 3D Pro
    - Microsoft SideWinder Precision Pro
    - Microsoft SideWinder Force Feedback Pro
    - Saitek ST290 Pro
    - Saitek Cyborg Evo

    Modified Controller Definitions:
    - All controllers with Compound Elements updated to use new system.
    - Added Hat Compound Elements to all controllers with hats.
    - Logitech G25, Raw Input: Added support for combined-axis pedal option in driver.
    - Logitech G27, Raw Input: Added variant for when no driver is installed, added support for combined-axis pedal option in driver.
    - Logitech G29, Raw Input: Added support for combined-axis pedal option in driver.
    - Logitech G29, Direct Input: Added mapping.
     
    Teku-Studios likes this.
  40. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    Wow. This is a nice update. Hope the asset store can release this tomorrow. Keep up the good work.
     
    guavaman likes this.
  41. camel82106

    camel82106

    Joined:
    Jul 2, 2013
    Posts:
    304
    Hello,
    I would like to add possibility to switch between predefined layours. Like lefthanded, righthanded. Simply actions are same, it has just different actions binding.

    I have tried to study this concept in Rewired and if I'm right, layouts may be right approach for this. What I'm missing is the ability to switch layout through control mapper. And load last used layout when starting game.

    As far I understand saving of different layouts is already there in UserDataStore_PlayerPrefs. What is missing is storing of actual layout used and switching to this layour on start of the game.

    Is it possible to direct me a little so I will be able to modify it? I cannot find a place where to inject selecting of last used layout. Or just add it to my game initialization script. And do something similar like it's described in howtos:
    Loading Controller Maps at runtime?

    Thanks!
    Peter
     
  42. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Do you have the skills required to be making an extension of UserDataStore? It should be pretty straightforward if so. If not, let me know and I will just do it for you.

    All you have to do is make new PlayerPrefs entries for each player, saving the current assigned layout id for each device/type. Add this to the Save routines. You'd also have to add the layout id to the Controller Map key string so you can save and load different layouts. Do the inverse for loading -- check the saved key for which Layout the user last used, then load the correct maps based on that.

    As for modifying Control Mapper, that would require more work. It's not within the scope of Control Mapper to support switching layouts at runtime.
     
    Last edited: Nov 1, 2016
  43. camel82106

    camel82106

    Joined:
    Jul 2, 2013
    Posts:
    304
    Well in this case I feel that I'm not skilled enough. So I would appreciate your help. Thanks

    Without modifying control mapper that means, that player wouldn't be able to change layout through control mapper GUI? (that's acceptable)
    Or I wouldn't even see reflected changes in control mapper if I would change layour at runtime.

    Best regards
    Peter
     
  44. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    It depends. Control Mapper has "suggested" Layouts which are set in the inspector for each controller type. When it loads a Controller Map, it cannot be guaranteed that a Controller Map will exist in the Player in a particular Category and Layout. Because of this, the suggested Layout is used to try to load a map in the Player for that controller type if it exists. If not, it will grab the first map it finds in that Category even if the Layout id doesn't match. If no map is found in the Player in that Category for any Layout id, then it will create a new blank map in that Category with the suggested Layout id. For this reason, even if your user is currently using the "Left-Handed" layout, if no Controller Map is found in that Player for that controller type when Control Mapper tries to load the maps, it will create one in whatever suggested layout id is set for the controller type. Control Mapper is extremely general purpose, so it cannot be predicted exactly how the developer will be using all the various parts of Rewired so there are limitations.

    One part that will not work properly is the "Restore Defaults" button. This button loads the user defaults from the maps set in the Player page of the Rewired Input Manager. This does not take into account the fact that you may have loaded a different layout into the Player. It simply reloads all the defaults set in the Rewired Input Manager.

    Re: Making UserDataStore_PlayerPrefs save the Layout

    This turned out to be nowhere near as straightforward as I originally thought. It's been a long time since I looked at the code of UserDataStore_PlayerPrefs. The system was made to fit the needs of Control Mapper and be very general purpose at the same time. Again, there are so many possible ways one could use the various systems in Rewired that there's nothing that will fit all possible needs.

    UserDataStore_PlayerPrefs works in a way that is incompatible with changing layouts at runtime. When Controller Maps are loaded from the XML data, it could not predict which maps should be loaded because there is no way to tell it what maps specifically should be loaded. Instead, it assumes that any and all compatible maps it finds should be loaded. This works perfectly well when you only have a single layout, but once you start wanting to save and load multiple layouts, the loading system breaks down because it will end up loading all your saved maps for all layouts into the Player. To solve this issue, there has to be something that tells it which Controller Maps to load. The only transparent solution is to use the currently loaded maps in the Player as a guide to tell it what you want to load along with a Layout Id override. This makes it so that the currently loaded maps tell it which category to load from and optionally the layout override tells it which layout to load from. Obviously this will not work for all purposes -- again, there's no such thing as one-size-fits-all, which is why the UserDataStore system is extendable so the developer can manage save data how he sees fit.

    The attached UserDataStore_PlayerPrefs_Layouts.unitypackage contains a new UserDataStore component that will save and load maps based on the current active layout.

    How to install it:
    1. Extract the Unitypackage into your project. It will create a new folder with a few new files.
    2. On your Rewired Input Manager, if a UserDataStore_PlayerPrefs component already exists, remove it.
    3. Add the new UserDataStore_PlayerPrefs_Layouts component to the Rewired Input Manager.

    How to use it:
    1. To set the current Active Layout for a particular controller type for a particular Player, set it through the new Rewired.LayoutHelper static class:

    Code (csharp):
    1. // Set the Active Layout for Joysticks to the "Default" layout
    2. LayoutHelper.SetActiveLayout(playerId, ControllerType.Joystick, "Default");
    This sets a flag for that Player for that controller type that the current Active Layout is the "Default" layout. When Load is called on UserDataStore, it will now use that Active Layout override to determine which map should be loaded. For example, if you change the Active Layout for Joysticks to "Left-Handed", the next time Joystick Maps are loaded for that Player, it will load the "Left-Handed" version of those maps if they exist in the Rewired Input Manager defaults or if they exist in the saved XML data. Loading of these maps occurs whenever a Joystick is plugged in or assigned to a Player through Control Mapper.

    By setting the Active Layout, it will override whenever a new map is loaded, but it does not by automatically change any existing maps in the Player. If you want to automatically switch maps to the new Layout, you have to call UserDataStore.Load. You can automate this by checking the "Reload on Active Layout Changed" toggle in the UserDataStore_PlayerPrefs_Layouts inspector. This makes it call Save() and then Load() immediately when you change the Active Layout through LayoutHelper. This can be used to make switching from one set of maps in one Layout to another Layout happen immediately with one call to LayoutHelper.SetActiveLayout.

    Notes:
    1.The Active Layout override settings are saved automatically every time Save is called in UserDataStore and loaded every time Load is called in UserDataStore. For example, Control Mapper saves at various times such as when pressing Done. If set to load data on start, Control Mapper will load the last Active Layout override settings on start.

    2. The Active Layout setting acts as a persistent flag that affects all devices of the type specified for a particular Player. If set on the Joystick controller type, even when a new joystick is plugged in, that joystick will also use the new Active Layout when loading its maps. This may or may not be desirable depending on your use case.

    Limitations:
    Because of the complexity and countless ways the developer may want to use Controller Maps, Categories, and Layouts, UserDataStore_PlayerPrefs_Layouts has limitations.

    1. Supports setting a single active layout id per-Player, per-device type. This acts as a layout id override so that when Controller Maps are loaded, they maps with the current active layout id will be loaded instead of the default layout id. This has the limitation of allowing only ONE layout id override per device type.

    2. Loads Controller Maps by comparing against the current Controller Maps found in the Player instead of loading all the maps found in the XML data. This makes it possible to load only the necessary maps in the correct layout id into the Player. Because of this, Controller Maps must not be cleared from the Player before loading or nothing will be loaded.

    I do not know your complete intended use case for using Layouts, but I have tried to make this as simple and as transparent to use as possible. I have tested it, but there could be cases that I have not tested or accounted for depending on how you intend to use it. Let me know of issues you run into.
     

    Attached Files:

    Last edited: Nov 2, 2016
    camel82106 likes this.
  45. Seiraniel

    Seiraniel

    Joined:
    Dec 23, 2014
    Posts:
    13
    I'm on the latest version of Rewired, Windows 10, Unity 5.4.2.

    It's a regular level load and the Rewired manager is checked as Don't Destroy On Load. I'll try debugging it some more later. Thank you for your answer.
     
  46. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    I looked back at your question again and you say " I'm working on a a 2D sidescroller and when I load a new scene while holding down the left or right button,". Left/right button being a keyboard key? If so, that could explain it. Keyboard keys are read from UnityEngine.Input.GetKey regardless of the chosen primary input source (Raw Input, Direct Input, Unity Input, etc.). If Unity clears inputs on level load, it would clear the keyboard key presses. You may also see a difference in the editor vs a build.
     
  47. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Anytime I add in a new action, all existing players do not have the key binding set for it. How can I fix this?
     
  48. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    Please see the documentation on the basic usage of Rewired. There is a wealth of information in the docs that covers just about every question and issue.

    Refer to the Quick Start guide on how to set up Controller Maps and assign them to Players.
     
  49. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    I have seen it. I've searched for this question, but have not been able to find any answers on it. Perhaps I'm searching for the wrong thing. To clarify, I have Rewired fully functioning in my game, and have for a while. The problem is if I add in a new action that was not previously there, then existing players do not have a key bound for it and they have to go to the controller settings and reset their controls.

    EDIT:
    Just found it, "Saved XML data is not updated when you make changes to the Rewired Input Manager"
    Why is this? This seems like it should be a basic feature, check if any new actions, get the actions default value, if that key is not bound to any other actions then assign it to the new action.
     
  50. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,632
    You must be using Control Mapper, which is important information to know when you're describing your issue. Rewired never saves any user data itself unless you are using the UserDataStore_PlayerPrefs component which is part of Control Mapper.

    By loading saved XML data, you are loading over any new "developer default" mappings set in the Rewired Input Manager. Saved XML data is entirely separate from the data in the Rewired Input Manager. If you make changes to the Rewired Input Manager settings after user data is saved, the XML data will become outdated. At this point, you must manage this data somehow -- delete it, flag it as outdated and don't load it, or some other management solution.

    It's stated in the UserDataStore_PlayerPrefs documentation that PlayerPrefs is far from the ideal data storage system and is only used for the most basic use cases. PlayerPrefs have no tools for listing key entries or searching for partial keys so you can manage save data intelligently. Instead, the only solution when using PlayerPrefs is wipe the PlayerPrefs so that all save data is cleared and you can start afresh. This is an inherent limitation to PlayerPrefs and is why the documentation recommends implementing a better data storage system that will meet your specific needs such a database, etc.

    What would be needed is some kind of XML data analysis and merging system. This cannot be included by default because there's no way to know the user's intentions or the developer's needs in this regard. Trying to merge changes to user default mappings and saved XML mappings would be incredibly complicated and prone to all kinds of errors.

    For example, lets say we have a simple system that looks at what the user currently has mapped and finds new mappings in the Rewired Input Manager to make those new mappings appear:
    • User intentionally deletes some Action mapping in a Controller Map.
    • Next time system loads XML data, it compares the developer defaults to the loaded XML data and sees a mapping missing and replaces it.
    • Now the user has the mapping back they deleted before.
    Also, replacing a missing mapping assumes that element hasn't already been mapped on some other Controller Map that is enabled. You can have any number of concurrent Controller Maps enabled at once. You could run into having the same elements mapped on multiple Controller Maps if it add these mappings because it saw they were missing. Another example -- If your new Action mapping is set to, say Button 1, but the user has already mapped something to that button, the user mapping and your default mapping would conflict. Or if you have something on another Controller Map that is mapped to that same button that can be used at the same time, this could also cause problems. How all this should behave is very much up to the developer's needs in their particular implementation of Rewired. There is no universal standard on how to handle assignment conflicts and no universal standard on how the developer will use the Controller Map system.

    There are tons of other possible problems that arise when trying to come up with some kind of automatic, transparent data analysis and merging system that works for every or even most use cases. That is why this is left up to the developer to implement if they need this kind of feature.

    Off hand, I can think of no way to do something like this without:
    1. Replacing PlayerPrefs with a better system.
    2. Having a data versioning system on every saved controller map, and probably on every individual mapping change.

    Data versioning would be done by the developer at the time they decide to make changes to the input system and roll out an update with their changes to users.

    It's a very complicated problem, but becomes staggeringly complicated when trying to make something that automatic, transparent, and works for all use cases.
     
    Last edited: Nov 6, 2016