Search Unity

Rewired - Advanced Input for Unity

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

  1. Kiupe

    Kiupe

    Joined:
    Feb 1, 2013
    Posts:
    528
    Hello,

    I'm using Rewired for the first time and I'm not quite sure that I do "get it" all the time. I'm currently working on a game prototype which will be available on desktop and on mobile. So the game will be playable with a keyboard or a touch screen for instance.

    In that game there is an inventory with a fixed number of slot (no scrolling). The player should be able to open/close the inventory, select an inventory item (moving left-right) and consume that item.

    It's kind of easy to imagine how the keyboard keys can be bind to actions in order to use that inventory, but I'm having more difficulty to get-it with a touch screen. Should the whole inventory be a custom controller and every interactable items (open/close button, slots ) be an element of that custom controller ? Or should I handle touches on the inventory as usual and then override a custom controller value (like a touch controller) in order to fed that custom controller element value and then trigger an action ?

    Not sure I'm clear enough here - but I guess my main interrogation is how to manage "touchable" elements in my game (buttons, sprites, UIs, whatever) in a "Rewired-style" ? With an external input device (keyboard, dpad etc.) those elements will be first selected using a navigation system and then an action could be performed on it. With a touch screen (mobile) you directly "touch" those elements you do not use an "input device" to select them and then performed an action on them.

    Thanks.
     
  2. AndyLangberg

    AndyLangberg

    Joined:
    Jul 6, 2018
    Posts:
    37
    Hi,

    I'm unsure if this is a known issue, or if I've implemented rewired wrong, but whenever I alt tab the application, rewired has a 1/3 chance of crashing completely, with the error:

    Code (csharp):
    1. Rewired: Rewired is not initialized. You must have an active and enabled Rewired Input Manager in the scene before calling any part of the Rewired API.
    2. ------- Rewired System Info -------
    3. Unity version: 2018.3.2f1
    4. Rewired version: 1.1.22.2.U2018
    5. Platform: Windows
    6. Editor Platform: Windows
    7. Using Unity input: False
    8.  
    9. UnityEngine.Logger:LogError(String, Object)
    10. Rewired.Logger:LogErrorNow(Object, Boolean)
    11. Rewired.Logger:LogError(Object, Boolean)
    12. Rewired.Logger:LogError(Object)
    13. Rewired.ReInput:CheckInitialized()
    14. Rewired.ReInput:CheckInitialized(Int32)
    15. Rewired.Player:GetButtonDown(String)
    16. PresentationLayer.AR.UIToolkit.ObjectClickFunction:Update() (at Assets/App/Scripts/PresentationLayer/AR/UIToolkit/ObjectClickFunction.cs:19)
    17.  
    This is super frustrating when debuging, as I often switch to VS to check out some code or stop on a breakpoint, only to alt tab back to Unity for Rewired to crash, forcing me to start over.
     
  3. Cramonky

    Cramonky

    Joined:
    Apr 1, 2013
    Posts:
    186
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Rewired's Action-based structure does not lend itself to being a general touch interface input system. Rewired was not designed to be that and trying to make it be one is going to be messy. Rewired is an Action-based system. Touching items and interacting with them doesn't really fit with that paradigm. You most certainly don't want to have different Actions for every item you could possibly interact with. The Action-based system works well for on-screen touch controls, but it does not work for uses such as you are describing. You have more data at your disposal when dealing with touches than you do with Actions such as finger id, raycast targets, movement vectors, etc.

    Unity's UI system has has a "Selectable" navigation system for keyboard and joystick input and uses data directly available from touches/clicks for touch based input and mouse input. If you're using Unity UI for your interface, it should basically be automatic. The RewiredStandaloneInputModule uses 4 Actions to navigate. Your UI elements respond to Submit Action which can come from any controller, or they will also response to a touch/click. This isn't the "Rewired" way of doing things -- it's the Unity UI way of doing things, and it works for what you're describing.

    If you're using some other UI system, then you would have to make that get input from Rewired in order to use it.
     
  5. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Look at the base of the call stack:
    PresentationLayer.AR.UIToolkit.ObjectClickFunction:Update() (at Assets/App/Scripts/PresentationLayer/AR/UIToolkit/ObjectClickFunction.cs:19)

    This function is calling player.GetButtonDown when Rewired has been deinitialized and is no longer running. What is deinitializing Rewired? It is deinitialized when OnDestroy or OnDisable is called by Unity. This could be when the GameObject is destroyed or disabled, it could be when the InputManager component is disabled, when loading a new scene without Don't Destroy on Load enabled, when recompiling scripts, etc. Anything that results in OnDestroy or OnDisable being called on the GameObject will cause Rewired to shut down.

    Ultimately, the error is coming from the code in PresentationLayer.AR.UIToolkit.ObjectClickFunction:Update(). This function is going to have to actually check if Rewired is ready before calling anything in the API.

    if(!ReInput.isReady) return;

    In addition, if you're storing some Player or any other object references to anything in the Rewired API and Rewired is disabled, even temporarily, all these references become invalid and you must get them again. This has to be the case here because it's throwing the error on player.GetButtonDown, not ReInput.players.GetPlayer, which means you're storing a reference to Player and then using it after Rewired has been shut down.
     
    Last edited: Feb 7, 2019
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Thanks!

    "Baked" controller element data does not exist in these Controller Map instances, baked data being ActionElementMap.elementIndex and ActionElementMap.elementIdentifierName. This data is not stored in the mapping information in the Rewired Input Manager. This data is baked into the ControllerMap and ActionElementMap at the time the maps are created from the Controller object for which it was created to avoid having to do elementIdentifierId to elementIndex lookups on the Controller every time these properties are accessed (which is very often). Since you are not providing a Controller object to it because you are using the GUID overload (no controller connected), it cannot bake any data from the Controller into the ActionElementMaps because no Controller exists. By using that overload, you are getting an incomplete ControllerMap which was created for no underlying Controller object. This is why the IDE documentation on that overload warns that you "Do not attempt to use this Controller Map in a Player.".
     
  7. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    I am exploring ways to change the structure of all this to make the information available in map instances.
     
  8. Cramonky

    Cramonky

    Joined:
    Apr 1, 2013
    Posts:
    186
    I see. I definitely would have expected this data to be there since I'm requesting a map for a specific controller. What I ended up doing is using a HardwareJoystickMap that I can assign via the inspector to get the name of the element. (I realize I could make my own map from elementIdentifierIds to names, but I wanted to make sure there wasn't any existing functionality I could use)

    Edit:

    That would be great!
     
  9. quitebuttery

    quitebuttery

    Joined:
    Mar 12, 2011
    Posts:
    329
    Ok so I'm seeing this exception sometimes when I click on an action to re-map, maybe this has something to do with it? It's inside your inputmanager:

    Code (CSharp):
    1. NullReferenceException
    2.   at (wrapper managed-to-native) UnityEngine.Behaviour.get_isActiveAndEnabled(UnityEngine.Behaviour)
    3.   at UnityEngine.EventSystems.UIBehaviour.IsActive () [0x00002] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\UIBehaviour.cs:22
    4.   at UnityEngine.UI.Graphic.SetVerticesDirty () [0x00002] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Graphic.cs:100
    5.   at UnityEngine.UI.Text.set_text (System.String value) [0x00053] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Text.cs:138
    6.   at SimpleRewiredRemapper.RedrawUI () [0x000ef] in C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Scripts\New FLARB Scripts\SimpleRewiredRemapper.cs:104
    7.  at SimpleRewiredRemapper.OnCancelControlSettings () [0x00025] in C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Scripts\New FLARB Scripts\SimpleRewiredRemapper.cs:238
    8.   at UnityEngine.Events.InvokableCall.Invoke () [0x00011] in <9c69720a20aa44498e2643c6456c4d0e>:0
    9.   at UnityEngine.Events.UnityEvent.Invoke () [0x00023] in <9c69720a20aa44498e2643c6456c4d0e>:0
    10.   at UnityEngine.UI.Button.Press () [0x0002d] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Button.cs:36
    11.   at UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) [0x00012] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Button.cs:45
    12.   at UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00008] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\ExecuteEvents.cs:50
    13.   at UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) [0x00073] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\ExecuteEvents.cs:261
    14. UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
    15. UnityEngine.DebugLogHandler:LogException(Exception, Object)
    16. UnityEngine.Logger:LogException(Exception, Object)
    17. UnityEngine.Debug:LogException(Exception)
    18. UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1) (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\ExecuteEvents.cs:265)
    19. Rewired.Integration.UnityUI.RewiredStandaloneInputModule:ProcessMousePress(MouseButtonEventData) (at C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Rewired\Integration\UnityUI\RewiredStandaloneInputModule.cs:1063)
    20. Rewired.Integration.UnityUI.RewiredStandaloneInputModule:ProcessMouseEvent(Int32, Int32) (at C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Rewired\Integration\UnityUI\RewiredStandaloneInputModule.cs:966)
    21. Rewired.Integration.UnityUI.RewiredStandaloneInputModule:ProcessMouseEvents() (at C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Rewired\Integration\UnityUI\RewiredStandaloneInputModule.cs:950)
    22. Rewired.Integration.UnityUI.RewiredStandaloneInputModule:Process() (at C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Rewired\Integration\UnityUI\RewiredStandaloneInputModule.cs:652)
    23. UnityEngine.EventSystems.EventSystem:Update() (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\EventSystem.cs:294)
    ---

     
  10. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    The GetInstance methods were tacked on after the fact and are somewhat hacky in nature because the system was never designed to give you Controller Maps with no underlying Controller attached. Just figuring out what Controller Definition to load based on nothing but a GUID is not simple and not fool proof. A Controller Definition may have dozens of platform/input source specific definitions and variants within it. Knowing which sub-definition and variant has to be used can be impossible depending on the platforms and input source(s) being used. In normal functioning, the input source(s) in use (XInput, Raw Input, etc.) use their own methods to identify what controller is connected. Everything is input source specific. XInput may be used for one controller while Raw Input may be used for another controller while a custom low-level system may be used for yet another controller (DS4). How this is determined is entirely up to the input source(s) in use and how they are able to recognize the particular controller with what information available. These GetInstance methods are working entirely backwards because they have no information to go on about the actual controller and can only make a best guess as to what sub-definition might be loaded by the particular input source(s) being used. This affects the baked data -- what controller element index does a particular element identifier match up to? Cannot be determined because the controller itself is not present and we cannot know 100% accurately what definition map will be used for it. Baking is done with the Controller object present, so the determination of exactly which sub-definition is loaded has already been done. While string names of element identifiers can probably be made to work without issue, element indices will not be reliable because they can only be baked to a "best guess."
     
    Last edited: Feb 7, 2019
  11. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    The code that is throwing the exception is in your script. I've highlighted the 2 lines causing it:

    NullReferenceException
    at (wrapper managed-to-native) UnityEngine.Behaviour.get_isActiveAndEnabled(UnityEngine.Behaviour)
    at UnityEngine.EventSystems.UIBehaviour.IsActive () [0x00002] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\UIBehaviour.cs:22
    at UnityEngine.UI.Graphic.SetVerticesDirty () [0x00002] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Graphic.cs:100
    at UnityEngine.UI.Text.set_text (System.String value) [0x00053] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Text.cs:138
    at SimpleRewiredRemapper.RedrawUI () [0x000ef] in C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Scripts\New FLARB Scripts\SimpleRewiredRemapper.cs:104
    at SimpleRewiredRemapper.OnCancelControlSettings () [0x00025] in C:\Users\Flarb\Documents\Unity\DEMON'S TILT (1) - REVERT\Assets\Scripts\New FLARB Scripts\SimpleRewiredRemapper.cs:238

    at UnityEngine.Events.InvokableCall.Invoke () [0x00011] in <9c69720a20aa44498e2643c6456c4d0e>:0
    at UnityEngine.Events.UnityEvent.Invoke () [0x00023] in <9c69720a20aa44498e2643c6456c4d0e>:0
    at UnityEngine.UI.Button.Press () [0x0002d] in C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Button.cs:36

    Line 104 in your SimpleRewiredRemapper.cs is trying to set some value in UI.Text.text that is in turn cascading into a NullReferenceException in a core Unity class UnityEngine.Behaviour when Behaviour.isActiveAndEnabled is queried. Is the UI.Text object you're trying to set the value in already destroyed?

    The base of the call stack is the RewiredStandaloneInputModule because this is responsible for sending Unity UI button events. That's the only reason why it's in the call stack. The error occurs after the button event is fired and control is handed off to SimpleRewiredRemapper.cs.
     
    Last edited: Feb 7, 2019
  12. quitebuttery

    quitebuttery

    Joined:
    Mar 12, 2011
    Posts:
    329
    Aha, I indeed did find that and fixed it! (I think...!)

    It's weird because it only happened on the Mac and not PC.
     
  13. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    To expand upon what I said before in my previous message:

    I would not attempt to use Rewired's Custom Controller and Actions as you seem to be describing above (took me a while and a re-read to actually get what you were saying). Selecting a potion, for example, in an inventory and touching it should not result in a "Use Potion" Action being triggered through Rewired with your scripts checking for the result of the Rewired "Use Potion" Action. That seems to be what you're describing above. While that's possible, that would me a misuse of the input system in my view.

    What would make much more sense is to have your potion UI button trigger some code that uses the potion and applies the health benefit. Using Unity UI, you could have the OnClick handler of the UI button trigger this function. This would work for controllers, keyboard, mouse, and touch because of the RewiredStandaloneInputModule. If you also want to bind a button on a controller to a Rewired "Use Potion" Action, you can do that, but that would be separate from the inventory. A script watching for Rewired input would check for "Use Potion" and then trigger the same function that was called by the UI button in the inventory.
     
  14. AndyLangberg

    AndyLangberg

    Joined:
    Jul 6, 2018
    Posts:
    37
    Aha, so unless I'm misunderstanding, you have to call

    Code (CSharp):
    1.             if (!ReInput.isReady)
    2.                 return;
    3.             _player = ReInput.players.GetPlayer(0);
    4.  
    at the start of every frame/Update() which uses it? This i counter intuitive, but if ReWired is disabled on alt tab, causing all references to disappear, it does explain why I was getting the errors.


    Edit: While I'm here, I'm also getting this error randomly on some alt tabs:

    Code (CSharp):
    1. Rewired: Touch controls cannot be used with a world space Canvas. Change the canvas render mode to screen space.
    2. ------- Rewired System Info -------
    3. Unity version: 2018.3.2f1
    4. Rewired version: 1.1.22.2.U2018
    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.Logger:LogError(String, Object)
    14. Rewired.Logger:LogErrorNow(Object, Boolean)
    15. Rewired.Logger:LogError(Object, Boolean)
    16. Rewired.Logger:LogError(Object)
    17. Rewired.ComponentControls.TouchControl:EjMLFLBRWYuJhkijMbvSxjQylzW(Boolean)
    18. Rewired.ComponentControls.TouchControl:OnValidate()
    19. Rewired.ComponentControls.TouchInteractable:OnValidate()
    20. Rewired.ComponentControls.TouchPad:OnValidate()
    21. UnityEngine.CanvasRenderer:RequestRefresh()
    This one is a bit confusing as there are no Touch controls being used on world space canvases, and like I said only appears when tabbing back and forth. Luckily it's a lot less critical than the last, as it doesn't hardlock the entire application.

    edit2: Actually this is even weirder than I thought. This error only appears when running the app, alt tab to Visual Studio and hit "ctrl +s" (Whether I've done changes to the code or not does not matter).
     
    Last edited: Feb 8, 2019
  15. Kiupe

    Kiupe

    Joined:
    Feb 1, 2013
    Posts:
    528
    Thanks for having a second thought on my interrogation. I did not know that RewiredStandaloneInputModule could be used to "trigger" an "OnClick" handler method of an UI element. I guess ( I will have to read the documentation) that the UI element should have the focus - which makes sense and is doable using the usual Rewired way to allow a keyboard or whatever navigate (change the focus) on UI elements.

    Thanks a lot.
     
  16. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Hi,

    I want to to have some HID USB footswitch controllers connect to unity and get response from them on PC Windows in Unity only. This Foot controllers are HID devices without requiring an driver to install.

    1) Does your package have an USB input monitor?
    * So if I connect several foot controllers, can I "Rewired" recognize them to run different functions.
    2) Would that generally possible to use any HID USB controller and make it use in by Rewired?
    3) What would happen if I have 2 USB HID controllers connected? Does Rewired recognize both and separate them to use for different functions?

    Thank you!

     
    Last edited: Feb 8, 2019
  17. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    You do not have to do that unless you are disabling the Rewired Input Manager at runtime or recompiling scripts at runtime. Just so you are aware, alt-tabbing away from the Unity editor does not cause this on its own. Rewired is not disabled on Alt-Tab by anything within Rewired's code. I cannot reproduce your issue if you're saying merely the act of Alt-Tabbing away is causing this and not a recompile after Alt-Tabbing away. If that's the case, something in your project, either some Unity configuration option or some script in your project, is causing Rewired to be disabled. I would investigate and see if you can figure out when OnDisable is being called. Attach a MonoBehaviour to the Rewired Input Manager game object which logs something in OnDisable and look at the call stack.

    If you are recompiling scripts at runtime which would be the case if you are saving code changes in Visual Studio while the game is running, this pattern is required and explained in the documentation here:
    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#null-reference-during-recompile

    Rewired objects (Player, Controller, Controller Map, etc.) do not inherit from UnityEngine.Object and therefore cannot be serialized to object references by the serialization system and deserialized like a reference to a GameObject, MonoBehaviour, etc. can. There is no way I could change things to make storing references to Rewired objects continue to work after recompiling at runtime without rebuilding every class in Rewired as MonoBehaviours and ScriptableObjects which would be incredibly inefficient.

    Something outside Rewired's control is responsible for changing data when you save something in Visual Studio at runtime. It's probably related to Unity reloading serialized data at that time and not loading the data before calling one of the MonoBehaviour callbacks that results in code being executed before serialized data has been reloaded. The exact code of that error message:

    Code (csharp):
    1. if(_canvas.renderMode == RenderMode.WorldSpace) {
    2.     Logger.LogError("Touch controls cannot be used with a world space Canvas. Change the canvas render mode to screen space.");
    3.     return false;
    4. }
    That means without a doubt the Canvas component above the Touch Control IS set to WorldSpace render mode. Rewired is not setting this to WorldSpace, so it can only be Unity doing it.

    This code is only called in:
    OnValidate()
    OnCanvasGroupChanged()
    OnTransformParentChanged()

    That means one of these callbacks is being executed on the Touch Control MonoBehaviour after recompile starts but BEFORE serialized data is reloaded by Unity, causing the Canvas render mode value to be set to the default of World. This is baffling. I am going to have to try to reproduce it and see if I can find a way to detect and block it. It's most likely OnValidate.

    Edit: Looking at your call stack, it is indeed OnValidate being called on TouchPad by CanvasRenderer.RequestRefresh. The only possible way this could result in the error you are seeing is if Unity is calling this BEFORE it deserializes the data on the Canvas itself and sets it to your true render mode.

    Code (csharp):
    1. ...
    2. Rewired.ComponentControls.TouchPad:OnValidate()
    3. UnityEngine.CanvasRenderer:RequestRefresh()
    I have never seen Unity do this before.

    The best part is I already have checks in the code to detect initialization with a non-serialized boolean that is cleared when Unity recompiles and return before executing this function. For it to be getting to this error code, it means that OnEnable has already been called on the TouchPad component before this code runs. That means Canvas is in a state where its data hasn't been deserialized yet while OnEnable has already run on other GameObjects. I didn't think that was even possible. Deserialization should be happening before OnEnable is called on anything as far as I am aware. UnityEngine.CanvasRenderer is a core component and not in the Unity UI source code so I cannot see when it runs this RequestRefresh function.

    After reviewing the code, I have yet even more checks here to make sure something like this does not happen, using a Coroutine to defer OnEnable initialization until the next frame after a recompile so as to prevent order of initialization issues with other objects. There's no way the object could be initialized before other objects are ready. I can see I explicitly tested and guarded against this scenario.

    Edit:

    After doing some testing (not able to reproduce the error), I have determined that CanvasRenderer.RequestRefresh is being called immediately BEFORE the application recompiles, not after. That means the TouchPad component is still initialized because the reloading of the AppDomain and clearing of non-serialized variables such as my _initialized boolean has not occurred yet by the time CanvasRenderer.RequestRefresh is called. In order for Canvas.renderMode to be set to World at this time like it is based on the error you posted, that would mean that the data on the Canvas has already been cleared before this function call occurs BUT the non-serialized boolean _initialized has NOT been cleared yet. This is completely baffling behavior. I've never seen anything like this before.

    Upon further digging, I have come to two conclusions:
    1. This perfect storm scenario of execution order is impossible to detect.
    2. I can do nothing but remove the check and the warning.
     
    Last edited: Feb 9, 2019
  18. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    The RewiredStandaloneInputModule functions in the exact same way the StandaloneInputModule does and performs the same function. The Unity version is documented here: https://docs.unity3d.com/Manual/script-StandaloneInputModule.html

    Extra information pertinent to Rewired's version is here:
    http://guavaman.com/projects/rewired/docs/RewiredStandaloneInputModule.html
     
  19. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    No, it works with HID devices, regardless of the connection protocol.

    The Raw Input input source only recognizes HID devices that identify themselves as HID Gamepad, Joystick, Multi Axis Controller, and Consumer Control. Keyboards and mice will be recognized but will not appear as separate devices and instead contribute to the "global" keyborad/mouse values.

    Rewired supports many optional input sources including:
    Raw Input
    Direct Input
    XInput
    SDL2
    Unity

    Whether devices appear or not depends on the input source(s) in use.

    If the device is detected, yes.

    Yes, for the most part.

    Yes.

    See this for understanding how Rewired works with unrecognized controllers:
    http://guavaman.com/projects/rewired/docs/SupportedControllers.html#controllers-without-definitions

    Download the free trial and see how it all works:
    http://guavaman.com/projects/rewired/trial.html
     
    Last edited: Feb 8, 2019
  20. dev_runeofdark

    dev_runeofdark

    Joined:
    Oct 27, 2016
    Posts:
    10
    Hi,

    I have a small question is it possible to get the calibrated deadzone of the thumbstick from a controller the player used?

    If its possible can you show my an example?

    Thanks
     
  21. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,080
    I can't figure out what's going on there. I've created a character controller with PlayMaker and it works with keyboard and mouse now I need a simple way to add my PS4 controller but seems there is no easy way? I just need when I press X button on my gamepad that will be equal with when I press W on my keyboard.
     
  22. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
  23. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Two Troubleshooting topics that will take you through step-by-step to find out where your problem is:

    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#joystick-problems
    http://guavaman.com/projects/rewired/docs/Troubleshooting.html#debug-information

    1) Is your Character Controller using Rewired for input?
    2) If so, follow the steps in the links above to determine if all the criteria are met for a Joystick to work in a Player.
     
  24. dev_runeofdark

    dev_runeofdark

    Joined:
    Oct 27, 2016
    Posts:
    10
    Thanks this helps me a lot. I have only two question left.

    1: In the InputManager has every element in the JoystickMap an index is this the same index for the same axis in the CalibrationMap.Axes list?

    For example Left Stick X has index 0 in the Inputmanager, is this also 0 as in the CalibrationMap.Axes list.

    2: Has the Joystick.CalibrationMap the default list with calibrations or is this the same as the CalibrationMap from Joystick.GetCalibrationMapSaveData() or is this another class?
     
  25. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,080
    Thanks. For backup I just moved "ControllerDataFiles" to my own folder! is that enough or should I copy "HardwareMaps" folder too?
     
    Last edited: Feb 10, 2019
  26. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    What are you trying to achieve by doing this? ControllerDataFiles does not store your user data, the Rewired Input Manager GameObject does, if that's what you're trying to back up. (see docs) You should not be moving core components of Rewired into other folders. That's a sure fire way to break things, especially when updating.
     
    Last edited: Feb 10, 2019
  27. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    No. Element indices are not shown in the Rewired Input Manager. There's an entire layer between the element index and the Controller Map called Element Identifiers. A controller's element indices can and do change per platform, per input source, per version of a driver, per many, many factors. Controller Maps are only concerned with Element Identifier Id, not the element index because the Element Identifier Ids are constant across platforms and other factors. It's even possible for a button to be an axis, an axis to be a button, or for an element to not even exist depending on the platform/input source.

    You cannot know what an element index for a particular element is going to be on a controller until that controller is plugged in. Many factors go into determining which controller definition is chosen based on the platform and input source(s) and other options in use. Once the controller is connected, the Element Identifier Id can be used to look up the index.

    Edit:
    The indices of bindings you create there is arbitrary and depends on the order you create them. There's no relationship between the order of a Controller Map's bindings and the Calibration Map.

    Calibration Map always has the same number of axes as the Controller has axes. A Controller's axis count and order is determined by the controller definition and is not guaranteed to be in any particular order. Each axis in the Calibration Map points to the axis at the same index in the Controller.

    I do not recommend trying to create your own customized default controller calibrations. Allow the user to calibrate his own axes as is shown in the examples I linked. It will avoid a lot of potential problems.

    I don't understand the question. All the ...SaveData classes are just wrapper classes that make it easy to get all the savable data from Players and Controllers for saving to XML/JSON. They can't be used directly.
     
    Last edited: Feb 10, 2019
  28. FritzC

    FritzC

    Joined:
    Nov 15, 2017
    Posts:
    15
  29. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    The only possible way that could happen is if UnityEditor.EditorUtility.DisplayDialogComplex is returning a value of 1 (the option to open the link for more information) by itself without receiving any user input over and over and over. UnityEditor.EditorUtility.DisplayDialogComplex is part of UnityEditor.dll and displays a dialog box on the screen that takes control from the application until the user makes a choice. Either something is wrong with your Unity install (I can't possibly imagine what), something on your system is automatically closing the dialog, or the ESC key is stuck on your keyboard. I cannot reproduce it using the same version of Unity and the trial version of Rewired. This code has been untouched for several years and nobody has ever once reported anything like this. Displaying a dialog window is core functionality of the Unity Editor over which I have no control. There's really nothing I can do.
     
    Last edited: Feb 10, 2019
  30. dev_runeofdark

    dev_runeofdark

    Joined:
    Oct 27, 2016
    Posts:
    10
    Thanks for the info

    It is not my intention to modify the calibrations. Only read the deadzone the user has calibrated.
     
  31. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Actually, my information was incorrect and incomplete. You don't even see the element identifier id in the Rewired Input Manager. The indices of bindings you create there is arbitrary and depends on the order you create them. There's no relationship between the order of a Controller Map's bindings and the Calibration Map.

    Calibration Map always has the same number of axes as the Controller has axes. A Controller's axis count and order is determined by the controller definition and is not guaranteed to be in any particular order. Each axis in the Calibration Map points to the axis at the same index in the Controller.
     
  32. dev_runeofdark

    dev_runeofdark

    Joined:
    Oct 27, 2016
    Posts:
    10
    Ok If I understand you the element Identifier Id you mentioned earlier isn't necessary or needed to find the index of the calibration map. It is actually the same index as that from the controllers definition? For example Left Stick X has index 3 at the controllers definition, than is index 3 the calibration for Left Stick X in the CalibrationMap.

    Am I right?
     
  33. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Element identifier id is not necessary to use the calibration map. It is necessary if you want to display the name of the axis they're mapping.

    You are likely looking at the Element Identifier in the controller defintion. This is how the system works:

    eid.png

    The front-facing elements you see in a controller definition are Element Identifiers. They are accessed by Id, not index. They do not line up with the final button and axis elements in the controller.

    Every input-source-specific mapping in the controller definition maps the element index to the Element Identifier. This can and does change per platform, per input source, per driver variant, etc. Order of elements may change, the number of elements may change, and even the element types may change.

    To get any metadata about the controller element, you must use the Element Identifier Id.

    Code (csharp):
    1. for(int i = 0; i < joystick.axisCount; i++) {
    2.            
    3.     // Get the name from the element identifier for the axis
    4.     Debug.Log(joystick.AxisElementIdentifiers[i].name); // one axis element identifier per axis in the controller
    5.  
    6.     // Or use the newer convenience property in the axis element
    7.     Debug.Log(joystick.axes[i].elementIdentifier.name);
    8. }
    9.  
    10. // If you know the id of the element identifier you want
    11. Debug.Log(joystick.GetElementIdentifierById(elementIdentifierId).name);
    12.  
    13. // Another way to get the axis index from the element identifier id
    14. int axisIndex = joystick.GetAxisIndexById(elementIdentifierId);
    15.  
    The Calibration Map is a map created specifically for the Controller at the time it is created. It contains 1 axis mapping per axis element in the controller. The array of axes in the Calibration Map line up with the array of axes in the Controller. If you want to calibrate Axis 0, you use the [0] index of Axes in the Calibration Map.

    To display the name of the axis to the user, you must get the Element Identifier of the element at Axis 0.

    Look at the source code of ControlRemappingDemo1.cs, line 761 in the examples folder to see how to do calibration. Control Mapper also shows a fully-functioning demo of controller axis calibration and includes the source code.
     
    Last edited: Feb 11, 2019
  34. AndyLangberg

    AndyLangberg

    Joined:
    Jul 6, 2018
    Posts:
    37

    This might be loosely connected, or not at all, but at least it's easily reproducible:

    Code (CSharp):
    1. Rewired: Touch controls cannot be used with a world space Canvas. Change the canvas render mode to screen space.
    2. ------- Rewired System Info -------
    3. Unity version: 2018.3.2f1
    4. Rewired version: 1.1.22.2.U2018
    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.Logger:LogError(String, Object)
    14. Rewired.Logger:LogErrorNow(Object, Boolean)
    15. Rewired.Logger:LogError(Object, Boolean)
    16. Rewired.Logger:LogError(Object)
    17. Rewired.ComponentControls.TouchControl:EjMLFLBRWYuJhkijMbvSxjQylzW(Boolean)
    18. Rewired.ComponentControls.TouchControl:OnSetProperty()
    19. Rewired.ComponentControls.TouchInteractable:OnSetProperty()
    20. Rewired.ComponentControls.TouchPad:OnSetProperty()
    21. Rewired.ComponentControls.TouchPad:set_inertiaFriction(Single)
    22. PresentationLayer.Screens.ViewData.ZoomableScrollRect:Update() (at Assets/App/Scripts/PresentationLayer/Screens/ViewData/ZoomableScrollRect.cs:76)
    This call stack refers to a Update() in my script function which simply reads

    Code (CSharp):
    1. _touchPad.inertiaFriction = 2;
    _touchPad is a straight reference to a rewired TouchPad script on a Touch Pad object. Every time I click "run" this pops up once.
     
  35. f1chris

    f1chris

    Joined:
    Sep 21, 2013
    Posts:
    335
    I'm trying to achieve this below but can't figure out how :

    my mobile is using the right side of the screen to look around ( 1st person view game). It's working nicely with a touch pad area. What I want is to have a button in the same area that will start the firing of the weapon but at same time would like to continue the look around of the touch pad.

    How can i have the button to receive the press event but having the touch pad under it to receive all the move events ?

    I tried with a joystick on top of the touch area and it working fine, except I prefer the smoothness of the touch pad.

    Any help ?

    thx in advance
     
  36. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Look at your first Canvas component on or above the TouchPad GameObject. The only way this error could ever possibly be reported is if Unity is returning RenderMode.WorldSpace for the Canvas.renderMode property on the first Canvas above the TouchControl. There is no other way this error message is ever logged. Being called in Update, it's clear that this isn't any weird order of execution problem like is possible in OnValidate. By the Update loop, everything is already setup in all objects. Therefore, there has to be a Canvas in your hierarchy that is set to RenderMode.WorldSpace that the TouchControl is finding.

    This error being logged would not affect anything else in the project. It's a Debug.Log, not an exception, and therefore does not halt execution of any other code.
     
    Last edited: Feb 11, 2019
  37. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Unity UI's touch detection is based on raycasting. You cannot make a button that you can press that will also activate other controls underneath it using Unity UI without taking special effort to raycast against everything, which would involve changing the input module to send events to all objects the raycast hit in the stack and not just the top one. The Pointer Input Module only sends click/touch events for the top-most Graphic component with Graphic.raycastTarget enabled that the raycast hits, blocking all others beneath it. Changing the input module to send events to all in the stack would have bad consequences on all UI's that rely on raycast blocking, so this is not something I can do on the RewiredPointerInputModule. (It would also cause chaos with Selectable selection.)

    The best you can do is to enable "Activate on Swipe In" on the pad area which will make it activate when the finger moves off the button and into the pad area, but it will not make the touch pad respond while the finger is actually over the button.

    You might be able to do achieve it if you disable Graphic.raycastTarget on the button when pressed, re-enable it when released. There also might be problems doing this.
     
    Last edited: Feb 11, 2019
    f1chris likes this.
  38. Miguelfanclub

    Miguelfanclub

    Joined:
    Jun 14, 2015
    Posts:
    64
    Hi,
    all is good when moving along items in a grid layout using automatic navigation (like an inventory grid) when the game is running in unity.
    This particular behavior is not working at all when I do an EXE.

    Unity 2018.2 and playmaker
     
  39. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    1) I assume you're talking about navigating a Unity UI interface using the Rewired Standalone Input Module. A more detailed explanation is very important for getting proper support.
    2) There is no difference in running the Rewired Standalone Input Module in the editor vs a build.
    3) This link contains explanations for the most common causes of differences in build vs editor behavior.
    4) Is some GameObject set to be the default selected GameObject in your event system?
     
  40. AndyLangberg

    AndyLangberg

    Joined:
    Jul 6, 2018
    Posts:
    37
    Seems like this is due to another asset I'm using called DoozyUI, whose "hide @Start" function which apparently does something weird with the canvas as it's hiding the menus. Annoying to have an error in the code I can't do anything about, but lucky that it doesn't crash anything at least.
     
  41. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    That explains it. It probably also explains the OnValidate error which I thought was caused by Unity but is probably caused by DoozyUI changing the Canvas render mode.

    Disable the top-most Rewired touch controller GameObject (or one above it) until the UI is ready to be displayed and you won't get the error anymore.
     
    Last edited: Feb 12, 2019
  42. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    531
    HEY!! Amazing work. I recall reading this was a fairly big task for you. Was starting to get a bit worried cause Mono is getting deprecated (or already has been) on some platforms. Cheers.
     
    guavaman likes this.
  43. Sabrino

    Sabrino

    Joined:
    Aug 8, 2015
    Posts:
    35
    Yes, thank you for IL2CPP support!
     
    guavaman likes this.
  44. guavaman

    guavaman

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

    Please see Updating Rewired before updating.

    @crazymonkay - This includes the changes to the GetControllerInstance methods to include baked information.
    @Ward101 - This includes a new event type, AxisActiveOrJustInactive, that will do what you want.

    Release notes since the last version published on the Unity Asset Store:

    1.1.23.0:

    API Changes:
    - Added ControllerStatusChangedEventArgs.controller property.
    - Added ControllerAssignmentChangedEventArgs class.
    - Added Player.ControllerHelper.ControllerAddedEvent event.
    - Added Player.ControllerHelper.ControllerRemovedEvent event.
    - Added InputActionEventType.AxisActiveOrJustInactive.
    - Added InputActionEventType.AxisRawActiveOrJustInactive.

    Changes:
    - Windows, Raw Input: Added support for multiple top-level HID controls on a device with identical usage page, usage, and link collection information.
    - Removed Canvas.renderMode check and warning in Touch Controls due to an impossible to detect scenario involving runtime script compilation and Unity serialized data being cleared in an unpredicable order on objects before script recompilation begins causing Canvas.renderMode to report a value of World even if not set to World triggering the error warning.
    - Updated Bolt integration with new InputActionEventTypes.

    1.1.22.4:

    Changes:
    - Action Element Maps in Controller Map instances obtained through ReInput.MappingHelper.GetControllerInstance and related methods now contain element identifier names and element indices.
    - Changed Gamepad Template mapping for Saitek P880 to map gamepad Left/Right Trigger to Button 7 and Button 8 instead of Left/Right Shoulder.

     
    Bartolomeus755 likes this.
  45. obstudio

    obstudio

    Joined:
    Sep 30, 2016
    Posts:
    58
    Hi, great job implementing PS4 gamepad features. Have you tried also implement support for speaker that is build in into this gamepad?
     
  46. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    No. That is not supported. Rewired doesn't do anything audio related. That would likely require a driver on Windows to work anyway.
     
    obstudio likes this.
  47. Khena_B

    Khena_B

    Joined:
    Aug 21, 2014
    Posts:
    273
    I'm getting some jitter from the joysticks axis values when holding them still, the Dualshock4 is worse than the Xbox One controller, I'm rounding the axis value and it makes it jump from 0.1 to 0.2 back and forth when around 0.15273 for example, is this normal or is there a way to make the joysticks less sensitive?
     
  48. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Rewired does not do any filtering or jitter removal on joystick axis values. The value you're seeing is what the hardware is sending, modified by dead zone, sensitivity transformations (if any), and fit into a -1 to +1 range. Sensitivity settings would not achieve the result that you're looking for. The only solution I can think of is filtering/jitter removal. Rewired doesn't offer this as a feature.
     
    Khena_B likes this.
  49. vambier

    vambier

    Joined:
    Oct 1, 2012
    Posts:
    102
    I just started using rewired in combination with the rex engine. I followed the steps for integrating with rex engine but I'm getting errors when running my game "KeyNotFoundException: The given key was not present in the dictionary"
    Do you have any idea what could be going wrong? I can see the values change in the debug information when I press buttons on my controller.
     
  50. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Undoubtedly RexEngine has been updated since version 1.03 which is the version Rewired supports (Rex Engine is now version 1.38) that must have added new Actions to the system which have no equivalent Actions in the default Rewired Input Manager that the Rex Engine integration comes with. Rex Engine calls for the value of some new Action like "Fly" which didn't exist before, the integration script tries to look up the Rewired Action for the value "Fly" from RexEngineInputManager and bam - Key not found exception. You will either have to modify RexEngineInputManager to support the new Action(s) or wait until I can update/rebuild the integration for RexEngine version 1.38.