Search Unity

Rewired - Advanced Input for Unity

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

  1. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    I sent you instructions.
     
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
  3. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Thanks for all the information!

    I suppose the biggest issue in my mind here is what level of Midi support would be expected and for what purpose? Obviously, the wider the net the better.

    A Custom Controller inputting Midi note/velocity values into buttons/axes would be appropriate for the most basic use case of using a Midi controller as a game controller. This would be fine for playing a normal game using any Midi device of your choice. However, it would not really be that appropriate for a music game.

    If Rewired had Midi support, I'm sure most who are interested in that would want it for music games. Mapping 127 keys to Actions and reading music input that way would be cumbersome and not intuitive. And then there's the issue of output. Also, I'm not that familiar with all the features / requirements of Midi. I see you have keys and velocities, but there are also all kinds of other features such as pitch bending, attack, sustain, etc. There are probably many more of which I am not aware. You would also need access to highly-accurate timing information about every input, which means a frame rate independent, multi-threaded API. These are the reasons why I stated you would need a completely new API to support all of this. None of these features are supported by joysticks, keyboards, mouse, etc., and it doesn't fit well into the Player-Action paradigm. Proper Midi support should probably also be able to output back to the Midi device for playback. You'd also need ways to change instruments on the device, etc. Essentially a full-blown Midi API.
     
  4. ftejada

    ftejada

    Joined:
    Jul 1, 2015
    Posts:
    695
    Hi @guavaman
    The new update seems to work perfectly on PS4.
    Thanks for your help. If we have something else, I'll tell you

    regards
     
  5. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Thanks for the update. Glad everything's working for you now.
     
  6. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    109
    Hey @guavaman ! Thanks for Rewired, it's been an excellent addition to my collection. I'm wondering if you can shed some light on this.

    Trying to use RewiredConsts.Action (as per the user manual) but Unity 2018.2.3 cannot find it.

    I'm mainly looking for a way to do not have to define each individual button action name and use matching action names in the animator controller. I imagined looping through the Rewired actions, then on a valid button press, map that action to the animator state machine. I couldn't find a player.GetButtonDown(*) and was thinking that I would have to use the ActionIdProperty attribute to manually map them in the inspector by exposing the actions and a list of statemachine parameters. At least that way I could tell the script which were bools and which were triggers. Have you tried something like this before?

    Thanks!
     
  7. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    RewiredConsts does not exist unless you export your Actions from your Rewired Input Manager to that class:
    http://guavaman.com/projects/rewired/docs/HowTos.html#exporting-constants

    Rewired does not automatically create any constants for you. This would not be possible since you can have as many Rewired Input Managers in your project as you want all with different Action sets.

    If you're talking about doing this at runtime, see Important Classes:
    http://guavaman.com/projects/rewired/docs/HowTos.html#important-classes

    ReInput.mapping:
    http://guavaman.com/projects/rewired/docs/api-reference/html/T_Rewired_ReInput_MappingHelper.htm

    Code (csharp):
    1. foreach(var action in ReInput.mapping.Actions) {
    2.     Debug.Log(action.name);
    3. }
     
  8. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    109
    Perfect I got it, thanks again Guavaman.
     
  9. Kybernesis

    Kybernesis

    Joined:
    Dec 3, 2013
    Posts:
    27
    Just started using Rewired since I need to support Keyboard & Mouse, Keyboard Only, Mouse Only, single touch with joystick and multi-touch without joystick.

    I have managed to implement all of the above for movement and rotation and clicking on objects for the first 3.

    But the touch scenarios require look rotation when dragging on any spot on the screen that is not another controller or UI, so I added a screen-stretched invisible TouchPad. Which works perfectly until I want to select objects in the scene. Cause then the touchPad captures all my clicks, which is to be expected.

    So my question is, is there any way to make touchpad only handle hold/dragging and let all press and double press events through?
     
    rubble1 likes this.
  10. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    Let me clarify some terms ... I will simplify just for the purpose of illustration.

    Typically keyboards are various number of keys. A piano has 88 keys. You can get 25, 49 and 61 key variants of the same keyboard.


    Channels: We have 16 to work with so you can put a different device (e.g. midi controller) on a different channel. So you could have 16 independent devices. On the Atari ST there was a game called Midi Maze that supported 16 players. Each player was on a different Atari ST machine (different midi channel corresponds to each player) all connected together via midi cables. It was great having midi built into the computer. These days with usb midi controllers work really nicely on windows and mac by being automatically detected.

    Midi Controller is just a keyboard without any sounds at a basic level [input only]. See LX25+ (25 keys) is an example see more details at this URL.

    https://www.nektartech.com/impact-lx25-plus.html

    Midi Synth is a keyboard with sounds at a basic level [input/output]. An example is Yamaha e353 (61 keys) is another example.

    https://usa.yamaha.com/products/musical_instruments/keyboards/portable_keyboards/psr-e353/index.html

    NOTE: synth modules (rack mounted/standalone) without keyboards are output only. The old Roland mt32 comes to mind as an example.

    I was thinking of MIDI input only and using it as game controller more or less. Not sure what the others requesting midi were expecting. Of course I would not complain if everything was included. :)

    For example here is an article of someone turning a guitar hero game controller into a midi controller. It makes a good example that a midi controller is input only. He does provide good overview of how he did the mapping and good amount of references. Good discussion on how he mapped game controller inputs to midi commands.

    https://slapyak.wordpress.com/guitar-hero-midi-controller
    more details on fingering for each note.
    https://slapyak.wordpress.com/ghmc-operators-manual/

    So in MIDI controller sense we (end user developers) have sounds stored on the computer. In the music "world" they have DAW (digital audio workstations). DAW has all of the sounds and software for manipulating the sounds (creating new sounds, etc.) ont he computer. Then you just use the midi controller to play all of the sounds which are stored on the computer (simple case). Ableton is a good example of commercial DAW software.

    https://www.ableton.com/en/live/what-is-live/

    USE CASE 1: midi input only

    So in midi input only case (using a midi controller) the end user developers are responsible for all audio/midi output. That is the use case I was thinking about. Basically for a very simple use case you could treat all note on/note off as a giant game controller button box. In my case I would not expect more than 1 midi controller (See Exhibit A).

    Another thing you need to think about it how many notes can someone press concurrently? If playing with both hands that is 10 notes concurrently. What is the limit that would be supported 32 or 128 notes concurrently?

    USE CASE 2: midi input and output

    In the simple case of output a few notes on a midi device would be nice in theory. It kind of really expands the scope greatly in my opinion. Leave audio/midi output to the developers.

    If supporting full midi output then you might have more issues with those are particular about timing problems in midi output. It might be all the fault of the operating system. Some people laugh when say you are using midi on windows and not a Mac for that reason. You really do not want to be spending time debugging someone's MIDI output timing issues remotely.

    There is a reason why car dealers require people to bring in their cars and charge a fee for diagnosing problems. That would definitely be a computer consulting fees apply (i.e. at a minimum travel/hotel/car rental, plus your time). :)

    Exhibit A:

    LX25plus_midi_controller.JPG
     
    Last edited: Aug 22, 2018
    guavaman likes this.
  11. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    No. These controls are all based on Unity UI. Unity UI uses raycasting to determine what is being touched (GraphicRaycaster component on your Canvas). Touch events are sent to the top-most GameObject that blocks the raycast. A gigantic touchpad that covers the entire screen catches all raycasts. Raycasts cannot be let through unless you disable raycast blocking on the object (it will no longer receive events). Doing what you want would require replacing Unity UI's raycasting and event systems with custom systems that use RaycastAll and send events to every object the raycast hits. It is outside the scope of Rewired to replace Unity's EventSystem and UI raycasting system with a custom system that fundamentally changes the way the UI system works.

    You would have to create your own touchpad that just uses the raw touch events and doesn't use Unity UI. Use a Custom Controller to pipe in the data to Actions:
    http://guavaman.com/projects/rewired/docs/CustomControllers.html
     
    Last edited: Aug 22, 2018
    rubble1 and Kybernesis like this.
  12. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Wow, thanks for the information overload! All useful.

    So Use Case 1 is the only one that would fit into Rewired's current system. While it's neat to be able to use a midi controller as a game controller, I'd be very hesitant to advertise midi support while only supporting the devices as game controllers. The majority of people looking for something that supports midi are going to be expecting all the standard midi features (use case 2). It's just too far outside the scope of Rewired to roll a full midi api into it. That's a whole other product in my opinion.

    That's a very good point about the midi output and OS issues. I had heard about that before but forgot that was an issue.
     
  13. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    You could just call it "other input options" and not call it MIDI. Just say it accepts midi note on/off values on channel 1 only. :)

    One thing that would be interesting is using MIDI input for some sort of automated testing of the input system. For standard game controllers I do not think there is nice way to use a usb protocol analyser to playback all of the game controller inputs in a fashion the operating system would accept.

    But if you had a MIDI input in theory you could use a MIDI sequencer and just record all of that MIDI input. Then you could just play it all back it into the input system for testing.
     
    vivalavida likes this.
  14. Kybernesis

    Kybernesis

    Joined:
    Dec 3, 2013
    Posts:
    27
    Okay, I figured as much as it uses the Unity UI. I'll make my own non-UI touch region/pad system then :)
     
  15. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Hmm... Spend all the time to implement it and then don't tell anyone it exists...

    That is an interesting idea.
     
    vivalavida likes this.
  16. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    You would just have tell one person and see how quickly it spreads. :)

    In theory if MIDI input was working you could also use for running simple demos too. If you want to show a particular capability then load this "midi file". With 16 channels in MIDI you could simulate 16 players too.
     
  17. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    You would be the person. :D

    Midi playback of input would be cool, but it would be more straightforward and far more user friendly to allow direct input of Action values (similar to a Custom Controller but without the Custom Controller). Or even have an input recording file format that could be both recorded and played back. While this is cool and all, I believe this sort of thing should be done above the input system, not through it. Your game has to process input somehow. When it processes it, some in-game action is executed when an input is received and the action is allowed to take place based on the current game states. Recording the actions that take place is superior to recording input in my view for many reasons. One reason is you never know if your game states will always sync up in the recording vs what's happening in the game due to all kinds of things (timings, randomization of certain values, permissions, odd differences in physics, etc). This could lead to the input playback getting out of sync with what's supposed to be happening and you end up with a recording that doesn't reflect what actually happened. Recording the in-game actions wouldn't have this problem as you wouldn't even have to check permissions when executing an action. That would prevent out-of-sync issues.
     
    vivalavida likes this.
  18. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
  19. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    @guavaman

    Have you seen polycade? It is interesting since it supports steam directly. It mentions Broforce (which is a game made with unity) so that got my attention. More information can be found at the link.

    http://www.polycade.com/

    polyCade.JPG
     
    flashframe likes this.
  20. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    I don't know if this has been addressed earlier in the thread, but I don't feel like scrolling through 89 pages.

    Importing Rewired has exploded the recompile time (especially in comparison to my very small project codebase). I've placed it in Plugins just to be safe, and since it's mostly in dlls it should be good in that respect too. However, my recompile times have gone from maybe a second or two to about 10.

    I also tried putting Rewired in its own assembly definition file. Just adding the file took a good five minutes, and it doesn't seem to have made any effect on the delay.

    I was in 2017.3, so I tried it in 2018.1 and got the exact same results.

    Deleting the examples folder seems to have helped a little bit.

    I'm seriously baffled because the meat of this asset shouldn't even need recompiling in the first place! Anything else I can do here? I've never had an asset impact my compile time like this before (in fact, I have several other code assets in this project, all of which have had little to no impact on compile time). This kind of delay seriously adds up for tiny changes and makes it difficult to work, especially for rapid prototyping.
     
    Last edited: Aug 29, 2018
  21. Verdemis

    Verdemis

    Joined:
    Apr 27, 2013
    Posts:
    92
    Hello everyone,

    I'm currently getting started with custom controllers in rewired. I created a custom controller for a touch controller. But I have one problem. The touch controller is a ui canvas and when I touch a button this button gets selected and my buttons in my ui game menu get deselected.

    p.ex. I have a menu with 4 buttons

    Start Game
    Load Game
    Options
    Quit

    Start Game is always preselected when the scene has been loaded. On my touch controller I have a virtual d-pad and four buttons. When the player touches the d-pad up or down I want to move through the menu and not "select" the touched button, so my game ui elements keep selected.

    Maybe there is already a build in way to prevent my touch controller to behave like regular ui elements and doesn't interfere my regular game ui?
     
  22. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    It is not recompiling. It is Unity loading serialized controller definitions:
    http://guavaman.com/projects/rewired/docs/KnownIssues.html#increased-compile-play-time-editor

    Putting it in Plugins isn't going to help with this.

    There's no way Rewired should be adding 8 seconds to your compiles/reloads. I've tested this many, many times and it adds 2-3 seconds max on very old hardware.
     
  23. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Are you using the built-in Touch Controls or your own UI touch controller? In either case, this isn't a Rewired-specific issue.

    If you have created your own touch control, you make the Selectable non-navigable (maintain selected state) by setting the Selectable's (Button's) navigation property to None in the inspector. This will prevent the Selectable from being selected, but this isn't going to stop your UI element from getting deselected when you click somewhere else on the screen. Unity will deselect the selected UI element when you click anywhere else on the screen. This is just how Unity UI works.

    The only way I know of to get around this is to watch the value of EventSystem.current.currentSelectedGameObject and set it to a value if it goes null forcing there to always be something selected.

    If your users have a touch screen, it's expected they will touch the UI elements directly to activate them.
     
  24. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    I haven't seen this. Pretty cool design! Thanks for sharing.

    Broforce uses Rewired, BTW.
     
  25. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    Awesome, thank you very much! I figured there might be a known cause for this. My apologies for not having trolled through the documentation enough to see the "known issues" section, but I'd just started using the asset for the first time at like 3am. :D
     
    guavaman likes this.
  26. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Rewired 1.1.19.6 is now available.

    See Updating Rewired before updating.

    Release Notes:

    1.1.19.6:

    Bug Fixes:
    - Reverted change to Windows Standalone Native Mouse Handling made in 1.1.19.2 to fix issue causing UnityEngine.Input mouse input to stop working when the built application is launched and the application loses focus during with the Unity splash screen logo and Rewired initializes when the application is out of focus. This change caused UnityEngine.Input mouse input to stop working in Exclusive Fullscreen mode. Implemented a new workaround for the launch out of focus issue.
     
  27. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    I did not know Broforce was a Rewired game too.

    There is a video of 4 player version of Broforce using two polycade in this video.


     
    guavaman likes this.
  28. Verdemis

    Verdemis

    Joined:
    Apr 27, 2013
    Posts:
    92
    Thank you for your quick response. I'm using the rewired touch controller... I created it via the create -> rewired menu.

    And I noticed that I get error messages... but only sometime and sometimes not. They appear on start of the scene right away or they don't appear at all.


    Rewired: Exception drawing properties:
    System.NullReferenceException: Object reference not set to an instance of an object
    at Rewired.Editor.Libraries.Rotorz.ReorderableList.ReorderableListControl.PrepareState (Int32 controlID, IReorderableListAdaptor adaptor) [0x00000] in <filename unknown>:0
    at Rewired.Editor.Libraries.Rotorz.ReorderableList.ReorderableListControl.Draw (Int32 controlID, IReorderableListAdaptor adaptor, Rewired.Editor.Libraries.Rotorz.ReorderableList.DrawEmpty drawEmpty) [0x00000] in <filename unknown>:0
    at Rewired.Editor.Libraries.Rotorz.ReorderableList.ReorderableListControl.DrawControlFromState (IReorderableListAdaptor adaptor, Rewired.Editor.Libraries.Rotorz.ReorderableList.DrawEmpty drawEmpty, ReorderableListFlags flags) [0x00000] in <filename unknown>:0
    at Rewired.Editor.Libraries.Rotorz.ReorderableList.ReorderableListGUI.‫‪‍‌‏‏‬‭‌‍‎‭‫
