Search Unity

Rewired - Advanced Input for Unity

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

  1. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    Hi, I am having a strange issue where:
    1) A user remaps an action A to a new key that already is mapped in another action B.
    2) Then he tries to remap action B with any new key.
    3) Console throws this rewired issue: Message: "The Action Element Map must belong to the same Controller Map you are passing in"
    4) In the Rewired editor action B shows as it is still mapped to the original key.
    5) In debug information action B is not mapped anywhere (its not within the keyboardmap).

    Used this function:
    Code (CSharp):
    1. // Begin listening for input
    2.             inputMapper.Start(
    3.                 new InputMapper.Context() {
    4.                     actionId = rows[index].action.id,
    5.                     controllerMap = controllerMap,
    6.                     actionRange = rows[index].actionRange,
    7.                     actionElementMapToReplace = controllerMap.GetElementMap(actionElementMapToReplaceId)
    8.                 }
    9.             );
    Any ideas?
     
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    There is not enough information here for me to diagnose your problem.
    1. Where and how is controllerMap obtained?
    2. Where and how is actionElementMapToReplaceId obtained and stored?
    3. Are the two Actions in Map Categories that are set to conflict check?
    This error is only thrown if you pass in an ActionElementMap that does not exist in the ControllerMap you are passing in.

    The data in the Rewired Editor will never change based on what the user has changed. This data is static -- it cannot be changed at runtime. It is data created by the developer and used as the defaults when the application is launched. Saved data is not stored in the Rewired Input Manager -- it is stored in XML if you are using a UserDataStore-derived component such as UserDataStore_PlayerPrefs. When data is found to load from XML, it is used instead of the data stored in the Rewired Editor.

    Before or after the user tries to remap it? If your UI is showing something as mapped and that is not shown in Debug Information, then your problem is in your UI redrawing.

    If you are storing a copy of Controller Map somewhere and using that throughout your process, the Controller Map may become invalid and no longer used by the Player if the Controller Map is recreated by some step in your process.

    For me to properly diagnose this, I will need to see your entire code for remapping. A simple repro project would be better.
     
  3. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    Its obtained in an internal wrapper of mine with actions.
    Code (CSharp):
    1. public ActionElementMap GetActionElementMap(){
    2.         if (actionElementMap == null) {
    3.             foreach (ControllerMap controllerMap in GetRewiredInput().controllers.maps.GetAllMaps()) {
    4.                 if (controllerMap.ContainsAction (axisName)) {
    5.                     foreach (ActionElementMap mappping in controllerMap.GetElementMaps()) {
    6.  
    7.                         if (this.axisName.Equals (ReInput.mapping.GetAction (mappping.actionId).name)) {
    8.                             this.actionElementMap = mappping;
    9.                             return this.actionElementMap;
    10.                         }
    11.                     }
    12.                 }
    13.             }
    14.             return null;
    15.         } else {
    16.             return this.actionElementMap;
    17.         }
    18.     }
    I am attempting to modify an existing manual with the key bindings. In the above code axisName is the action name as a string.

    it is worth mentioning the cached variable this.actionElementMap is replaced in an on OnKeybindingChanged event to avoid wrong values.

    Yes all the categories have this checked.

    Strange as this ActionElementMap are retrieved as shown in the above code

    This happens exactly when the user remaps the action A before remapping action B. In the debug information Action A has the correct new value, Action B disappears.
     
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Are you storing this at some point and assuming it doesn't change? The ActionElementMap can be destroyed and recreated when a binding is changed meaning an old stored id value becomes invalid.

    Because you are checking if(actionElementMap == null), if your ActionElementMap was set at any time before (the previous mapping), it is no longer null and the new ActionElementMap for that value will not be retrieved.

    I don't think I'm going to be able to find your issue without the complete source code to the class(es) involved in remapping because this most likely has to do with storing and using an old value for something involved. To share this privately, please use the support form on my website.
     
  5. DOOManiac

    DOOManiac

    Joined:
    Mar 15, 2017
    Posts:
    3
    Hello @guavaman ! First, let me thank you for the best asset on the asset store. Rewired is fantastic and a joy to work with.

    I've been working on custom keyboard binding system via the InputMapper. I've got everything working except for replacing an existing binding. It seems my data.responseCallback(InputMapper.ConflictResponse.Replace); is not doing anything.

    I've looked at the two examples, SimpleControlRemapping.cs and ControlRemappingDemo1.cs, along with the documentation, and I seem to be using it as intended; just nothing happens. The only difference is that I want to always just replace the element right away.

    The rest of my code does work (i.e. if not overwriting, cancelling, or clearing a bind), so this is puzzling to me.

    Code (CSharp):
    1.  
    2. private void Start()
    3. {
    4.     player = ReInput.players.GetPlayer(0);
    5.  
    6.     inputMapper.options.checkForConflicts = true;
    7.     inputMapper.options.allowKeyboardKeysWithModifiers = false;
    8.     inputMapper.options.allowKeyboardModifierKeyAsPrimary = true;
    9.  
    10.     // ... unrelated things
    11. }
    12.  
    13. private void OnEnable()
    14. {
    15.     if (!ReInput.isReady)
    16.         return; // don't run if Rewired hasn't been initialized
    17.  
    18.     // Subscribe to our inputMapper events here!
    19.     inputMapper.InputMappedEvent += OnInputMapped;
    20.     inputMapper.ConflictFoundEvent += OnInputConflict;
    21.     inputMapper.StoppedEvent += OnStopped;
    22. }
    23.  
    24. private void OnDisable()
    25. {
    26.     inputMapper.Stop();
    27.     inputMapper.RemoveAllEventListeners();
    28.  
    29.     if (ReInput.isReady)
    30.         ReInput.userDataStore.Save();
    31. }
    32.  
    33. public void ResetBindings()
    34. {
    35.     // TODO: Ask player to confirm before doing this
    36.     player.controllers.maps.LoadDefaultMaps(ControllerType.Keyboard);
    37.     LoadBindings();
    38. }
    39.  
    40. // aem is the ActionElementMap for the bind we clicked in the UI
    41. public void Bind(ActionElementMap aem, string label)
    42. {
    43.     InputMapper.Context context = new InputMapper.Context()
    44.     {
    45.         actionId = aem.actionId,
    46.         controllerMap = aem.controllerMap,
    47.         actionRange = (aem.axisContribution == Pole.Negative ? AxisRange.Negative : AxisRange.Positive),
    48.         actionElementMapToReplace = aem // Replace self
    49.     };
    50.  
    51.     inputMapper.Start(context);
    52.  
    53.     ShowPopup(label);
    54. }
    55.  
    56. public void CancelBinding()
    57. {
    58.     inputMapper.Stop();
    59. }
    60.  
    61. private void OnInputMapped(InputMapper.InputMappedEventData data)
    62. {
    63. Debug.Log("MAPPED! " + GetFormattedKey(data.actionElementMap));
    64.     // Update this row in the UI
    65.     UpdateLabel(data.actionElementMap);
    66. }
    67.  
    68. private void OnInputConflict(InputMapper.ConflictFoundEventData data)
    69. {
    70.     if (data.isProtected)
    71.     {
    72.         if (data.assignment.keyCode == KeyCode.Escape)
    73.         {
    74.             inputMapper.Stop();
    75.         }
    76.         else if (data.assignment.keyCode == KeyCode.Backspace)
    77.         {
    78.             // Clear the binding
    79.             ActionElementMap aem = data.assignment.elementMap;
    80.             data.assignment.controllerMap.ReplaceElementMap(aem.id, aem.actionId, aem.axisContribution, KeyCode.None, ModifierKeyFlags.None);
    81.  
    82.             inputMapper.Stop();
    83.         }
    84.  
    85.         data.responseCallback(InputMapper.ConflictResponse.Cancel);
    86.     }
    87.     else
    88.     {
    89.         // TODO: This still doesn't work :(
    90. Debug.Log("CONFLICT! " + GetFormattedDescription(data.assignment.elementMap, data.assignment.action) + ": " + GetFormattedKey(data.assignment.elementMap));
    91. foreach(ElementAssignmentConflictInfo conflict in data.conflicts)
    92. {
    93. Debug.Log("> " + GetFormattedDescription(conflict.elementMap, conflict.action) + ": " + GetFormattedKey(conflict.elementMap));
    94. }
    95.  
    96.         // This doesn't seem to ever fire???
    97.         data.responseCallback(InputMapper.ConflictResponse.Replace);
    98.     }
    99.  
    100.     // Update the UI when we are done!
    101.     LoadBindings();
    102. }
    103.  

    The error is in the OnInputConflict() method. I know it's firing because I see the Debug.Log() right before it.

    I would greatly appreciate any advice on what I'm doing wrong here. Thanks!
     
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    You will never get a conflict if the only conflicting element is the same one you are replacing. That wouldn't make sense to trigger a conflict against the mapping you are replacing.

    Conflicts are only triggered if conflict checking to and against that Map Category is enabled from the other. See the Map Categories page: http://guavaman.com/projects/rewired/docs/RewiredEditor.html#MapCategories

    If OnInputConflict is executing, there is a conflict.

    What do you mean by "it doesn't seem to ever fire?" If you call that delegate, it executes immediately. Are you checking the Debug Information to see what ActionElementMaps are in your Controller Maps after calling it? Are you perhaps not updating your UI to display the new mappings?
     
    Last edited: Jan 1, 2018
  7. DOOManiac

    DOOManiac

    Joined:
    Mar 15, 2017
    Posts:
    3
    Thanks for the very quick response.

    The OnInputConflict() method DOES fire, as I get all the way to the Debug.Logs immediately preceeding the call to the responseCallback. After that, responseCallback seems to not do anything. The debug information panel (which is great BTW) seems to not show any changes.

    It's not a UI problem as I have tried saving the settings and going back into the scene, but the changes won't have been saved. This part does work if I am binding w/o any conflicts, so I have confidence in it.
     
  8. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    The responseCallback delegate immediately removes conflicts by calling player.controllers.conflictChecking.RemoveElementAssignmentConflicts on every Player designated for conflict checking (defaults to all Players.)

    The only way I will be able to determine the source of your issues is with a repro project. Testing conflict removal using the SimpleControlRemapping demo shows no issues, even when the conflict occurs across multiple Controller Maps and/or across multiple Players. Your particular setup is probably different in some way which I cannot identify without seeing the Rewired Input Manager.

    Please use the support form on the website to send me a repro project.

    In addition, check the console for messages and make sure warnings are enabled.
     
    Last edited: Jan 2, 2018
  9. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    How and when are you getting and storing value you are passing in for aem in the Bind method? The most common error people make when using Input Mapper is to store an ActionElementMap once when you first open the UI and assume it is still valid after changing a binding so it is not updated. Replacing a binding can create an entirely new ActionElementMap, so if you still have an old one stored after a mapping is created, it will be invalid. When you pass it into the Context, it will not be assigned to any Player.
     
  10. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    Hi @guavaman !

    Here are both classes on my side (input and controll change) handling this. There isn't much more to it I think. Maybe I need to add a conflict resolving event?

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using Rewired;
    5.  
    6. public class UIInputActionHelpTopic : MonoBehaviour {
    7.        
    8.     public Text actionName;
    9.     public Text keyBinding;
    10.     public Text actionDescription;
    11.  
    12.     private UIHelp uiHelp;
    13.     private InputValue inputValue;
    14.  
    15.     public void SetUp(UIHelp.HelpItem data, UIHelp uiHelp){
    16.         this.actionName.text = data.actionName;
    17.         this.keyBinding.text = data.keyBinding;
    18.         this.actionDescription.text = data.description;
    19.         this.inputValue = data.inputValue;
    20.         this.uiHelp = uiHelp;
    21.     }
    22.  
    23.     private void OnKeybindingChanged(InputMapper.InputMappedEventData eventData){
    24.  
    25.         uiHelp.HideKeyChangePopup ();
    26.         this.keyBinding.text = inputValue.KeysAsString ();
    27.         ReInput.userDataStore.Save ();
    28.     }
    29.  
    30.     public void ChangeKeyBinding(){
    31.         ActionElementMap actionElementMap = null;
    32.         //we should only allow none combo keys to be altered
    33.         foreach(KeyValue kv in this.inputValue.keysPressed){
    34.             actionElementMap = kv.GetActionElementMap ();
    35.             break;
    36.         }
    37.  
    38.         uiHelp.inputMapper.RemoveAllEventListeners ();
    39.         uiHelp.inputMapper.InputMappedEvent += OnKeybindingChanged;
    40.  
    41.         if (actionElementMap != null) {
    42.             uiHelp.inputMapper.Start (
    43.                 new InputMapper.Context () {
    44.                     actionId = actionElementMap.actionId,
    45.                     controllerMap = actionElementMap.controllerMap,
    46.                     actionRange = actionElementMap.axisRange,
    47.                     actionElementMapToReplace = actionElementMap
    48.                 }
    49.             );
    50.             uiHelp.ShowKeyChangePopup (this.keyBinding.text);
    51.         } else {
    52.             Debug.LogError ("Action " + this.actionName.text + " not mapped");
    53.         }
    54.  
    55.     }
    56. }
    57.  
    58.  


    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections.Generic;
    4. using Rewired;
    5.  
    6. public class KeyValue {
    7.  
    8.  
    9.     public readonly string axisName;
    10.     private static List<KeyValue> keyValueOptions;
    11.  
    12.     private static HashSet<string> keyAxisRepeatCheck;
    13.  
    14.     private string readableValue;
    15.  
    16.     private KeyValue(string axisName, string i18nBinding){
    17.         //safe check
    18.         if(keyAxisRepeatCheck == null){
    19.             keyAxisRepeatCheck = new HashSet<string>();
    20.         }
    21.         if (keyAxisRepeatCheck.Contains (axisName)) {
    22.             Debug.LogError ("axisName [" + axisName + "] already mapped!");
    23.         } else {
    24.             keyAxisRepeatCheck.Add (axisName);
    25.         }
    26.            
    27.         this.axisName = axisName;
    28.  
    29.         if (keyValueOptions == null) {
    30.             InitCollections ();
    31.         }
    32.  
    33.         keyValueOptions.Add (this);
    34.         this.readableValue = i18nBinding;
    35.     }
    36.  
    37.     private ActionElementMap actionElementMap;
    38.  
    39.     public void SetActionElementMap(ActionElementMap actionElementMap){
    40.         this.actionElementMap = actionElementMap;
    41.     }
    42.  
    43.     public ActionElementMap GetActionElementMap(){
    44.         if (actionElementMap == null) {
    45.             foreach (ControllerMap controllerMap in GetRewiredInput().controllers.maps.GetAllMaps()) {
    46.                 if (controllerMap.ContainsAction (axisName)) {
    47.                     foreach (ActionElementMap mappping in controllerMap.GetElementMaps()) {
    48.  
    49.                         if (this.axisName.Equals (ReInput.mapping.GetAction (mappping.actionId).name)) {
    50.                             this.actionElementMap = mappping;
    51.                             return this.actionElementMap;
    52.                         }
    53.                     }
    54.                 }
    55.             }
    56.             return null;
    57.         } else {
    58.             return this.actionElementMap;
    59.         }
    60.     }
    61.  
    62.     public override string ToString (){
    63.         ActionElementMap actionElementMap = GetActionElementMap ();
    64.         if(actionElementMap != null){
    65.             string combo = "";
    66.             if (actionElementMap.hasModifiers){
    67.                 combo += "'";
    68.                 if (actionElementMap.modifierKey1 != ModifierKey.None) {
    69.                     combo += actionElementMap.modifierKey1.ToString () + "'";
    70.                 }
    71.                 if (actionElementMap.modifierKey2 != ModifierKey.None) {
    72.                     combo += " + '" + actionElementMap.modifierKey2.ToString () + "'";
    73.                 }
    74.                 if (actionElementMap.modifierKey3 != ModifierKey.None) {
    75.                     combo += " + '" + actionElementMap.modifierKey3.ToString () + "'";
    76.                 }
    77.  
    78.                 combo += "' & '";
    79.             }
    80.             if (actionElementMap.keyboardKeyCode != KeyboardKeyCode.None) {
    81.                 combo += actionElementMap.keyboardKeyCode.ToString ();
    82.             }
    83.             if (actionElementMap.hasModifiers) {
    84.                 combo += "'";
    85.             }
    86.             return combo;
    87.         }
    88.  
    89.         return "Not mapped";
    90.     }
    91.  
    92.     private void InitCollections(){
    93.         keyValueOptions = new List<KeyValue> ();
    94.     }
    95.  
    96.     //Avoids skipipin frame issues on resting      
    97.     private bool keyAlreadyPressed;
    98.  
    99.  
    100.     public bool IsPressed(){
    101.    
    102.  
    103.         if (GetRewiredInput().GetButton (axisName)){
    104.             if (!keyAlreadyPressed ) {
    105.                 keyAlreadyPressed = true;
    106.                 return true;
    107.             } else {
    108.                 return false;
    109.             }
    110.         } else {
    111.             keyAlreadyPressed = false;
    112.             return false;
    113.         }
    114.     }
    115.  
    116.  
    117.     public static List<KeyValue> GetKeysPressed(){
    118.         List<KeyValue> keys = new List<KeyValue> ();
    119.  
    120.         foreach(KeyValue keyValue in keyValueOptions){
    121.             if (keyValue.IsPressed ()) {
    122.                 keys.Add (keyValue);
    123.             }
    124.         }
    125.  
    126.         return keys;
    127.     }
    128.  
    129.     private static Rewired.Player rewiredInput;
    130.  
    131.     private Rewired.Player GetRewiredInput(){
    132.         if (rewiredInput == null) {
    133.             rewiredInput = ReInput.players.GetPlayer (0);
    134.         }
    135.         return rewiredInput;
    136.     }
    137. }
    138.  
    139.  
    140.  
     
  11. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    Maybe its the way I am trying to find the elements as it allways gets only the mapped actions not the unmapped one. In this case I would need to add a mapping when the action is not mapped instead of replacing a map elements. Would this be correct?

    In this case I would need to rebuild the parameters here internally somehow:

    actionId = actionElementMap.actionId,
    controllerMap = actionElementMap.controllerMap,
    actionRange = actionElementMap.axisRange,
    actionElementMapToReplace = actionElementMap
     
  12. samfisher-ace

    samfisher-ace

    Joined:
    Jun 13, 2016
    Posts:
    4
    Hi @guavaman,

    I am using Rewired's custom controllers to update combo actions, in addition to normal keyboard and mouse maps. Some combo actions (in the custom controller map) are supposed to block other actions, so I have a per-frame cache to set a used flag. However, when testing, the blocked actions are fired for one frame before being blocked. Debugging shows that this is due to the combo update being late one frame.

    I am using Rewired 1.1.3 and CustomController.SetButtonUpdateCallback to update the combo values.
    The frame that both of the elements of the combo is down is e.g. 17539, while the callback that detects the combo being active is on frame 17540.

    Setting callback :
    Code (CSharp):
    1. ComboController.SetButtonUpdateCallback ( OnComboButtonUpdate );
    Callback :
    Code (CSharp):
    1. private static bool OnComboButtonUpdate ( int Button )
    2. {
    3.     var Value = false;
    4.     switch ( ( ComboAction ) Button )
    5.     {
    6.         case ComboAction.MoveForward :
    7.             Value = GameInput.Current.GetButton ( GameInputAction.Combo1 ) && GameInput.Current.GetButton ( GameInputAction.Combo2 );
    8.             if ( Value )
    9.             {
    10.                 GameInput.UseAction ( GameInputAction.Attack );
    11.                 GameInput.UseAction ( GameInputAction.Defense );
    12.             }
    13.             break;
    14.     }
    15.     return Value;
    16. }
    Wondering if I'm doing something wrong or the custom controller update is really one frame late. Thanks.
     
  13. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    In my case, I found a solution by adding a new mapping. Thanks for the patience.
     
  14. DOOManiac

    DOOManiac

    Joined:
    Mar 15, 2017
    Posts:
    3
    That was my problem. I was storing the AEM and then re-using it later, so I re-wrote things to not do that.

    I also found that if I called the responseCallback from inside OnConflict it never worked, but if I stored it in a member variable just as the example shows, and then call that w/ a Unity timeout 0.01f later, that works...

    Thanks for the point in the right direction!
     
  15. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    If you look at SimpleControlRemapping.cs, you will see how this is handled.

    Every time the UI is redrawn, the ActionElementMap id for each field is stored. If there is no existing ActionElementMap in the field, an id of -1 is used. When the field is clicked, null is passed as the actionElementMapToReplace argument if there is none to replace. This causes it to add a new ActionElementMap instead of replacing an existing one.

    I tried to create a repro project out of the code you sent but there are too many missing classes so I cannot see how you are handling things. Please provide me a repro case project and I'll be able to see exactly what is happening.

    (This post was written before you stated you solved your problem.)
     
    Last edited: Jan 3, 2018
  16. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    This is to be expected and there is no way around it. Here's why:
    • You are trying to combine the results of two separate Actions into one Action.
    • Actions values are calculated once per frame.
    • SetButtonUpdateCallback fires before Actions are calculated that frame. Getting the value of Actions in the SetButtonUpdateCallback means the values of the Actions are actually those of the previous frame. This could get really messy if you are updating in both Fixed Update and Update. If you are, you should not get the value of Actions in the SetButtonUpdateCallback and instead record the values in variables (one for Update and one for Fixed Update) which can be read in the proper callback for that update loop.
    • The result of this is that a Custom Controller element driven by the values of Actions will always be delayed by 1 frame.
    • Using code to evaluate button combos instead of piping it into a CustomController does not have this issue.
     
    Last edited: Jan 3, 2018
  17. djgriff

    djgriff

    Joined:
    May 29, 2014
    Posts:
    263
    I have a problem where the input is causing lag and frame drop considerably. if i dont touch the keyboard everything is fine. then if i move the player everything drop to like 12 fps ish... It doesn't happen every time i play but like 7 out 10 time.
    I did a deep profile, the results are as show in attached.

    There are no error outputs in the console.

    please see link: https://imgur.com/a/mCayj

    Any help greatly appreciated.

    Thanks

    Daniel

    Edit: this is a network game. Also it only happens when i change the speed variable on the bullet prefab some how messes everything up. But it looks like it is your asset for some really weird reason.
     
    Last edited: Jan 10, 2018
  18. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    1) What platform is this?
    2) What Unity version?
    3) What Rewired version?

    4) The link you have posted shows an image profiling the Application.LoadLevelAsync process. I don't see how this is relevant to your problem. LoadLevelAsync is only called when you are loading a level. If Rewired is doing anything during LoadLevelAsync, it is initializing itself if a Rewired Input Manager was present in the loaded scene and one didn't already exist in the current scene prior to loading. Initialization is a 1-frame process and is required. If you have a profiler image showing the slow-down during a frame that is not related to level loading, please post it.

    5) There is nothing in Rewired's code that could cause the framerate to drop when input is occurring.

    6) Are you using input events instead of polling? When an input event fires it will show up in the profiler as part of Rewired but in actuality it isn't because your callback code is being executed by Rewired and therefore is attributed to it. Comment out the code in the callback for moving the player and see what happens.

    7) How are you "moving the player?" Are you using the keyboard, a joystick, the mouse, a touch controller? If a joystick, which one and is it USB or Bluetooth?

    8) Is "Fixed Update" enabled in the Rewired Input Manager -> Settings -> Update Loops?

    9) Test using the example in Rewired/Examples/EightPlayers and see if you get the same result.

    Rewired does not do anything but provide input values and does not interact with physics or any other part of Unity. It's very likely some kind of error in your code that acts on the input values coming from Rewired.
     
    Last edited: Jan 11, 2018
  19. TiToMoskito

    TiToMoskito

    Joined:
    Jan 28, 2014
    Posts:
    34
    Do you plan to add Force Feedback for Logitech Wheels?
     
  20. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    There are no plans to add force feedback.
     
  21. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Rewired never calls UnityEngine.GetButton("Submit") which is exactly what the error you are reporting means. Some code in your project is calling UnityEngine.GetButton("Submit"), but it's not Rewired. Rewired only ever calls UnityEngine.Getxxx when not using native input or on platforms that always use Unity input such as Android, iOS, etc. Even so, when using Unity fallback, it only calls GetAxis on the various joystick axes and mouse buttons and axes generate by Rewired on install ("Joy1Axis1, MouseAxis1, MouseButton0), never on "Submit". This error you are seeing is generated by Unity's input system, not Rewired. Changing from Native input to Unity fallback input wouldn't change anything in this regard.

    "Submit" is one of the default Unity Input Manager entries created by Unity when you initially create your project. "Submit" is used by their UI system's StandaloneInputModule to allow you to press a button in the UI. The only way "Submit" could be missing is if you or some other plugin you installed deleted that input manager entry. Regardless, a missing "Submit" entry in the Unity Input Manager would not cause input to stop working in Rewired.

    Because your symptoms are so confusing, the only way you will be able to determine why input is not working is to debug it using Debug Information: http://guavaman.com/projects/rewired/docs/Troubleshooting.html#debug-information

    When using Debug Information, click back into the game window after interacting with the inspector before doing live control testing or you will always get 0 values due to the game window not being in focus.

    1) I don't know whether you are referring to keyboard, joystick, or mouse input. Check if values at the Controller level are being generated by looking at the Keyboard, Mouse, and individual joysticks in Debug Information -> Controllers -> CONTROLLER -> Buttons. Click back into the game window and press buttons and watch the values in the inspector. It will show you live information and you will be able to see if the button values are being retrieved.

    2) Check controller assignments. Debug Information -> Players -> PLAYER -> Controllers. Any Controller used by your Player must be assigned to it or it will not have any effect on Player Action values.

    3) Check Controller Maps: Debug Information -> Players -> PLAYER -> Controller Maps -> CONTROLLER TYPE. The Player must have a Controller Map that maps an Action or the Action will never have a non-zero value.

    4) Check live Action values: Debug Information -> Players -> PLAYER -> Actions. You can see the live value of Actions in a Player as you press buttons and move joysticks.

    Using these tools, you will probably find where the error lies. If everything looks good in Debug Information, then you can be sure your problem is in your code.
     
  22. nkcowmaster

    nkcowmaster

    Joined:
    Jun 28, 2013
    Posts:
    4
    Thanks for that, I realized what the issue was after digging deep into the documentation; I failed to replace the Unity Input Module with the Rewired Standalone Input Module. Thanks for your help on that though, and yes the Player Debug feature was very helpful in getting my Controller Map to switch from a Menu to Gameplay one. :)
     
  23. nkcowmaster

    nkcowmaster

    Joined:
    Jun 28, 2013
    Posts:
    4
    One other issue I am having, that I can't seem to find on the troubleshooting, is that whenever my scene reloads or changes, my Rewired breaks and I receive the following red error message spam:

    "Rewired: Rewired: An Exception occurred during update (Update). Rewired will attempt to continue running.

    When I test my Rewired Input Manager individually in each scene, it seems to be working great. It's just the moment the scene reloads is when I get the errors.
     
  24. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Are you using the trial version? The rest of the exception gives more information. Download the trial again and install over it.
     
  25. aftokinito

    aftokinito

    Joined:
    Jan 30, 2013
    Posts:
    10
    Hey @guavaman, may you please post a link to the issue "
    Windows, .NET 4.6 experiemental backend: Application freezes on exit" on Unity's issue tracker? This is being a quite annoying issue for me and I would like to keep track of it (and vote for it to demonstrate that it is a priority!)
     
  26. nkcowmaster

    nkcowmaster

    Joined:
    Jun 28, 2013
    Posts:
    4
    Yep, reinstalling the Trial fixed my issue! Thanks for your help, I have since hooked up my whole game to using Rewired and will be making my purchase very soon! :D
     
  27. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    I was told on 11/3/2017:

    --------------
    Hey,

    Thanks for reporting the issue.

    We have fixed this and problem will not appear in the next released version.
    If you are able to reproduce it on the next version of Unity, please respond to this email.

    We highly appreciate your contribution. If you have further questions, feel free to contact us.
    -------------

    When I followed up asking for an ETA, they couldn't give me one. The bug ticket is already set to closed.
     
  28. thePKPat

    thePKPat

    Joined:
    Jun 2, 2013
    Posts:
    6
    Unity 5.4.2f2
    I just imported the package into a blank unity project I got the dll library errors. So i changed the internal rruntime dll to run in editor as well (only standalone was checked).

    The problem is now that there is no Rewired option under the window tab. So I cannot install Rewired. Is this a known issue?

    Edit: I have used Rewired in 2017.2 on another project with no issues and it worked great. I installed rewired through the asset store so it should be the unity 5 version. It worked when installing it into Unity 5.6.2
     
  29. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    No, there is no issue like this. What DLL library errors are you referring to and on what build platform? How are you installing Rewired? Are you installing it from the Unity Asset Store? Make sure you download it again if you have both Unity 2017 and Unity 5 installed because both versions download the asset to the same folder. If you download in 2017 then go back to 5x and install without downloading again, it will install the Unity 2017 version in Unity 5.x which will not work.
     
  30. thePKPat

    thePKPat

    Joined:
    Jun 2, 2013
    Posts:
    6
    You are 100% right! I didn't know the asset store did that, learn something new every day about Unity.

    Thanks for the quick response and help, I love Rewired!
     
    guavaman likes this.
  31. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    Hi @guavaman!

    I am having the following issue. I use this to let the user do a remap:

    Code (CSharp):
    1.  
    2. inputMapper.options.defaultActionWhenConflictFound = InputMapper.ConflictResponse.Replace;
    3.  
    4. inputMapper.Start (
    5.                 new InputMapper.Context () {
    6.                     actionId = actionElementMap.actionId,
    7.                     controllerMap = actionElementMap.controllerMap,
    8.                     actionRange = actionElementMap.axisRange,
    9.                     actionElementMapToReplace = actionElementMap
    10.                 }
    11.             );
    I configured a map category with the none overridable bindings. In this case lets say I added to this category an action with the space key keybinding.

    How can I take control of the keychanging event when a user tries to override an action with space? I still want the ConflictResponse.Replace policy to work for the other key bindings.
     
  32. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    What are you trying to achieve here? Are you trying to block the user from mapping the Space key to an Action?
     
  33. DimeStudios_Dan

    DimeStudios_Dan

    Joined:
    May 4, 2015
    Posts:
    4
    Hi,

    Love the plugin. It's a godsend. Got a problem though, but if it's a known issue already just point me in the direction I should look.

    So using Rewired with a PS4 game, but run into a hitch. The Left Stick Y input is being inverted on PS4. Dualshock 4 on PC is fine. On the latest plugin (1.1.9.0)

    On Unity 2017 2.0p4, with the required PS4 extensions and relevant SDK 5.xxx. What's bugging me is that in Unity 5.4.5 and SDK 4.5xxx it was fine.

    Is this a problem caused by Rewired, a PS4 SDK change, a Unity change, or a combination? I'd really like to avoid having 2 different Dualshock 4 / InputManager configs that I have to percompiler flag in and out. Is there something I'm missing, or something you can patch in? <3
     
  34. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Have you checked whether this could be some mapping problem? You could be loading saved XML data. This is frequently a cause of some mysterious problems that show up in builds and not in the editor.

    Use Debug Information to see what's mapped:
    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#debug-information

    Check the live values from the controllers as well.

    If indeed this behavior changed, it would have to be one of the underlying dependencies:
    Unity
    PS4 SDK (dependency of Unity)

    Patching this is problematic. 1) I would need to know exactly what is causing it to be inverted and the exact version of Unity/SDK that changed the behavior. 2) Rewired does not detect or interact with the PS4 SDK directly in any way. I would have to be able to check the SDK version and hack in special case code to invert the axes.

    In addition, I would be extremely surprised if the left stick is inverted and the right isn't.
     
    Last edited: Jan 17, 2018
  35. DimeStudios_Dan

    DimeStudios_Dan

    Joined:
    May 4, 2015
    Posts:
    4
    Ok... I tried a bunch of stuff, compared it to projects that were working under the same settings and conditions etc... nothing would work.

    Finally I caved in, cleared everything out, reimported Rewired without exclusion and ran the installation.. and BAM worked straight away. So i'm guessing somewhere along the way, something was missing or incorrect. No idea how to reproduce though, but I'll pay attention to what examples and integrations I remove in case there's a correlation

    Cheers.
     
  36. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Good. It's possible Rewired's Unity input manager entries got changed somehow. If you go to the Unity input manager and look at Joy1Axis2 (assuming this was joystick 1), if Invert was checked, you'd get that issue. It would also happen if something modified Rewired's DualShock 4 controller definition for the PS4 platform.
     
  37. aftokinito

    aftokinito

    Joined:
    Jan 30, 2013
    Posts:
    10
    Hey @guavaman,

    I kinda resolved the issue by doing what a users suggested here (I guess this is the issue you were referring to on the tracker?): https://issuetracker.unity3d.com/is...41.1886304306.1516003877-422504201.1499787104

    However, I still have a problem that, when XInput support is enabled (with Raw Input), if I open more than 1 instance of the game at the same time, as long as there is a controller already connected the additional instances (after the firstg one) just hard crash throwing AccessViolationException referring to Xinput_1.dll, Xinput_2.dll and Xinput_3.dll. If I connect the controller after all instances have been started, everything works just fine. This means that for testing (I am working on a multiplayer game), I have to keep turning the controller on and off since this also affects the editor.
    I believe this might be related to "Windows Standalone (Use XInput enabled, Windows 10 Insider Preview): Game crashes when using or plugging in an XInput-compatible controller." but I am not on an Insider build (I'm on 1703, build 15063.786).
    What kind of logs would you like me to provide to work on getting this issue resolved?
     
  38. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,459
    This seems like a really nasty problem if you are not paying attention when switching between Unity 5.x and Unity 2017.x versions especially if you have a lot of different assets (e.g. UFPS, RFPS, etc) to build against for testing purposes. Did Unity do the same thing in 2018.x beta or did they create a new directory for assets instead reusing same asset folder for all 3 versions of Unity.
     
  39. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    Yes, that is correct. For this I added a map category with the space key with the user assignable toggle disabled
     
  40. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    The problem is not that this does't work, but that when I try to do an ilegal keybinding such as setting up space for another action, I have no way of controlling reacting to it (as I have the conflict check disabled to allow for regular replace policy)
     
  41. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22
    Something that I would like to do is the following:

    enable conflict checking on my code, then

    Code (Boo):
    1. private void OnConfictFound(InputMapper.ConflictFoundEventData eventData){
    2.  
    3. if(keybinding attempt on none assignable key){
    4.     re listen for another key input
    5. } else {
    6.     do regular replace policy
    7. }
    8.  
    9.     }
     
  42. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    I was not aware of this workaround. Unity is being forcibly quit using this method.

    Rewired is doing nothing that should cause an access violation. Communication with XInput is extremely simple with the XInput dll being called by p/invoke calls to the various XInput functions. There's no other way to do it from C#. I cannot reproduce this issue with any version of Unity, an Xbox 360 controller or an Xbox One S controller.

    I would suggest something else in your system may be causing this such as a virus scanner or some other memory resident program, some other plugin (such as Steam) doing something weird with memory, or something like that. Please test in a new project using the example scene in Rewired/Examples/EightPlayers.

    Unfortunately, with Rewired being 100% managed code, a crash dump or other native crash report really doesn't help at all in narrowing down where the problem may lie (if it's even in Rewired).

    I need all this information to be able to try to reproduce it:
    1. What version of Unity are you using?
    2. What version of Windows 10 are you using?
    3. What exact controller are you using? (Xbox One original mode, Xbox One 2nd edition w/ audio jack, Xbox One S, etc.) If Xbox One, are you using the latest firmware?
    4. How is this controller attached to the system? Are you using the old wireless dongle, the newer wireless USB plug, a wire connected to your system? Is there a hub involved?

    Basically anything you can possibly think of that might allow me to reproduce it. Even when reproduced, however, there is very little chance I can change anything in Rewired's code that will affect this issue.

    The only other thing I can do would be to make debug builds that would log everything that happens and use that to determine when it is crashing (again, assuming something in the Rewired code is causing it.)
     
    Last edited: Jan 18, 2018
  43. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    The only way you could do this would be to cancel polling when you hit a protected assignment and start polling over again. However, due to a bug I just found, this isn't super easy to do. So I've fixed this bug, but also added an InputMapper.ConflictResponse.Ignore option which will make it just continue to poll.

    Please contact me via the support form on my site and I'll send you a link to download the new release.
     
  44. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    I just tested and indeed it still uses %appdata%\Unity\Asset Store-5.x in Unity 2018. Yes, this is a particularly bad problem because it's almost impossible to figure out what's happening based on user's symptoms. It's just one of a billion things I always have in the back of my head from doing all this support that invariably involves debugging and supporting the seemingly limitless number of dependencies and/or loosely-related systems.
     
  45. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22

    K just did!

    Would the InputMapper.ConflictResponse.Ignore still replace the keybindings if there is a conflict involving valid user assignable keys?

    While we are at it, is there a easy way to clear all user changes without clearing all of the UserPreferences?

    Thanks!
     
  46. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Okay, I sent you the link.

    Ignore will not replace anything. It will just skip the conflict and continue polling. It's up to you to determine whether or not you want to replace it and send the command. If you do, you would not send Ignore, you would send Replace via the callback. Check the docs to see how to detect protected assignments, #6:
    http://guavaman.com/projects/rewired/docs/InputMapper.html

    ConflictResponse.Cancel will stop polling.
    ConflictResponse.Replace will replace the conflicting assignments and stop polling.
    ConflictResponse.Add will add a new assignment in addition to the conflicts and stop polling.
    ConflictResponse.Ignore will ignore the conflict and continue polling.

    No. This is the reason it is noted everywhere that mentions UserDataStore_PlayerPrefs (and in its own source code) that PlayerPrefs is not a good system and is not robust enough for every data storage need. PlayerPrefs cannot look up keys by a prefix. You have to know the EXACT key in order to see if it exists. This makes it impossible to store data by keys such as controller vid/pid, etc. if you want to be able to clear only the Rewired data. If all the data were saved under a single key and serialized as a gigantic string, this would be possible, but it's not due to size limitations on various platforms. PlayerPrefs is not the ideal storage solution, but it was used 1) to give you something good enough for most purposes 2) because it comes with Unity and works across all platforms and 3) as an example starting point for you to create your own UserDataStore system that uses a database or some other storage means.
     
    Last edited: Jan 17, 2018
  47. aftokinito

    aftokinito

    Joined:
    Jan 30, 2013
    Posts:
    10
    1) 2017.3.0f3
    2) 1709 16299.125
    3) Xbox 360 wireless controller for Windows
    4) The controller has its own USB dongle (it's a puck like thing with a USB cable on one end and a button on the other side)

    Sometimes, when I get both instances of the game to run by plugging the controller after starting the instances, rewired won't register any input from the controller but Windows will (from the control panel). Inside the editor, nity registers the controller as bieng attached via Unity's input system and Unity does register the controller's input via that system but not through Rewired (in the debug info of the Input Manager, all the buttons and axes are stuck at 0.0000 value)

    EDIT: Almost forgot, I am having the same problem with the demo you suggested as long as I open two instances of it. It only happens with the standalone player, by the way, the editor is fine.
     
    Last edited: Jan 18, 2018
  48. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Thanks for the information.

    A few notes:
    1. The Windows Control Panel tool measures input from Direct Input, not XInput. These are two separate input APIs and do not have any relationship to one another.
    2. Unity detects controller connections through detecting the HID device, also not using XInput here.
    3. For all controller elements except the L/R triggers in separate axis mode (axis 9/10 from what I remember), Unity gets the input from the HID device directly. XInput is only used for the separate axis triggers because these can only be obtained through XInput. Try pressing the triggers and see if they register values (not Axis 2, that's from taken from HID and is a single axis that is used for both triggers).
    4. Rewired's detection of XInput devices is taken directly from XInput by checking whether a controller is connected. You can see exactly what XInput is reporting by using the attached XInputTest.cs script. It will show on-screen the connected devices. This will tell you if XInput is the cause of these problems.

    Thanks. Are these 32 or 64 bit builds? Are they debug or release builds?

    Was this in a new project or not?

    Edit: Testing with Unity 2017.3.0f3, an Xbox 360 wireless controller with the same dongle as yours, and up to 8 running instances of builds (both 32 and 64-bit versions) shows no issues. I see I am running Windows 10 1703 15063.850 and you are running 1709 16299.125. Thus far I have not been offered the option to upgrade. I will see if I can get the download manually.
     

    Attached Files:

    Last edited: Jan 19, 2018
  49. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    22

    Hi Guavaman, I hope you answer this one quickly as I am on a tight schedule :S. I managed to fix most of the issues and even rewrite a simple wrapper of player prefs to enable me to reset all the keys:

    Code (CSharp):
    1. public class PlayerCustomDataHandler {
    2.  
    3.     [Serializable]
    4.     public class Data {
    5.        
    6.         public Dictionary<string, string> rewiredValues;
    7.  
    8.         public static readonly string DATA_FILE_NAME = "/saves/CustomData";
    9.  
    10.         public void Save(){
    11.             WriteToBinaryFile<Data> (GameManager.GetFilePath(DATA_FILE_NAME), this);
    12.         }
    13.  
    14.         public static Data LoadFromFile(){
    15.             Data d = null;
    16.             string path = GameManager.GetFilePath (DATA_FILE_NAME);
    17.             if (!File.Exists (path)) {
    18.                 d = new Data ();
    19.                 d.rewiredValues = new Dictionary<string, string> ();
    20.             } else {
    21.                 d = ReadFromBinaryFile<Data> (path);
    22.             }
    23.             return d;
    24.         }
    25.     }
    26.  
    27.     private static Data _data;
    28.  
    29.  
    30.  
    31.     private static Data data{
    32.         get{
    33.             if (_data == null) {
    34.                 _data = Data.LoadFromFile();
    35.             }
    36.             return _data;
    37.         }
    38.     }
    39.  
    40.     public static bool HasRewiredKey(string key){
    41.         return data.rewiredValues.ContainsKey (key);
    42.         //return PlayerPrefs.HasKey (key);
    43.     }
    44.  
    45.     public static string GetReviredString(string key){
    46.         if (HasRewiredKey (key)) {
    47.             return data.rewiredValues [key];
    48.         } else {
    49.             return null;
    50.         }
    51.         //return PlayerPrefs.GetString (key);
    52.     }
    53.  
    54.     public static void Save(){
    55.         data.Save ();
    56.         //PlayerPrefs.Save ();
    57.     }
    58.  
    59.     public static void SetRewiredString(string key, string value){
    60.         if (HasRewiredKey (key)) {
    61.             data.rewiredValues [key] = value;
    62.         } else {
    63.             data.rewiredValues.Add (key, value);
    64.         }
    65.         //PlayerPrefs.SetString (key, value);
    66.     }
    67.  
    68.     public static void ResetRewiredData(){
    69.         data.rewiredValues.Clear ();
    70.         Save ();
    71.     }
    72.  
    73.  
    74.  
    75.     /// <summary>
    76.     /// Writes the given object instance to a binary file.
    77.     /// <para>Object type (and all child types) must be decorated with the [Serializable] attribute.</para>
    78.     /// <para>To prevent a variable from being serialized, decorate it with the [NonSerialized] attribute; cannot be applied to properties.</para>
    79.     /// </summary>
    80.     /// <typeparam name="T">The type of object being written to the XML file.</typeparam>
    81.     /// <param name="filePath">The file path to write the object instance to.</param>
    82.     /// <param name="objectToWrite">The object instance to write to the XML file.</param>
    83.     /// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
    84.     public static void WriteToBinaryFile<T>(string filePath, T objectToWrite){
    85.         WriteToBinaryFile (filePath, objectToWrite, false);
    86.     }
    87.  
    88.     /// <summary>
    89.     /// Writes the given object instance to a binary file.
    90.     /// <para>Object type (and all child types) must be decorated with the [Serializable] attribute.</para>
    91.     /// <para>To prevent a variable from being serialized, decorate it with the [NonSerialized] attribute; cannot be applied to properties.</para>
    92.     /// </summary>
    93.     /// <typeparam name="T">The type of object being written to the XML file.</typeparam>
    94.     /// <param name="filePath">The file path to write the object instance to.</param>
    95.     /// <param name="objectToWrite">The object instance to write to the XML file.</param>
    96.     /// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
    97.     public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append)
    98.     {
    99.  
    100.  
    101.         using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
    102.         {
    103.             var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    104.             binaryFormatter.Serialize(stream, objectToWrite);
    105.         }
    106.     }
    107.  
    108.     /// <summary>
    109.     /// Reads an object instance from a binary file.
    110.     /// </summary>
    111.     /// <typeparam name="T">The type of object to read from the XML.</typeparam>
    112.     /// <param name="filePath">The file path to read the object instance from.</param>
    113.     /// <returns>Returns a new instance of the object read from the binary file.</returns>
    114.     public static T ReadFromBinaryFile<T>(string filePath)
    115.     {
    116.         using (Stream stream = File.Open(filePath, FileMode.Open))
    117.         {
    118.             var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    119.             return (T)binaryFormatter.Deserialize(stream);
    120.         }
    121.     }
    122. }
    123.  
    124.  
    This works very nicely on normal functions. Now when I use the ResetRewiredData() function, it only will work when I stop running the game and reload it.
    Using:

    Code (CSharp):
    1. ReInput.userDataStore.Load();
    2. ReInput.userDataStore.Save();
    Reverts the effect, meaning reloading the game has the not the mapping back to default.
    What am I missing here?
     
  50. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Is this part of a custom UserDataStore implementation? Or are you using both UserDataStore_PlayerPrefs and your supplemental class to store the keys? I don't see where you actually delete any PlayerPref keys.

    • If you have no user data to load, for example after you clear it, it won't find anything to load and therefore it's going to leave whatever data is currently loaded in the Player alone. That's why it hasn't reverted anything -- you aren't reverting, you are loading nothing.
    • UserDataStore saves data at various points. You can see this in the editor console. For example, when you unplug a controller, or when you close Control Mapper. After that, XML data is saved and the next time you run it, it gets loaded.
    • Look at the How To's documentation here. Use player.controllers.maps.LoadDefaultMaps to wipe all the current maps in the Player and load the defaults as defined in the Rewired Input Manager if you want to revert to defaults.
     
    Last edited: Jan 18, 2018