Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Rewired - Advanced Input for Unity

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

  1. _eternal

    _eternal

    Joined:
    Nov 25, 2014
    Posts:
    169
    All right, I'm back again after investigating this a bit. This is the error message I'm getting in the Player.log, which apparently just means that the build is corrupted somehow, as you had guessed.

    Code (CSharp):
    1. The file 'C:/Users/eternal/Desktop/asdf/Monospaced Lovers_Data/level0' is corrupted! Remove it and launch unity again!
    2. [Position out of bounds!]
    I've narrowed the problem down to the RewiredStandaloneInputModule component. The game builds correctly if I remove this component. Technically, the Rewired error messages that I mentioned before still appear, but at least the build works without getting corrupted. The only way to make those error messages go away way to delete RewiredStandaloneInputModule.cs from the project entirely.

    However, I still can't reproduce the problem in an empty project.

    Is there anything I can do to "reset" whatever is broken? I've already tried
    - Remove and rebuild entire Library folder
    - Delete Rewired and re-import
    - Delete Rewired package from AppData/Roaming and re-download, then re-import
    - Delete PlayerPrefs via the debug button on the InputManager component
    - To answer your previous questions: no, I haven't changed any settings about excluding assemblies

    I already filed a bug report with Unity, but they haven't replied yet. I'm just trying to figure out why it would only affect one project and not another, even when I've narrowed it down to a single component.
     
    Last edited: Jul 22, 2021
  2. Barliesque

    Barliesque

    Joined:
    Jan 12, 2014
    Posts:
    78
    @guavaman

    I'm running into a problem building with il2cpp...
    I've come across an older post where something similar was happening -- related to obfuscation in the Rewired dll. Hoping you can offer a quick solution!

    The project is on Unity 2019.3, building for Windows.
     
  3. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    That is very weird. Rewired is just DLLs, scripts, MonoBehaviours, and Scriptable Objects. There isn't anything to be "reset" that Rewired manages or has any control over. It sounds like data corruption in the scene file or something. That's not something I have any knowledge of or the ability to cause or fix as an asset developer. All I can really do is make guesses. Delete the GameObject that contained the RewiredStandaloneInputModule, save the scene, quit the editor, launch it again, recreate the object and try again. If it's the scene, I would expect building a different scene like one of the examples that comes with Rewired that uses Unity UI should work.

    If something were corrupted with Rewired's serialized data, deleting Rewired and reinstalling it would have fixed it. You did that. The symptoms don't match with that cause anyway. You would be getting errors logged by Rewired about controller data files being missing or corrupt if that were the case.
     
    Last edited: Jul 22, 2021
    _eternal likes this.
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    There's a notice at the very top of the documentation page. The solution can be found there:
    https://guavaman.com/projects/rewired/docs/

    notice.png
     
    Last edited: Jul 22, 2021
  5. Barliesque

    Barliesque

    Joined:
    Jan 12, 2014
    Posts:
    78
    @guavaman Huzzah! Disabling the VS2019 optimizer did the trick! Thank you.
     
  6. sk1zZ

    sk1zZ

    Joined:
    Mar 30, 2015
    Posts:
    6
    Thanks! That example helps a lot!
    Everything else works like a charm except axis movement remapping. Spent a whole day and still don't know what is going on.
    All buttons remap correct, include joysticks, but axis buttons for movement behave weird. If I remap bottom direction, Rewired assign it top direction. Same for right direction. I checked "actionElementMapToReplace" in Context just after i've started InputMapper and map's element setted right. But in "OnInputMapped" event "data.actionElementMap" has top direction action from keyboard map. Same information is displayed in debug window in Rewired Input Manager (screenshot attached).
    Any ideas why it's happening?
     

    Attached Files:

  7. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    You must not be providing the correct Action Range in the Context.

    https://guavaman.com/projects/rewired/docs/InputMapper.html

    Capture.PNG

    The SimpleControlRemapping example works. Read the source code of the SimpleControlRemapping.cs example and compare it to what you have.
     
    sk1zZ likes this.
  8. TeohRIK

    TeohRIK

    Joined:
    Jan 22, 2014
    Posts:
    105
    Hi, wanna ask something regarding to Touch Joystick. Is it possible to disable the joystick control and enable the tap only?

    Thanks
     
  9. sk1zZ

    sk1zZ

    Joined:
    Mar 30, 2015
    Posts:
    6
  10. idibil

    idibil

    Joined:
    Oct 10, 2015
    Posts:
    20
    Hello guavaman,

    I am using a 3d inventory system, where you access to the items placing the mouse on a item and click on it.

    I used raycast with the mouse coordinates, and this is working well, but the pointer system used for gamepad with rewired use different coordinates and when I try to get them, for some reason it gets on items from wrong position.

    Is there any fast way to get pointer coordinates? Now, I am trying from UIPointer Script, here the code:

    Code (CSharp):
    1.         public void OnScreenPositionChanged(Vector2 screenPosition) {
    2.             if(_canvas == null) return;
    3.  
    4.             // Get the rendering camera the current Canvas render mode
    5.             Camera camera = null;
    6.             switch(_canvas.renderMode) {
    7.                 case RenderMode.ScreenSpaceCamera:
    8.                 case RenderMode.WorldSpace:
    9.                     camera = _canvas.worldCamera;
    10.                     break;
    11.                 case RenderMode.ScreenSpaceOverlay:
    12.                     // leave null
    13.                     break;
    14.             }
    15.  
    16.             // Convert screen-space point to local space point
    17.             Vector2 point;
    18.             RectTransformUtility.ScreenPointToLocalPointInRectangle((transform.parent as RectTransform), screenPosition, camera, out point);
    19.  
    20.             // Apply to transform position
    21.             transform.localPosition = new Vector3(
    22.                 point.x,
    23.                 point.y,
    24.                 transform.localPosition.z
    25.             );
    26.  
    27.             if (raycastScript != null)
    28.             {
    29.                 raycastScript.pointerPoint = new Vector3(point.x, point.y, 0f);
    30.             }
    31.  
    32.         }
    33.  
    34.         }
    Where the ray cast:

    Code (CSharp):
    1.     private void GetRayCast()
    2.     {
    3.  
    4.         controller = Rewiredplayer.controllers.GetLastActiveController();
    5.         RaycastHit hit;
    6.  
    7.  
    8.         if (controller != null && controller.type == ControllerType.Joystick)
    9.         {
    10.                mouseRatioX = (Screen.width / 2) + pointerPoint.x;
    11.                mouseRatioY = (Screen.height / 2) + pointerPoint.y;
    12.                CustomPosition = new Vector3(mouseRatioX, mouseRatioY, 0); //this work but with some items it active from wrong positions
    13.         }
    14.         else
    15.         {
    16.             CustomPosition = ReInput.controllers.Mouse.screenPosition; //this works great
    17.         }
    18.  
    19.         Ray ray = new Ray(cam.transform.position, cam.ScreenPointToRay(CustomPosition).direction); //Event.current.mousePosition
    20.  
    21.         if (Physics.Raycast(ray, out hit, maxSelectionDistance))
    22.         {
    23.             Debug.DrawLine(cam.transform.position, hit.point, Color.red);
    24.             Debug.Log(hit.point);
    25.             if (hit.collider != null && hit.collider.GetComponent<Item>() != null && hit.collider.GetComponent<Item>().enabled)
    26.             {
    27.  


    What is I missing? Or do we have anything as ReInput.controllers.Mouse.screenPosition for the gamepad pointer?
     
  11. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    That is definitely not an intended use case. Leave the Horizontal and Vertical axis targets set to None.

    But what would be the point in doing this over using a button?
     
  12. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    You're taking a value that was transformed into Canvas space and trying to use it as if it were a screen pixel value. This is not going to work. The function you're using OnScreenPositionChanged is receiving a screen pixel value in the first place which it then transforms. Store the unmodified screen position and use it. You don't need to branch code between mouse and joystick controllers. They work exactly the same.

    Code (csharp):
    1. public void OnScreenPositionChanged(Vector2 screenPosition) // screenPosition is a screen pixel position -- exactly the value you want

    PlayerMouse returns a screen pixel position in OnScreenPositionChagned as well as exposing it through the PlayerMouse.screenPosition property.
     
    Last edited: Jul 23, 2021
  13. idibil

    idibil

    Joined:
    Oct 10, 2015
    Posts:
    20
    Yes, that was. Thank you so much, Guavaman!
     
  14. TeohRIK

    TeohRIK

    Joined:
    Jan 22, 2014
    Posts:
    105
    Oh thanks for reply. Cause for some cases I want to disable the directional aiming.
     
  15. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Changing the Axis Calibration would also be a hack that should work. Set the dead zones to 1.
     
    TeohRIK likes this.
  16. ch1ky3n

    ch1ky3n

    Joined:
    Oct 26, 2017
    Posts:
    40
    Alright, I'm using rewired just fine until yesterday I notice a playmaker actions of "Rewired Action Element Map" there are lots of them. I'm thinking of exploring what do these actions are for and I have no idea at all. Try to google it but nothing avail. Can Mr. Guavaman give me one example of how to use this. I believe I can work out from there.

    What bugging me is the ActionElementMapId, How to find my ActionElementMapID?
    cuz it seems this is why I didn't get any input from all of these actions.

    Thank You for this super dupper asset
     
  17. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    If you want to know how to use Rewired, ignore the fact you are using Play Maker. You're not going to find PlayMaker documentation for Rewired. Look at the normal Rewired documentation and see if one of the functions you want to use has an equivalent PlayMaker Action:

    From the PlayMaker integration documentation page:

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

    Documentation:

    There is no PlayMaker-specific documentation. PlayMaker Actions are direct analogues to the methods, properties, fields, and events in the Rewired API. All the standard Rewired documentation applies.

    For example, the Rewired API method:
    player.GetButtonDown

    Corresponds directly to the PlayMaker Action:
    RewiredPlayerGetButtonDown

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

    ActionElementMaps are part of the Controller Map system. https://guavaman.com/projects/rewired/docs/HowTos.html#managing-controller-maps-runtime

    They are explained visually in the last diagram on this page:
    https://guavaman.com/projects/rewired/docs/ControllerMaps.html

    These Actions have very little use when using PlayMaker. You can basically just see various information about the bindings in a Controller Map. You can't do elaborate things with them such as is required to make your own custom control rebinding system. That is not doable using PlayMaker Actions as most of the rebinding API is not exposed through PlayMaker Actions.
     
  18. TeohRIK

    TeohRIK

    Joined:
    Jan 22, 2014
    Posts:
    105
    Hi, thanks for the tips, setting dead zone to 1 doing the trick, but it cause some weird animation

    deadzone joystick.gif
     
  19. Barliesque

    Barliesque

    Joined:
    Jan 12, 2014
    Posts:
    78
    I'm looking to match some actions to a couple of controls on the HOTAS Warthog Joystick. Among the numerous controls mapped, I don't see anything that appears to be what I'm looking for--but then these buttons seem to have a few different names depending on who you ask. I'm looking for the "Trim Switch" and the "TMS" switch, pictured here:



    Are they perhaps already mapped under different names, or do I need to map them myself?
     
  20. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,498
    Those controls are not named like that. You should build a the control mapper demo and then it is really easy to figure out the names of the controls as you press them.

    https://guavaman.com/projects/rewired/docs/ControlMapper.html
     
    Barliesque and guavaman like this.
  21. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
  22. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    It's not clear whether you're asking about mapping the Warthog directly or using the HOTAS Template.

    All the labeling of the joystick elements is based on a physical descriptions, not functionality. You will see "Trigger", not "Fire", for example.
     
  23. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Setting the Touch Joystick X and Y axis dead zones to 1 results in the axis value never changing from 0. The stick disc can't move at any time from the center because the stick disc position is determined by the axis value of the Custom Controller axis it's bound to. I just tested it and it works as expected. You must be doing something else that is causing the disc to move like setting the axis values externally, setting the value in the Custom Controller through another means, or perhaps you made some kind of change to the Unity UI object structure that no longer conforms to what was set up originally and is being driven by something else. What I see in your gif looks like two sources of input fighting for dominance. I can't reproduce it and it doesn't make sense that it would move if the axis value is always 0.

    Capture1.PNG

    2021-07-27_00-39-10.gif
     
    TeohRIK likes this.
  24. Barliesque

    Barliesque

    Joined:
    Jan 12, 2014
    Posts:
    78
    Thanks for the pointer! I found that those two buttons are called "POV" and "Left Hat", so copied the string values from the Control Mapper Demo, adding them into my Rewired Actions. Then went over to the Joystick Map and added them in there: POV Up, POV Down, Left Hat Up, Left Hat Down. When setting the Element field for those, I was startled to see all eight directions available in the list for both controls, none of which had previously appeared (?!?!)

    Anyway, those buttons are still not working for me. Not sure what I've done wrong as those buttons are now set up exactly as others I've been using that work perfectly.
     
  25. Barliesque

    Barliesque

    Joined:
    Jan 12, 2014
    Posts:
    78
    Doh! Turns out I was testing without saving my script changes first. o_O
    ...works just fine now. Thank you!
     
  26. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Normally, you would create an Action that describes something in-game like Fire, then map that to the element on the stick. There isn't much benefit in using an Action-based input system if your Action names are stick element names.

    There's no code path I know of that could lead to element names appearing in the drop-down list one time you look at it and not another. I've never heard of any bug like this. Perhaps you were looking at the element names for a different joystick or the controller template?

    There is also a global option to choose whether you want recognized hats to be treated as 4 or 8 way hats:

    https://guavaman.com/projects/rewired/docs/RewiredEditor.html#Settings

    "Force 4 Way Hats"

    And I suggest you export constants instead of using strings to look up Action values:
    https://guavaman.com/projects/rewired/docs/HowTos.html#exporting-constants
     
  27. hurleybird

    hurleybird

    Joined:
    Mar 4, 2013
    Posts:
    106
    While I've used Rewired before using the built-in stuff, my experience so far when needing to build custom input mapping and data store has been poor.

    So far, three big issues:

    1. The obfuscation makes for a number of black boxes that are difficult to understand.

    2. Lack of what seems should be obvious overloads. For example, Player.controllers.maps.GetMap() takes the controller type and index as the first two arguments. Why isn't there an overload that just takes a controller? I can get the index of the controller in a round-about fashion, but I shouldn't need to.

    3. This is the big one: exception hiding. If I had to guess, I'd say there's some async/await going on where exceptions are not being properly propagated. I'm in the process of making a new CustomDataStore class that handles data storage externally instead of using player prefs. This should be a simple task, but the Load() method is being called automatically from somewhere in obfuscated land, and if there's any issue in the CustomDataStore class all it provides is "Rewired: Rewired: An exception occurred during initialization. Input will not function" with some useless call stack from obfuscated land and nothing that references the actual problem in the CustomDataStore class!

    I understand why you obfuscate, but this is really the root cause of my frustrations. Normally, I'd go in and add that overload, or fix the exception hiding. My suggestion is that, if it must be obfuscated, perhaps provide a few more samples that cover common uses. At a minimum, something to handle external data storage, and an input mapper where a single column handles all of the controllers assigned to a player (eg. similar to Overload).
     
  28. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    First, what you are calling a controller "index" is not an index:

    https://guavaman.com/projects/rewired/docs/BasicUsage.html

    The way to get a controller id from a Controller object is to type controller.id. The controller type can be obtained from controller.type.

    There are overloads that take a Controller object instead of the two arguments controllerType and controllerId for each overload of the function except the generic versions:

    https://guavaman.com/projects/rewir..._Player_ControllerHelper_MapHelper_GetMap.htm

    https://guavaman.com/projects/rewir..._Player_ControllerHelper_MapHelper_GetMap.htm

    https://guavaman.com/projects/rewir...layer_ControllerHelper_MapHelper_GetMap_1.htm

    https://guavaman.com/projects/rewir...layer_ControllerHelper_MapHelper_GetMap_2.htm

    The generic versions do nothing different but cast the result for you which you can easily do with an explicit cast to the type like (JoystickMap). The generic versions should have overloads that take the Controller object, so that was a mistake.

    I aslo get complaints about having too many overloads and convenience functions in the API. Some people want more options, some want fewer.

    There is no async code in Rewired. Rewired was written for Mono 2.0 (.Net 3.5) and still is for compatibility across all platforms. Async/Await did not exist.

    Exceptions should give you the inner exception right below the first exception in the log readout. Here's the code that writes the exception:

    Logger.LogError(message + "\n\nException:\n" + (exception.InnerException != null ? exception.InnerException : exception));

    What version of Rewired are you using? This inner exception reporting was added at some point in the past.

    UserDataStore.Load() is only called by the UserDataStore implementation. It is never called from within the DLL. The source code is visible for the implementation. By default, this is UserDataStore_PlayerPrefs.

    Load should not be getting called during Rewired's initialization even from that script. What would get called during initialization is the OnInitialize function of the UserDataStore implementation. If Load is called from within OnInitialize in the implementation, then Load would ultimately be getting called during Rewired's initialization.

    I do not provide examples of a single-column, single-pool-of-bindings input mapping design because it goes completely against the design of the Rewired system. This is not an advertised or supported use case because achieving it with Rewired's Controller-centric Controller Map design would be an exercise in square-peg-round-hole hacking. It can be done, but it's difficult and not straight forward. It wasn't the way Rewired's mapping system was designed to work. I happen to know that the game you reference, Overload, uses it's own Action mapping system and does not use Rewired's Player-Action Controller Map system in any way. They designed an Action system that was not based on the Controller Map per Controller concept and their UI reflects that. They are only using the Controller layer of Rewired.

    I've provided far more than the minimum regarding input mapping and data storage. Apart from Control Mapper, I've provided a means to implement your own custom data storage solution by making an implementation of an interface. I've provided a working cross-platform data storage solution with code that was designed to use Unity's own built-in cross-platform data storage scheme (PlayerPrefs). Only with their recent abandonment of PlayerPrefs on certain console platforms does this now break down and require a re-implementation. In my view, it's Unity, the engine developer, who should be providing the generic cross-platform data storage solution that actually works on the 30+ platforms (times scripting backends supported) that they support (with new ones coming every year), not some guy who wrote an input system plugin. That's a gigantic task because of the number of platforms with no way to test on most, and knowing Unity's cross-platform inconsistencies, trying to make something blindly that works across all is a recipe for many very long and painful support cases. If Unity's cross-platform data storage solution worked on all platforms as it was originally intended, there would be much less need to re-implement this.

    I fail to see how obfuscation of internal code correlates to an expectation that I should provide even more features to the user out of the box. What feature each user wants to be supplied out of the box for the product to be "complete" is completely different from user to user. (Single-column input mapping example. In the past, it was a drop-in input mapper, touch controls, Unity UI support, software mouse cursors, PlayMaker support, video tutorials, etc.) Obfuscation of internal code should in no way prevent users from implementing their own features on top of Rewired.

    Rewired is not a source code product. There should not be an expectation of being able to go in and modify the DLL when you have a problem or want something to work differently. If there is a problem with some specific functionality like exception reporting, tell me about the problem so I can fix it.
     
    Last edited: Jul 28, 2021
  29. hurleybird

    hurleybird

    Joined:
    Mar 4, 2013
    Posts:
    106
    Got it. I was confused by, for example, Player.controllers.Joysticks.IndexOf(joystick).

    Yup, see that now.

    I get the exception message, but the call stack isn't always preserved.

    For example, if in the UserDataStore_PlayerPrefs.Load() I add
    throw new Exception("I'm an exception");
    just before
    int count = LoadAll();
    , the error message that appears in the console is:


    Rewired: Rewired: An exception occurred during initialization. Input will not function.
    Exception:
    System.Exception: I'm an exception
    at Rewired.ReInput.WiHHbBScAOibnnscPRNtplVPiTS (Rewired.InputManager_Base , System.Func`2[T,TResult] , Rewired.Data.ConfigVars , Rewired.Data.ControllerDataFiles , Rewired.Data.UserData ) [0x003da] in <36e4153e51f34777ad607e54d9756476>:0
    at Rewired.InputManager_Base.Initialize () [0x000a0] in <36e4153e51f34777ad607e54d9756476>:0
    ------- Rewired System Info -------
    Unity version: 2020.3.15f1
    Rewired version: 1.1.39.3.U2020
    Platform: Windows
    Editor Platform: Windows
    Using Unity input: False
    UnityEngine.Logger:LogError (string,object)
    Rewired.Logger:LogErrorNow (object,bool)
    Rewired.Logger:LogError (object,bool)
    Rewired.Logger:LogError (object)
    Rewired.InputManager_Base:HandleException (Rewired.InputManager_Base/ExceptionPoint,string,System.Exception)
    Rewired.InputManager_Base:Initialize ()
    Rewired.InputManager_Base:Awake ()


    No mention of the UserDataStore_PlayerPrefs class at all in there. Unless the exception message is specific to just one place in the code, that isn't helpful.

    Looking at your code example, it only handles inner exceptions one level deep. Did you recently add another layer of depth to exception logging? It wouldn't be a bad idea to support arbitrary levels in any case, since there's no guarantee that the exception you get from user code won't itself have multiple levels of inner exceptions.

    That's good to know. Overload is a few years old now, so I should ask, in your opinion, in terms of handling generic controllers on generic platforms, is Rewired still the obvious best solution? Or have others caught up here? I'm generally hesitant to use the new Unity Input System out of fear it could drastically change.
     
  30. aegis123321

    aegis123321

    Joined:
    Jul 5, 2015
    Posts:
    35
    Hi there. It seems to be a performance issue on Windows standalone with IL2CPP:
    There is a obfuscated class in Rewired_Windows.dll consistently makes spikes at somehow fixed intervals.

    I've tried to built with Mono and this issue didn't happen. So it should be a bug I guess?

    Unity2019.4.28f1
    Rewired 1.1.37.0.U2019
     
  31. Barliesque

    Barliesque

    Joined:
    Jan 12, 2014
    Posts:
    78
    For this particular project it made sense to stick with control names, but yes, I agree.

    Awesome! Thank you for pointing that out.

    I don't use strings. I actually define my own enum, matching the name to the ActionID.
    ...I'll make a point of using that export system next time! ;)
     
    Last edited: Jul 29, 2021
  32. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Anything that works differently in IL2CPP than it does in Mono can only be a bug in IL2CPP of some sort. The code is 100% identical. Mono executes the same code with no issue but IL2CPP doesn't. This kind of problem is absurdly hard to debug because I didn't write IL2CPP and don't have any inside information about how it works. "Fixing" or rather patching over a problem caused by a bug in IL2CPP is nearly impossible. Only if I can somehow identify the specific code feature or Windows API function call where the delay is occurring and find some kind of alternate way to achieve the same thing without triggering this bug would a resolution be possible.

    I cannot reproduce this issue at all. I've tried with several different controllers. I don't have any context about under what circumstances this is happening.

    The function that is reportedly causing the spike is simply the code that executes when Windows delivers an event (Raw Input event, window event, etc.) The profiler stopped at the highest level, basically right when the event was received. The function that is actually running slowly is many, many levels deeper, and based on past experience, is very likely a Windows API function call, for example, to retrieve button data from the Raw Input event Windows sent or some such. But I can't know unless I can reproduce this myself and drill all the way down to the exact function call that's spiking. If it is some Windows API call which is taking a long time to complete, I won't be able to fix it. If that's the case, based on my past experience, things like this likely only occur in a perfect storm of circumstances including a specific Windows build version, driver version, and some specific device(s) in use.

    If you have more detailed information about under what circumstances this is occurring (devices connected and whether they're connected via USB/bluetooth, etc., running in a window, clicking around with the mouse, moving joysticks, primary input source chosen, etc.) then I will try to reproduce under those circumstances.
     
    Last edited: Jul 29, 2021
  33. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    The exception is being propagated and logged. After research, the reason the stack trace is being killed is the difference between:

    Code (csharp):
    1. catch(Exception ex) {
    2. // do something
    3. throw ex;
    4. }
    5.  
    6. catch(Exception ex) {
    7. // do something
    8. throw;
    9. }
    10.  
    You could easily solve this issue by wrapping your code that gets executed by Rewired in a try/catch statement. Handling exceptions and not relying on whatever is upstream to handle them is good practice anyway.

    Unity doesn't even report inner exceptions, so I don't think infinite depth exception reporting is necessary or to be expected.

    Rewired is still the best in my opinion, but I might be slightly biased.

    I don't keep up with changes to the other systems out there. I haven't even had the time to really learn Unity's new system since its 2nd redesign... or is it 3rd?
     
    Last edited: Jul 29, 2021
  34. aegis123321

    aegis123321

    Joined:
    Jul 5, 2015
    Posts:
    35
    Hi, just to let you know I made a simple project to reproduce it and reported by official support.
     
  35. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Thanks. I got it.

    As I was reading your description of the problem, it came to my mind. I've dealt with debugging something like this multiple times for different users fairly recently. The problem isn't Rewired. It's Unity.

    Here's my conclusion to a report that mouse input was causing performance issues:
    https://forum.unity.com/threads/rewired-advanced-input-for-unity.270693/page-146#post-7158238

    In short:
    1. High refresh-rate mice cause Unity to slow down drastically with or without Rewired in the project.
    2. The only reason Rewired is even shown in this stack trace is because of how the Raw Input mouse event rerouting works. An application may only receive Raw Input events for a particular device type to one single window. Unity requires these events for their mouse input to work. Rewired also needs to receive these events for its Raw Input mouse to work. Rewired creates a message window, subscribes to Raw Input events to this window, then it reroutes the Raw Input mouse events back to Unity when they come in. What happens after that is out of Rewired's control. Unity becomes downstream of Rewired and therefore Rewired ends up in the stack trace.

    This is a false flag. I keep having to do this same kind of deep debug for issues that are ultimately issues in Unity because of this event rerouting causing Rewired to be included in the stack trace. I wish I could prevent Rewired from showing up in this stack trace but I can't. The reason the profiler shows this under Other is that the code is being executed at the beginning of the main thread by Windows when it delivers the Raw Input messages to the application.

    The reason I couldn't reproduce it is that I use a mouse that is several years old and doesn't run a 1000 Hz+ refresh rate. Plugging in a newer mouse with a 8000 Hz refresh rate, I can easily see massive profiler spikes as I move the mouse.
     
    Last edited: Jul 30, 2021
    april_4_short likes this.
  36. aegis123321

    aegis123321

    Joined:
    Jul 5, 2015
    Posts:
    35
    Thanks!
    I just realized that that project was Mono, so it didn't only happens on IL2CPP. Sorry for misleading.
    And yes, I just tested a empty project without Rewired.
    It was still showing spikes when I moving mouse as you said.
    so.. unity?
    Always has been.
     
  37. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,498
    The control mapper was always my tool of choice for mapping all the flight controllers and all other controllers. That was before the debug information tool was available. Thankfully I only had to do it once and support multiple platforms.
     
    guavaman likes this.
  38. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,498
    Glad you got everything working. Control Mapper demo has been a good friend for a very long time.
     
  39. liandris

    liandris

    Joined:
    Mar 23, 2021
    Posts:
    8
    Hello again. I wanted to provide more information and reply to this specific bit of text.

    I'm noticing more of games that unable to read input from my DS4 controller when expected. I think I saw 2-3 more games since my first message here. Today, I happened to talk to developer of one of such games and he was able to solve the issue. What he did was to change how controllers are assigned to players. While by default (also probably according to "best practices" you linked) is 1 controller per each player, he changed that to "unlimited" (that seemed to also fix issues other players reported, not just DS4Windows users). I'm not sure exactly what this implies in terms of internal workings of Rewired, but more importantly, here is my view on the problem: it could be that 3rd party joystick software is not necessarily the cause.

    See, in my case (I'm using DS4Windows), input actually works well if I run the game from the Windows Explorer, using relevant .exe file. Running the game from Steam is what appears to break it. So, my "fix" for such games was to just create a separate shortcut and use it to play them like I wanted. This makes me think that the default suggested logic of assigning controllers may be not optimal. Or maybe this is completely wrong if changing this default logic breaks local multiplayer handling of multiple controllers. Anyway, Steam is trying to do something, even if Steam Input is disabled globally and per-game, that breaks this assigning logic when using 3rd party tools.

    I'm not sure exactly what you could do about this issue. Maybe add more options accessible to end users that might solve such issues? Maybe just add a note in relevant documentation sections? Or maybe you can contact Valve more directly to ask them to look into the issue (really sorry for suggesting this, since it appears to be something they could solve, but it doesn't seem like I have any chances to get a response from them).
     
  40. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    https://guavaman.com/projects/rewired/docs/BestPractices.html

    The best practices documentation does not say to set it to assign one joystick per player. Quoting from that page:
    • Always provide some means for your users to change controller assignments. It is especially important if you are making a multi-player game. You cannot know what devices, physical or virtual, will be present on a user's system, appear as Joysticks to Rewired, and be assigned to a Player. Device emulation software (VJoy, DS4Win, SCPToolkit, etc.) and certain device drivers can and frequently do cause problems by creating extra, non-functional virtual devices. Allowing the user to make their own controller assignments solves this issue as well as making it possible for users to swap controllers, etc. You can either include Control Mapper directly in your game or create your own system.
    • Max Joysticks Per Player to 100 so all controllers attached to the system may be used by the player.
    I understand this problem very well and have for quite some time.This is the exact reason why I put the above guidance in the Best Practices documentation.

    There are several different incarnations of this issue with different symptoms, but fundamentally, the causes are always similar.

    1. You are using Steam.
    2. You have Use XInput enabled.
    3. You are using DS4 win.
    4. You have Steam-configured controller support enabled in Steam.
    5. Steam is taking over the DS4 controller and creating both an XInput device for it and a HID device for it and hiding the real HID device.
    6. DS4 Win is also creating either another XInput device or a HID device that Steam cannot distinguish from a real device.
    7. You now have 2 identical controllers exposed to Rewired, one of which works, and the other doesn't, because Steam is taking over all input and determining what input XInput and Raw Input send through these devices. In some cases, both devices will produce input and you will end up having 2 Players controlled by the same physical controller.
    8. Steam already knows how to handle the DS4 HID device. It exposes an environment variable that Rewired reads in order to ignore the HID device that is being replaced by Steam's virtual XInput device. DS4Win's device isn't being hidden by Steam, or its being processed as a second DS4Win through their virtual controller system.

    I've already done both of those. The Best Practices page warns you that you must provide the user a means to assign and unassign controllers to handle exactly this situation. Players of the game could be using any number of software mapping / virtual device drivers out there or they may simply have some device driver installed that creates phantom joysticks. There isn't any more I can do. This is a problem caused by virtual controllers created by a 3rd party driver conflicting with Steam's own virtual controller handling logic.

    I don't think Steam can solve this problem either. DS4Win is designed to expose a virtual device through Windows which appears to all software simply as a real device. Neither Rewired nor Steam can know that these devices DS4Win is creating are virtual, nor can they know they are created by DS4Win. As far as I can imagine, the only way you could possibly know this is to hook into the running DS4Win process or the driver and somehow read that information. That means you have to write code to explicitly detect and support for DS4Win, and keep up to date with versions and changes over time. I doubt Steam is interested in doing this, especially considering DS4Win is only one of many such virtual device applications out there.
     
    Last edited: Aug 4, 2021
  41. liandris

    liandris

    Joined:
    Mar 23, 2021
    Posts:
    8
    Alright, so it's already in the documentation. Thanks for pointing this out, because I assumed the opposite from my conversation with the game developer.

    Still, what's the default setting? I imagine those few developers that shipped games with this issue did not read the document and preferred to not touch many options, so maybe it could be improved by changing the defaults? For example, if most games are single-player maybe it would be best to set it to 100 by default.

    These points are logical but it doesn't work like this for now. In my case, I don't have my controller support enabled in Steam. In General Controller Settings all options are disabled. I can also go to game properties and set the option to Disable Steam Input (though it won't matter). Steam does not and should not read any any controller input. Yet, it appears to affect my controller input when I launch the game from Steam client. - input gets broken. Running the game from .exe file in Windows Explorer gives different results - I can use my controller fine.

    So, I expect this issue to get easily solved if user has one solution configured and all others disabled - it's only sane. But it will only work if all of such solutions that need to be disabled, can be disabled to not interfere, and Steam appears to be problematic in this respect because its interference can't be prevented.
     
  42. LukeFireproof

    LukeFireproof

    Joined:
    Jan 21, 2016
    Posts:
    12
    Hi, we've been using Rewired in our projects for a few years now and just started getting a weird error that seems to occur before editor crashes sometimes. Googling hasn't turned up much so thought I'd ask if anyone knows anything about it!

    Code (CSharp):
    1. SharedThread: Too many calls to Unregister.
    2. ------- Rewired System Info -------
    3. Unity version: 2021.1.0f1
    4. Rewired version: 1.1.39.2.U2021
    5. Platform: Windows
    6. Editor Platform: Windows
    7. Using Unity input: False
    8. Primary input source: RawInput
    9. Use XInput: True
    10. Native mouse handling: True
    11. Enhanced device support: True
    12.  
    13. UnityEngine.Debug:LogError (object)
    14. Rewired.Logger:LogErrorNow (object,bool)
    15. Rewired.Logger:LogError (object,bool)
    16. lYpnjwLmqFbdwVdJOLgfRGxUFwRg/CAnsxNOapfKTpWAwmffCDHQuCLLb<bool>:zJFRdysZzKwMeypLGDqUfcJQbhz ()
    17. lYpnjwLmqFbdwVdJOLgfRGxUFwRg<bool>:vOoVSaurNUXrMEfhVdiLjtCSPNFn (bool)
    18. lYpnjwLmqFbdwVdJOLgfRGxUFwRg<bool>:Finalize ()
     
  43. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Rewired is advertised as a multi-player input system. If I set the default to 100, those people who don't bother to look at the documentation will be contacting me for support telling me only the first Player can control anything. The default settings are what I believe they should be for the majority of games.

    The advice about changing the number of joysticks assigned per player in a single player game is scattered throughout the documentation in several other places also in an attempt to prevent people from missing this:
    https://guavaman.com/projects/rewired/docs/Controllers.html#joystick-auto-assignment
    https://guavaman.com/projects/rewired/docs/HowTos.html#appletv-siri-remote

    Your game also has settings in the Steamworks backend to determine how Steam treats controllers. Both the Steamworks backend and the client side can affect how Steam manages controllers. Both have to be disabled or Steam will start playing games with input devices. There also may be some setting in the .vdf files contained in your project for the default profile to use for the "Steam Controller", but I'm not sure. It's also possible they've broken it in some update at some point. I suggest you contact Steamworks support or post on their forums to see if there are any other options to prevent Steam from messing with controllers. In my testing in the past, it was possible to stop Steam from taking over input with the right settings in the backend and client.

    They may also have added settings for Remote Play. For the game to support that, Steam control over all input is required. So if this is even an option, if it's enabled, Steam will necessarily take over input.

    Steam is and always has been a gigantic headache for many, many reasons. Their system is basically hack on top of hack to achieve what they do with input, screen overlays, remote play, and a lot of other features. They're trying to make desktop computers into consoles by hooking into all manner of things in the Windows API and rewriting the results. It's rife with issues that developers like us have to deal with every day. I can't tell you how many times I've rewritten and rewritten code in my input system, which is supposed to be like any other Steam-agnostic application, to implement workarounds to all manner of Steam nonsense that doesn't work right, suddenly breaks after an update, etc., and it keeps changing year by year. I don't expect that to get better any time soon.
     
    Last edited: Aug 4, 2021
    shotoutgames likes this.
  44. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    That's just not possible... There is no code path that can lead to this being logged. Nobody has ever reported this before either.

    In cases like this, it's a virtual certainty that some completely new monkey wrench has been thrown into the works that makes everything work in a completely new way that was never anticipated before. Things that one could rely on in the past to be true are no longer true, so code that couldn't possibly execute before suddenly does. The cause is always some kind of unexpected change in an underlying dependency. The biggest dependency of Rewired is Unity.

    For this to happen, the App Domain would have to be getting unloaded before Dispose is called on SharedThread. The only way this would be possible is if the App Domain is unloaded before OnDestroy fires and Rewired shuts down everything. I don't see how this could be possible. If Rewired cannot shut down in a predictable, controlled manner, all manner of chaos will ensue such as threads being left running, native callbacks left registered, and many other issues.

    Are you using some kind of new Unity setting such as their configurable play mode options?

    Does this happen when recompiling scripts or DLLs while Play mode is enabled? I'm basically just making wild guesses in the dark here. This is inexplicable and should not be happening.

    I imagine it is likely there are some specific Unity options you are using or specific process or sequence of processes that are occurring in your project to trigger this unexpected order of function calls.
     
    Last edited: Aug 5, 2021
  45. LukeFireproof

    LukeFireproof

    Joined:
    Jan 21, 2016
    Posts:
    12
    I'm not using any of those playmode options. I have noticed it happen on compile sometimes, although not sure if it's during playmode or not. My compile settings are set to Recompile After Finished Playing so it shouldn't be compiling anything in playmode anyway.

    Thanks for your response, I'll keep an eye on it and let you know if I figure anything out!
     
  46. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Is Rewired set to run in Edit mode?

    https://guavaman.com/projects/rewired/docs/InputManager.html#run-in-edit-mode

    Are you using ASMDEF files in your project?
     
  47. LukeFireproof

    LukeFireproof

    Joined:
    Jan 21, 2016
    Posts:
    12
    No

    Yes, we have ASMDEFs set up
     
  48. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,802
    Is there any chance I could get access to your project to do some testing?
     
  49. liandris

    liandris

    Joined:
    Mar 23, 2021
    Posts:
    8
    Well it's a tough one, but I'd advise you to reconsider. Here are the arguments:
    • Gamedevs seem to jump into Rewired for the broad game controller support, not for multiplayer. Most games are single-player, not multi-player.
    • Many gamedevs seem to not care about documentation. Maybe they are lazy or don't have much time. They think all they need is to include Rewired and they are good to go (and that's probably how they get this issue in their games). Most single-player games won't provide a proper way to rebind gamepad controls. And we are talking about the ability to re-assign game controllers, which is included in even less games.
    • People have issues, which translates into wasting time of both gamers and developers. Complaints on forums, lost sales etc.
    • Even though Steam is contributing into the issues, it doesn't mean it will be solved for everyone when Valve fix this. And it may always be re-introduced in later updates.
    See, I think Rewired needs to be more foolproof. So if it's targeted to multi-player input, consider the differences between how single-player and multi-player games are developed. In case with SP a dev will likely test just one gamepad and be done with it, while with MP surely devs are going to have multiple devices and see how they work together, and read documentation to find out what to do.

    I can think about at least 3 ways on how this can be possibly solved:
    1. Change the default value from 1 to anything beyond, perhaps 100. Advise that it should be changed to 1 for any multi-player mode.
    2. Introduce some kind of global modes or profiles - SP and MP, where the default value of this setting is 100 and 1 respectively. Require developer to choose the mode before he does anything else.
    3. By default assign a controller only after a button is pressed on it. I think it's somewhat sub-optimal, but at least it complements the multi-player "lobby" way of assigning controllers between players.
    Also, I have 2 more requests:
    1. I'd like to know where exactly this value is kept in a published game. Most developers won't fix this in updates (many don't provide any updates whatsoever). So knowing where it is may help users to solve the issue themselves, or with guides. Is it in one of main .dll files or in some configuration file? Is it float or int?
    2. Whether you decide to change the default or not, consider providing a user-friendly way of changing this value (or maybe others too). A command line switch would allow players to fix their games easily. For example
      -rewired-conf RewiredConfigSetMaxJoysticksPerPlayer=1
    I also advise to act as fast as possible because it will save more future games from such issues. I've tried more latest Unity-based games recently and my impression is that this trend of broken SP configuration is increasing.
     
  50. libra34567

    libra34567

    Joined:
    Apr 5, 2014
    Posts:
    42
    @guavaman Soooo, I installed rewired package into a fresh new unity project. Nothing else in there. But the PS4SpecialFeature demo is not working for PS4DS controller. (The controller is connected according to console. The light color is passed from unity to my controller correctly. But I cant seem to use any bottom/orientation/vibration/touchpad etc) Any clue please? I tested with steam open and without. Please help. Thank you

    P.s. I had it working this morning. But for some reason its not working again this afternoon :(. Hence I created a empty project for testing. Unfortunately it went the same. I installed everything It mentioned during the installation steps.

    P.s.2 Its working perfectly fine if I build it. So its only not working in unity editor
     
    Last edited: Aug 9, 2021
unityunity