‫‎‫‮‫‪
‌‍‮ (IReorderableListAdaptor , Rewired.Editor.Libraries.Rotorz.ReorderableList.DrawEmpty , ReorderableListFlags ) [0x00000] in <filename unknown>:0
    at Rewired.Editor.Libraries.Rotorz.ReorderableList.ReorderableListGUI.NyZZmEjPZIWstcVISPgGBpmesLi (UnityEditor.SerializedProperty , Single , Rewired.Editor.Libraries.Rotorz.ReorderableList.DrawEmpty , ReorderableListFlags ) [0x00000] in <filename unknown>:0
    at Rewired.Editor.Libraries.Rotorz.ReorderableList.ReorderableListGUI.ListField (UnityEditor.SerializedProperty arrayProperty) [0x00000] in <filename unknown>:0
    at Rewired.Editor.RewiredStandaloneInputModuleInspector_Internal.‭‬‍‍‌‮‮‎‬‍‎‫‫‎‭‭‮‌‍‬‭‏

‎‬
‌
‮ (UnityEditor.SerializedProperty ) [0x00000] in <filename unknown>:0
    at Rewired.Editor.RewiredStandaloneInputModuleInspector_Internal.DrawProperties () [0x00000] in <filename unknown>:0
    at Rewired.Editor.RewiredStandaloneInputModuleInspector_Internal.OnInspectorGUI () [0x00000] in <filename unknown>:0
    ------- Rewired System Info -------
    Unity version: 2018.2.1f1
    Rewired version: 1.1.19.0.U2018
    Platform: Windows
    Editor Platform: Windows
    Using Unity input: False
    Primary input source: RawInput
    Use XInput: True
    Native mouse handling: True
    Enhanced device support: True

    UnityEngine.Logger:LogError(String, Object)
    Rewired.Logger:LogErrorNow(Object, Boolean)
    Rewired.Logger:LogError(Object, Boolean)
    Rewired.Logger:LogError(Object)
    Rewired.Editor.RewiredStandaloneInputModuleInspector_Internal:
‫‭‌‍‫‪‭‌‪‏
‬‮‏‬‌‮‪‏‭
‌‮(Object)
    Rewired.Editor.RewiredStandaloneInputModuleInspector_Internal:OnInspectorGUI()
    Rewired.Editor.CustomInspector_External:OnInspectorGUI() (at Assets/Plugins/Rewired/Internal/Scripts/Editor/CustomInspectors/CustomInspector_External.cs:19)
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr)
     
  29. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Rewired's touch controls cannot be selected. So what's happening here is what I described happens when you click anywhere on the screen off of a Selectable in Unity UI. It just deselects.

    Update Rewired.

    Release Notes:

    1.1.19.1:

    Bug Fixes:
    - Editor DLL: Updated Rotorz Reorderable List due to breaking changes made in Unity 2018.2 API.
    - Windows Standalone, Raw Input + Native Keyboard Handling: Keyboard no longer returns key values the frame after being enabled if any keys were pressed when the Keyboard was disabled.
    - Windows Standalone, Raw Input + Native Mouse Handling: Mouse no longer returns button values the frame after being enabled if any buttons were pressed when the Mouse was disabled.
     
  30. thatscraigz

    thatscraigz

    Joined:
    Mar 27, 2015
    Posts:
    100
    Hi @guavaman!

    Hope you are doing well :) I had a quick question about inverting a players axis using Playmaker.

    Currently I what I'm doing is just loading in a bool on game startup whether the axis is inverted, then doing what I've bracketed in red.



    Is there a better way to do this? Or a way to make it get saved into the Rewired Mappings that get automatically loaded?

    Secondary question, what are the use cases for the two actions at the top of my stack?
    'Rewired Action Element Map Get Element Identifier ID'
    'Rewired Action Element Map Get ID'

    Thanks for the awesome support, it means a lot to me :)
     
  31. guavaman

    guavaman

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

    Rewired never saves anything on its own. You cannot make changes to the Rewired Input Manager data in a build or at runtime.

    Saving data in Rewired is a completely separate process that exists on top of Rewired's core. There is no core built-in saving or loading. There is an included UserDataStore_PlayerPrefs component that is can be used to save and load data to XML using PlayerPrefs, but this is only ever used #1 if you manually choose to use the component and #2 tell it when to save and load data. This component was created for use by Control Mapper. You can create your own UserDataStore component to replace this if you have special saving needs or don't want to use PlayerPrefs.

    On its own, UserDataStore_PlayerPrefs will can load data on start if the option is checked in the inspector or when a joystick is connected. It will save data when a joystick is disconnected. Apart from that, it will not save anything unless explicitly told to do so. Control Mapper is what's responsible for telling UserDataStore to save modified user mappings and controller data. This is normally done when the Control Mapper UI is closed after the user has modified their mappings. If you're not using Control Mapper, you have to do this yourself by calling ReInput.userDataStore.Save or one of the other save functions depending on what data you want to save. UserDataStore is not accessible through PlayMaker Actions. If you want to use it, you would have to add the userDataStore_PlayerPrefs component on the Rewired Input Manager GameObject, then call ReInput.userDataStore.Save whenever any data changes that you want preserved.

    The first Action "Rewired Action Element Map Get Element Identifier Id" gets the Element Identifier Id of the controller element that is bound to the Action. This is used to access the controller element directly for various purposes, mostly for remapping and/or displaying information about what element an Action is mapped to.

    The second Action "Rewired Action Element Map Get Id" is completely useless. The Action Element Map has an id property which is a unique id by which the Action Element Map can be retrieved. This was a property on the Action Element Map so I made an Action for it. However, because PlayMaker cannot store the actual ActionElementMap object, the Action Element Map Id is used to retrieve the Action Element Map in order for the Action to be able to run. This means this Action is useless because it requires the Action Element Map Id in order to look up the Action Element Map from which to retrieve the id. This Action should be removed.
     
  32. NaughtyMoleGames

    NaughtyMoleGames

    Joined:
    Jan 25, 2018
    Posts:
    51
    Having a weird issue where if I set time scale to 0 (to pause the game) everything works fine, until I push a keyboard button then unity/build freezes. Any thoughts?
     
  33. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Rewired doesn't use Time.time in a single place in the entire codebase.

    Rewired will not fail or stop running when Time.timeScale is set to 0 or back to 1. Only FixedUpdate will cease to execute because Unity doesn't call FixedUpdate when Time.timeScale is set to 0.
     
    Last edited: Sep 1, 2018
  34. colorfulKati

    colorfulKati

    Joined:
    Sep 2, 2018
    Posts:
    1
    Hello :)

    I am using a PlayerMouse to move a pointer via mouse and gamepad.
    For some of my objects I use MonoBehaviour functions like OnMouseOver(), OnMouseUpAsButton() and others.
    This works fine when I control the pointer by mouse, but they aren't called when the pointer is controller by gamepad. Is there any way how I could still trigger these events even if the hardware pointer is not hovering over these objects? Or do you have a recommendation on how I should implement this instead?

    Thank you very much in advance!
    Cheers,
    Kati
     
  35. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    PlayerMouse does not trigger Unity's MonoBehaviour events. You would have to trigger those events yourself if you want that functionality by raycasting from the PlayerMouse position from the camera into the scene, getting the raycast hit, and calling the events with SendMessage.
     
  36. thatscraigz

    thatscraigz

    Joined:
    Mar 27, 2015
    Posts:
    100
    Thank you for the in depth and incredibly useful response @guavaman , it really means a lot to me :)
     
    guavaman likes this.
  37. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Rewired 1.1.19.7 is available for registered users. If you'd like to receive early access to updates, contact me here.

    See Updating Rewired before updating.

    1.1.19.7:

    Changes:
    - Universal Fighting Engine integration now blocks input from the Start action while Control Mapper is open.
    - Windows Standalone, XInput: Removed use of Windows LoadLibraryW function due to Sophos HitmanPro.Alert false positive malware detection due to the use of the LoadLibraryW function.

    Bug Fixes:
    - Fixed exception thrown by OnGUIHelper sometimes in edit mode.
    - Windows Standalone, Raw Input/Direct Input + Native Mouse Handling: Horizontal scroll wheel no longer contributes vertical scroll wheel values.
     
  38. Gaspedal

    Gaspedal

    Joined:
    Mar 29, 2009
    Posts:
    376
    Is this a good Idea to use the "useXInput" property for detecting the correct name of the jostick for using XInput later after reseting Rewired?
    like this, just as example:

    void Initialize(){
    useXInput = false; // Rewired will be reseted...
    InitializePlayer();
    PlayerJoystickUID = GetPlayerJoystickUID();
    useXInput = true; // Rewired will be reseted...
    InitializePlayer();
    If PlayerJoystickUID = PS4ControllerUID -> Player using a PS 4 Controller
    If PlayerJoystickUID = XBOXOneControllerUID -> Player using a XboxOne Controller
    If PlayerJoystickUID = XBOX360ControllerUID -> Player using a Xbox360 Controller
    }

    That would work fine but is this a good Idea to solving the XInput Bug problem that still detect the gamepad as "Xbox 360 Controller" always? Is this way safe?
     
    Last edited: Sep 10, 2018
  39. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    No, this is a bad idea for several reasons.

    Resetting Rewired reassigns controllers, reloads controller maps, and a lot of other things. The order of controller assignment will not match when using XInput vs without. XInput devices are assigned first, then other devices when XInput is used. With multiple controllers attached, the order of assignment will be sequential from XInput device ID 0-3. When using Raw Input, it will be sequential based on the device id string returned by Windows. One cannot be matched to the other. There is no way to tell which controller in Raw Input is which controller in XInput. The only time your method would work is when there is only one controller attached to the system.

    Finally, resetting Rewired is expensive. It has to recreate all objects, reinitialize all input sources, and much more. No object from the previous instance is valid in the next instance.
     
    Gaspedal likes this.
  40. Gaspedal

    Gaspedal

    Joined:
    Mar 29, 2009
    Posts:
    376
    thanks, then I will update my code and choose for a input system that can show me the correct controller names. I have tested it with two xbox one controllers and each time it has worked fine. :)
     
    Last edited: Sep 10, 2018
  41. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    Hey there @guavaman ,
    I have been using rewired for quite some time now and absolutely love it. I have only been working on PC projects so far, so I never really paid much attention to it but I am now working on a mobile game that is fairly intensive so I have been doing and checking everything I possibly can to try and optimize performance when I came across something in my menu. When I use ControlMapper.Open() as well as the "done" button I get a pretty massive spike as seen below (the large spike is opening it, the smaller one is hitting the Done button). All said and done it was something like 1.7mb worth of GC and it looks like over 10,000 calls when opening it, is this normal?

    Thanks,
    -MH

     
  42. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Try one Xbox One and one X360. Ain't going to work consistently. This is a 10+ year running problem with Unity's input system which tries to match the XInput device to the HID device so it can use the HID name and some of the HID controls with some of the XInput controls. It works most of the time for 1 or 2 controller games, but not always and results in problems like triggers activating on the wrong controller, especially with 4 controller games. There are tons of threads about this. It's simply not possible to do what you want using XInput because Microsoft does not allow you to get this information from XInput, nor do they allow you to get the XInput device id from the HID side. Any implementation that tries to do this is guaranteed to fail. This is not a problem, bug, or limitation of Rewired. This is a design decision by Microsoft. This information is available through Windows.Gaming.Input available only on later versions of Windows 10, but not through XInput.
     
    Last edited: Sep 11, 2018
  43. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    The menu is being built, objects instantiated, elements themed, all kinds of stuff has to happen for it to open.

    That specific line you are pointing to in your image is not a function call by anything in my code. That's coming from Unity's UI system. 4418 calls to Font.CacheFontForText. I do not know when Unity's UI system calls this, but it undoubtedly has something to do with rendering text. All the other GC I see in that image is also caused by UnityEngine UI calls of various things like enabling text, images, etc. A lot of it is instantiation.
     
    Last edited: Sep 11, 2018
  44. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    Thanks for the info. I do have another question. I tried looking it up, but I am not exactly sure what to search for. I could not find anything Rewired specific when trying to search "Simulate Keypress" or "Send Key", etc. Instead of listening for an input, how can I send one out? I am using DoozyUI to send the ControlMapper.Open() and Doozy listens for the Escape key, which it counts as "Back" in navigation, so if I hit Escape it will go back, but if I hit the "Done" button in the control mapper, it will close it, but I have some more scripts and such that require me to go back. It would be ideal if I could send the Escape / Cancel input when I press the "Done" button in the control mapper so that I can go back to where I was in the navigation.

    How might I go about doing this?

    Thanks!
    -MH

    --- Edit, I just looked through some more of it's settings and code, it looks like it is set to listen for a virtual button of name "Cancel", so if there is a way by clicking done, I can send "Cancel" that would be ideal.
     
    Last edited: Sep 11, 2018
  45. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    You can't manually set values of Actions in any way except through the use of a Custom Controller. While you could do that, it might be overkill for this situation.

    Control Mapper exposes events such as ScreenOpenedEvent and ScreenClosedEvent. You can use the ScreenClosedEvent event to trigger something to happen after it is closed.
     
  46. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    That's the thing though, when it closes I need to trigger the action of "Cancel" as if Escape was being pressed. I might just go about it another way though. Does the action of remapping controls have to be done via the control mapper or could I make a custom lightweight control page using Doozys UIElements and buttons so that the interaction ends up being what it needs to be? For a mobile game, I don't need nearly the amount of things on that page.
     
  47. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Coding your own system is going to have the same issue. Sending the "Cancel" Action (if you are referring to the UI cancel event and not a Rewired Cancel Action) is a function of the StandaloneInputModule. The RewiredStandaloneInputModule lets this Action be triggered from the Rewired Players while the default Unity StandaloneInputModule uses their own input system. The result is the same. Anything watching for the Cancel UI action is going to receive it from the input module being used. The input module is entirely separate from Control Mapper.

    You can trigger your own Cancel event through the EventSystem. It will not pass through Rewired, but any scripts that consume the Cancel UI event will receive it.

    Control Mapper is absolutely not required. It's not even part of the default Rewired installation. It's listed as an Extra. It's nothing more than a convenience for users who don't want to code their own system.

    See this:
    http://guavaman.com/projects/rewired/docs/HowTos.html#controller-mapping-screen

    But as stated above, this is not a problem with Control Mapper and wouldn't be solved by you making your own screen. It's how the UI event system works.

    It would also not be difficult at all to make a CustomController to do this.
     
    Last edited: Sep 11, 2018
  48. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    I understand and appreciate the info. I will figure something out. Luckily it's not a huge deal, I just want to make sure it's all clean and as proper as it can be.
     
  49. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Here's all the code you'd need to set up a custom controller to handle this. You'd also need to make a Custom Controller in the Rewired Input Manager, create a single button, then create a Custom Controller map that maps Cancel to this button, assign that Custom Controller map to your Player, and then assign the Custom Controller you created to that Player and give it a tag that can identify it.

    Link ControlMapper's onScreenClosed event in the inspector to this OnControlMapperClosed event and it should give you the result you want.

    Code (csharp):
    1. using UnityEngine;
    2. using Rewired;
    3.  
    4. public class CustomControllerExample : MonoBehaviour {
    5.  
    6.     public int playerId;
    7.     public string customControllerTag;
    8.  
    9.     private CustomController cc;
    10.     private bool inputCancel;
    11.  
    12.     private void Awake() {
    13.         CustomController cc = ReInput.players.GetPlayer(playerId).controllers.GetControllerWithTag<CustomController>(customControllerTag);
    14.         if (cc == null) Debug.LogError("No custom controller found in player " + playerId + " with tag " + customControllerTag);
    15.         cc.SetButtonUpdateCallback(OnButtonUpdate);
    16.     }
    17.  
    18.     private void OnDestroy() {
    19.         if(cc != null) cc.SetButtonUpdateCallback(null);
    20.     }
    21.  
    22.     private bool OnButtonUpdate(int index) {
    23.         if (index == 0) {
    24.             bool value = inputCancel;
    25.             inputCancel = false;
    26.             return value;
    27.         }
    28.         return false;
    29.     }
    30.  
    31.     public void OnControlMapperClosed() {
    32.         inputCancel = true;
    33.     }
    34. }
    35.  
    You could also just set the button value in the Custom Controller directly in OnControlMapperClosed instead of using the update delegate, but you'd need to clear the value the next frame or it will stay true forever.
     
  50. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    This would also work:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Rewired;
    4.  
    5. public class CustomControllerExample : MonoBehaviour {
    6.  
    7.     public int playerId;
    8.     public string customControllerTag;
    9.  
    10.     private CustomController cc;
    11.  
    12.     private void Awake() {
    13.         CustomController cc = ReInput.players.GetPlayer(playerId).controllers.GetControllerWithTag<CustomController>(customControllerTag);
    14.         if (cc == null) Debug.LogError("No custom controller found in player " + playerId + " with tag " + customControllerTag);
    15.     }
    16.  
    17.     public void OnControlMapperClosed() {
    18.         if (cc == null) return;
    19.         cc.SetButtonValue(0, true);
    20.         StartCoroutine(ClearButtonValueDelayed());
    21.     }
    22.  
    23.     IEnumerator ClearButtonValueDelayed() {
    24.         yield return null;
    25.         if (cc != null) cc.SetButtonValue(0, false);
    26.     }
    27. }