Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Rewired - Advanced Input for Unity

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

  1. Undertaker-Infinity

    Undertaker-Infinity

    Joined:
    May 2, 2014
    Posts:
    112
    Hi again! Another question regarding the Touchpad: I haven't been able to get the deadzone to work, it behaves the same despite any changes I've tried.

    This is my setup:
    Touchpad has axis set to Axis elements in the custom controller, using both, in Vector from Center mode, with Direction value format. Activate on Swipe in and Stay active on Swipe out are enabled. Dead zone and Sensitivity Type are both set to radial, both axis are enabled, have sensitivity set to multiplier (1) and Apply Range Calibration disabled.

    This is what I tried:
    Changing Dead Zone for each axis in the Touchpad Advanced section (went up to 0.9 and saw no change)
    Changing Dead Zone for each axis in the Custom Controller (also went up to 0.9 and no saw no change), which has calibration enabled, min/max to -1/1 and Zero to 0.

    This is what I expected:
    A dead zone around the center of the touchpad, then towards the edge (radially) I expected the value to jump up to the value at that position, since I have Apply Range Calibration turned off.

    Am I doing something wrong? Touchpad is working beautifully otherwise, it just feels a bit off witout a deadzone.
    Thanks!
     
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    @danbg After fighting with this the entire day, I came up with an odd but effective solution. It is attached.

    What I made here was entirely possible with what Rewired comes with out of the box because you have control over the movable area of the PlayerMouse. Actually this was almost entirely a Unity UI and Unity multi-display issue. The only part that involves Rewired is setting the movable region of PlayerMouse which is effortless once you have the position information of the displays.

    It works like this:
    1. Find absolute positions of all displays by searching at all the edges and corners of the first display and then each display thereafter using Display.RelativeMouseAt.
    2. Set the PlayerMouse movement area to limit movement to the absolute rect of that display.
    3. Output a screen position transformed to be relative to the selected display so it can be used to move a Unity UI cursor.

    Setup:
    1. Add the component to the PlayerMouse component.
    2. Set the display index for that PlayerMouse in the inspector.
    3. Attach the On Screen Position Changed event to your cursor script.
    4. Your cursor script will have to transform the screen position to Canvas space as shown in the UIPointer.cs script in the examples, but this time, you will have to provide it with the Camera that is rendering that display instead of using Camera.main.

    Limitations:
    Your desire to have a master mouse that can traverse all the displays and interact with them is a problem. This cannot be done with PlayerMouse without setting the movable area to a value that is equivalent to the smallest rect that can contain all your displays together with the 0, 0 point being the lower-left corner of the primary display. If there are regions with no display in them, the mouse will still be allowed to move into those regions.

    ----

    This is not a general-purpose solution. This is a solution for your specific use case of wanting a PlayerMouse cursor to be fixed to a specific display and work with Unity UI. A general-purpose solution would make software cursors behave exactly like the Windows hardware cursor does and be able to limit the movable region to the shape of all connected screens just like Windows does.

    There are likely too many issues with trying to make some kind of general-purpose system with the limited tools Unity gives you to know what's happening with the displays. And there is always going to be user setup required because of the complex Canvas rendering options.

    Unity also has some very odd behaviors. When you move a display in Windows display options around to a different location while Unity is running, Unity does not update the location of that display. If you query Display.RelativeMouseAt with the mouse pointer over the moved display, you will get 0's for all values. But because they don't move the virtual representation of that display, the code I made to detect the displays continues to work. The hardware cursor does work as expected because Windows is in control of that, but the Unity representation of the desktop is incorrect making it impossible to create a software cursor that behaves exactly like the hardware cursor, able to cross displays, etc. in this scenario.
     

    Attached Files:

    Last edited: Apr 28, 2020
  3. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Vector from Center + Direction is going to always give you a normalized vector (direction).

    The Axis Calibration dead zone on the on the touch pad control does not do what you are expecting it to do. It is applied to the final X and Y axis values when fed into the Custom Controller's axes every frame. So with Vector from Center + Direction, you're getting a value with a magnitude that is always 1. Applying a dead zone of 0.9 to that will do nothing.

    I think you are wanting to apply a dead zone to make the Touch Control not return any value until your finger has moved a certain distance from the starting point? There is no setting on the Touch Pad that will do that. But I might also interpret what you're looking for as something more like a joystick. If that's the case, I suggest you use the Touch Joystick control instead. A Touch Pad set to Vector from Center + Direction is doing exactly what a joystick does except it doesn't have a any range of movement. Eliminate the range of movement by setting sensitivity very high on both axes.
     
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    So they did exactly what I did in my hack, except they did it by extending the EventSystem. All this is doing is setting the event system to EventSystem.current temporarily so it can run the update, then setting it back. This isn't going to handle multiple selections or anything by itself. All it does it allow you to put multiple EventSystems in the same scene and have them all update. You can easily do the same thing. Just take out a few lines of code that are unnecessary:

    Code (CSharp):
    1. namespace MyNamespace
    2. {
    3.     /// <summary>
    4.     /// A modified EventSystem class, which allows multiple players to have their own instances of a UI,
    5.     /// each with its own selection.
    6.     /// </summary>
    7.     public class MultiplayerEventSystem : EventSystem
    8.     {
    9.         protected override void Update()
    10.         {
    11.             var originalCurrent = current;
    12.             current = this; // in order to avoid reimplementing half of the EventSystem class, just temporarily assign this EventSystem to be the globally current one
    13.             try
    14.             {
    15.                 base.Update();
    16.             }
    17.             finally
    18.             {
    19.                 current = originalCurrent;
    20.             }
    21.         }
    22.     }
    23. }
    24.  
     
  5. danbg

    danbg

    Joined:
    May 1, 2017
    Posts:
    65
    Hello guavaman, I have good news and bad news (but maybe the bad news are due to something I did bad) It is working, but only with 2 displays, if I add a third one it's madness, probably due to the PlayerMouse problem. This is what I did in the main Scene to handle all cursors (I'm trying at first with every cursor in the same main scene using overlay canvas for each display)
    1. Add to a new empty GameObject your first MultipleEventSystem
    2. Add for each cursor a new empty GameObject with an EventSystem and a RewiredStandaloneInputModule. Inside each GameObject a new GameObject with a PlayerMouse (with UseHardwarePointerPosition and DefaultToCenter = true) and a PlayerMouseMultiDisplayHelper (CenterCursor = true).
    3. Add a "root" Canvas for each display. Add a UIPointer_Player prefab to each Canvas.
    4. Link on each RewiredStandaloneInputModule the PlayerMice var with only its own PlayerMouse within.
    5. On every PlayerMouseMultiDisplayHelper change the DisplayIndex and add to its OnScreenPositionChanged event the UIPointer.OnScreenPositionChanged of the UIPointer_player prefab inside the Canvas for that display.
    As I said, with 2 displays it's working, but not with 3+ displays. I don't know if it has something to do with my displays' setup. Rright now I just have 4 connected on a row to make these tests (physically [1,0,2,3], WindowsIDs [3,4,1,2]), my main one being 0. Maybe I just have to sort them like [0,1,2,3] or it has something to do with your 4th step:
    Because I didn't change any cameras (not sure where or how to do it) It feels so close... any tips?

    Regarding the master mouse problem, I solved it just adding another EventSystem to MultipleEventSystems, and using a regular StandaloneInputModule, without Rewired PlayerMouse or RewiredStandaloneInputModule. It works, the only weird thing is that if I leave a button selected with the mouse, it will be activated if I activate the LeftMouse action with some Rewired PlayerMouse cursors... Not ideal, but I guess I can live with that after all these difficulties.
     
    Last edited: Apr 28, 2020
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Did you attempt to do any debugging to figure out why? I cannot test with 3 displays because I only have 2. It's entirely possible it's not finding the 3rd screen due to an oversight or bug in the searching code.

    If you're using the UIPointer that came with Rewired as an example, it's not going to work. That has Camera.main hard-coded into it and uses that camera to transform the display-space input to viewport space, then to Canvas space.

    Please don't take this the wrong way, but do you have limited experience with programming? I get the impression throughout this conversation that you're trying to solve these problems entirely through changing options in inspectors and editors and adding/removing components. It seems as if you're not understanding or are at least unsure of my code examples I sent and not trying to dig into underlying problems that are happening by using standard programmer practice like debugging and tracing down to find the exact cause of the problems. This is very important information for me to know. If I knew this, I wouldn't be giving you general directions that assume you know much about code like telling you to change your pointer drawing code to use the current Camera for the display to transform the screen space pixel coordinates.

    The UIPointer example that comes with Rewired was never intended to be dropped in and used in a game. It's in the Rewired.Demos namespace for reason. It's there to show you a basic example of how you might move a Unity UI pointer around using PlayerMouse.

    Replace the UIPointer.cs file with the one attached. Edit: I changed the way the calculation works and now it does not require you to assign the Camera. This is working with Screen Space Overlay. I'm not certain it works in other modes.

    What is happening is not what you think is happening.

    You are using the StandaloneInputModule, therefore you are using Unity's input system for the Submit event. If you look at Unity's Input Manager, you will see Submit is set by default to "joystick button 0" as one of the bindings. You are simply getting a submit event through Unity's input system that is triggering on the currently selected object for that Event System.

    1. Remove the StandaloneInputModule and use a RewiredStandaloneInputModule.
    2. Remove all Players from being able to control the UI in the inspector.
    3. Set Use System Player.
    4. Assign the mouse to the System Player by default in the Rewired Input Manager -> Players -> System page.
    5. Do not add a Player Mouse. Just use the hardware mouse.
     

    Attached Files:

    Last edited: Apr 28, 2020
  7. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    You should not have Use Hardware Pointer Position set to true on any Player Mouse. That makes it follow the actual mouse pointer if the Mouse is assigned to that Player. You want the hardware mouse to only be used by the master, so none of the Player Mice should be set to use this.
     
    Last edited: Apr 28, 2020
  8. fairchild670

    fairchild670

    Joined:
    Dec 3, 2012
    Posts:
    69
    Hello there! I have a question regarding the InputMapper - we'd like to allow a player to instantly swap two face buttons on a controller (i.e. Xbox One Contoller) without any prompts.

    I've got most of it working with the conflictData replace event - we just allow the conflict to pass. However after looking at the documentation and this thread, I can't seem to figure out how to complete the other side of the swap. Is there an example or other documentation that might hint at this functionality?

    Example:

    Jump is assigned to Y
    Punch is assigned to B

    Player remaps Jump to B and Punch to Y at the same time.

    Much appreciated!
     
  9. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    There is no documentation on this specialized functionality.

    Change properties on the Action Element Maps:
    https://guavaman.com/projects/rewired/docs/api-reference/html/T_Rewired_ActionElementMap.htm

    Action Element Maps contain all the information about a binding. Controller Maps contain a list of Action Element Maps.

    Documentation on the complex topic of control remapping is only in API documentation of functions and complete code examples:
    Control Mapper (Includes a swap feature)
    Simple Control Remapping
    Control Remapping 1

    Other relevant docs:
    https://guavaman.com/projects/rewired/docs/ControllerMaps.html#how-input-is-processed
    https://guavaman.com/projects/rewired/docs/api-reference/html/T_Rewired_ControllerMap.htm
    https://guavaman.com/projects/rewired/docs/api-reference/html/T_Rewired_ControllerMapWithAxes.htm

    You know what Action Element Map you are replacing, so you have both the original Action Element Map and the new proposed bindings.
     
    Last edited: Apr 29, 2020
    fairchild670 likes this.
  10. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    315
  11. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
  12. danbg

    danbg

    Joined:
    May 1, 2017
    Posts:
    65
    It's in fact finding all the screens, but the dimensions are totally mixed beyond 2 displays. I have to inspect it more closely to get why it's happening. There are also Kinects and TUIO here, using their own Input Modules, I have to make sure everything could be combined togeteher.

    Don't worry. I can tell you that I know what I'm doing... moreless :D (the system uses C#, JavaScript, Python, Autohotkey and Node. It combines messages from 2 different servers and even Arduinos, TTS and voice recognition with its own grammar) By no means I'm so experienced as you with Rewired or Unity's UI and Input System. I tell you exactly what I do without hacking the code, because none of us really know if there are unknow limitations in Unity's Input System (they themselves don't know it very well)

    For example, the only way I could make 40 touch points to work simultaneously was using TUIO. Just some months ago multidisplay UI with different resolutions was impossible to do without creating my own multiplayer system, and even then, Unity's multidisplay support was a total mess... Of course I could try to modify everything, but I'm sure other users could benefit from this if I try to stay as close as possible to the standard, that's why I try to use the simplest and ready to use code or prefabs available. For example, there are solutions for the discrepancies in the PlayerMouse coordinates using Autohotkey, but hey, I try to follow KISS principle, specially in something like this, that combines so many different inputs and outputs. It's hard enough to keep non supported TUIO to receive object IDs without fiducials.

    I didn't know that. The first test gave me the same results, but I have to check it more closely.

    I did that and it's still behaving like I told you (maybe I'm doing something wrong). As I told you, I will look at this more closely, but first I have to solve the 3 or more displays not working.

    Thanks for your patience and support :)
     
  13. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    315
    guavaman likes this.
  14. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Is it possible Unity is reporting incorrect values for Display.RenderingWidth and Display.RenderingHeight for some of your screens? Those are used in PlayerMouseMultiDisplayHelper.FindDisplayAt to get the resolution of the display. This resolution is used to set the PlayerMouse Movement Area in pixels. This would need to be logged for each of your screens to know if it's giving you the right values. The other important piece of data is the pixel coordinate of the lower-left corner of the display. This is obtained by using Display.RelativeMouseAt in that same function. If this is returning an incorrect value for any screen, the whole house of cards will come crashing down. You'll have to debug this and watch the data you're getting back for every screen to make sure the x, y, width, and height look correct for each display it finds.

    Good. Then it won't be a problem to debug and dig in and find the root cause of the issue.

    I just set up a test of that exact scenario with 2 Player Mouse cursors and 1 master hardware cursor and it works without the issue you described, so there has to be something wrong in the setup.

    Here is what I have:
    2 Players
    3 Mutliplayer Event Systems + Rewired Standalone Input Module
    2 PlayerMouse GameObjects

    Rewired Standalone Input Module 1: (For Player 1)
    Disabled "Use All Rewired Game Players"
    Disabled "Use Rewired System Player"
    Rewired Player Ids: Player0
    PlayerMice: PlayerMouse_P0

    Rewired Standalone Input Module 2: (For Player 2)
    Disabled "Use All Rewired Game Players"
    Disabled "Use Rewired System Player"
    Rewired Player Ids: Player1
    PlayerMice: PlayerMouse_P1

    Rewired Standalone Input Module 3: (For System Player)
    Disabled "Use All Rewired Game Players"
    Enabled "Use Rewired System Player"
    Rewired Player Ids: None
    PlayerMice: None

    PlayerMouse (both Players):
    Disabled "Use Hardware Pointer Position"
    Mouse X Action = MouseH
    Mouse Y Action = MouseV
    Mouse Left Click Action = MouseLeftClick

    Players in Rewired Input Manager:

    Player 1 and Player 2 both have a Joystick Map for the Gamepad Template that maps:
    Left Stick X = MouseH
    Left Stick Y = MouseV
    Action Bottom Row 1 = MouseLeftClick
    Note that none of the UI actions are mapped here (UIHorizontal, UISubmit) as that would not work with Player Mouse and cause many issues.

    System:
    Enabled "Assign Mouse on Start"
    Note that the System Player does not have any Controller Maps at all.

    Player0:
    Disabled "Assign Mouse on Start"
    Added Joystick Map (default, default)

    Player1:
    Disabled "Assign Mouse on Start"
    Added Joystick Map (default, default)

    Any extra Unity Standalone Input Modules in the scene would cause the issue you're describing.

    I have uploaded my setup scene as a UnityPackage here. Made in Unity 2019.3.10f1.
     

    Attached Files:

    Last edited: Apr 29, 2020
  15. danbg

    danbg

    Joined:
    May 1, 2017
    Posts:
    65
    Hi guavaman, I have good news. It was working the whole time... an asset concerning TUIO in my test project was creating all this havoc :O It was creating an unexpected EventSystem on runtime nested in a very nasty and obscure way... I obliterated it and everything is working great with 4 displays. Even better, with just some mods in the code TUIO is working too (only on the first display, but hey, I can live with that). Your Scene helped me to make sure I was doing the same, so I started checking everywhere else... There are some minor issues and small errors regarding TUIO and your MultiEvent code, but I think I can handle it and it's beyond Rewired scope. Thanks a lot :) I have another question regarding another issue, so I will post it in a new message.
     
  16. danbg

    danbg

    Joined:
    May 1, 2017
    Posts:
    65
    Custom controller cursor for UI using screen coords

    I've reading the documentation about custom controllers and checking the demos, but I wonder what is the best way to create a custom controller for moving a cursor and using the UI when, instead of controller axes, you have the cursor coords in screen.

    I'm using a Kinect to get a cursor, and it's working nice with the UI using its own input module, but I would like to use RewiredStandaloneInputModule and PlayerMouse (because I want to use the MultipleEventSystems) Maybe the best way is to modify directly the KinectInputModule code or play with raycasting, but it would be great if there is a way to convert easily any kind of cursors to Rewired to have a unified UI system (for example: lightguns, Wiimotes, OpenCV cursors)

    I know it's not the most efficient way to do it, but there is a lot of crazy controllers out there, and a simple way to adapt them to Rewired would help a lot to improve support.

    Thanks again.
     
  17. fairchild670

    fairchild670

    Joined:
    Dec 3, 2012
    Posts:
    69
    Hi Guavaman, Thanks for the info! I'm very close I think. I've got this code to create the new ActionElementMap:

    Code (CSharp):
    1.  
    2. Debug.Log(Time.time + " <color=green>QuickMenuRemapControls</color>: found the button that is getting its button removed "
    3.     + button.GetButtonNameText() + " assigning elementIdentifierId " + lastElementIdentifierId + " to it...");
    4.  
    5. ActionElementMap aem = null;
    6.  
    7. if (map.CreateElementMap(new ElementAssignment(lastElementIdentifierId, button.Handler.RewiredAction, false), out aem))
    8. {
    9.     Debug.Log(Time.time + " QuickMenuRemapControls: successfully created an action element map elementIdentifierId " + aem.elementIdentifierId
    10.     + ", " + aem.elementIdentifierName + ", " + aem.actionId + ", " + aem.actionDescriptiveName);
    11.  
    12.     button.InitializeElementIdentifierIds(map);
    13. }
    14.  
    And I'm noticing in the RewiredInputManager Debug Information (as well as the debug lines printed out) that the new ActionElementMap always has an elementIdentifierId of 0. Even if I hard code a known elementIdentifierId. Is there another step I may be missing?

    Here's the debug for the above code:

    Code (CSharp):
    1. 3.171278 QuickMenuRemapControls: found the button that is getting its button removed Active Suit Module assigning elementIdentifierId 6 to it...
    2. 3.171278 QuickMenuRemapControls: successfully created an action element map elementIdentifierId 0, None, 4, Active Suit Module
     
  18. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Custom Controllers can populated with absolute screen coordinates if you so choose. Values are only clamped if you choose to enable Calibrate when creating the axis in the Custom Controller.

    Player Mouse was designed to take absolute -1 to +1 values from Player axes and convert them into a screen position and expose a movement delta. That's really all it does. You do not have to use Player Mouse to achieve this. Player Mouse is simply a convenience added for the most common use case of wanting to move a cursor with keyboard or gamepads. Everything Player Mouse does could be re-implemented on your own by consuming axis values from the Player.

    Player Mouse was not designed to take an absolute screen position. You can do that if you want by setting the screen position through the property. Or you can implement your own mouse class and use it in the Rewired Standalone Input Module by implementing Rewired.UI.IMouseInputSource and adding the mouse to the Rewired Standalone Input Module through RewiredPointerInputModule.AddMouseInputSource.

    In short, there isn't any pre-built system that's going to do what you want to do. Write a script to get the data out from the Player that you want and either feed it into a Player Mouse or write your own replacement for Player Mouse that does what you want it to.
     
  19. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    You are not providing the correct information in the Element Assignment. That ElementAssignment constructor you are using says this in the documentation:

    "A struct for use in element assignment. Overload for assignment of a full axis."

    https://guavaman.com/projects/rewir.../html/M_Rewired_ElementAssignment__ctor_8.htm

    If you are not creating an Axis binding, that overload is not going to work because it sets ElementAssignment.type to ElementAssignmentType.FullAxis, which is used to determine what type of Action Element Map to create.

    There are many overloads of that function that take various information required for all the different binding types. If you do not know the type of assignment you are making, choose an overload that provides all the information for a complete binding like this:

    Code (csharp):
    1. // Copied from Control Mapper source code
    2. controllerMap.ReplaceOrCreateElementMap(
    3.   ElementAssignment.CompleteAssignment(
    4.       mapping.controllerType,
    5.       swapElementType,
    6.       swapElementIdentifierId,
    7.       swapAxisRange,
    8.       swapKeyCode,
    9.       swapModifierKeyFlags,
    10.       swapActionId,
    11.       swapAxisContribution,
    12.       swapInvert
    13.   )
    14. );
    If you know you are making a Button assignment, use the overloads for buttons:

    https://guavaman.com/projects/rewir.../html/M_Rewired_ElementAssignment__ctor_6.htm
    https://guavaman.com/projects/rewir...ewired_ElementAssignment_ButtonAssignment.htm

    The static functions are easier to use than the constructor overloads because they're named according to their function. The constructors should probably have been private and not exposed.
     
  20. danbg

    danbg

    Joined:
    May 1, 2017
    Posts:
    65
    Hi guavaman, thanks! Just to be clear, I should create a custom controller to get my custom cursor position, then pass that controller to a Player and create a custom PlayerMouse to use the UI with it (or create a script to convert Player's custom controller data to PlayerMouse), is that right?
     
  21. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Yes. That is the standard way of working with input in Rewired. Player gets input from controller, consumer consumes from Player. The only difference here is your mouse is the consumer and that mouse is then used by the RewiredStandaloneInputModule as a pointer.

    The least-effort way is to write a script to send the unmodified values of the X and Y screen space coordinates from the Player to PlayerMouse.screenPosition. You will have to account for the fact that these coordinates must be in absolute space, so your script that feeds the PlayerMouse must have all the logic to determine the screen positions/dimensions like the script I wrote you. There's no way to avoid this because Unity UI will only work on multiple screens if the absolute position the PointerInputModule receives is in absolute space. You will also have to set the Player Mouse movement area so it doesn't clamp you into the wrong display.
     
  22. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Just to be clear, 99% of this entire issue was outside Rewired's scope and didn't fall into the category of providing support for Rewired. This was all basically a bunch of issues with understanding how Unity UI works and working around those issue, many of which I was not even aware of as I have never attempted much regarding multi-display with Unity UI or mutli-EventSystem.
    • Unity UI (Event System) was written to allow for only one Event System to run at a time. This is a limitation with what Unity UI provides. Rewired never provided an alternate Event System that worked with multiple running simultaneously.
    • Unity UI is what requires an absolute mouse position for the cursor to be detected by the PointerInputModule and raycasting and required me to come up with that convoluted system to detect the display information for each screen.
    • Unity UI is also what required the absolute screen position to be transformed into local screen space before being transformed to Canvas space in order for the UI sprite to appear
    Moving sprite cursors around in Unity UI that aren't attached to the hardware cursor on multiple displays without Rewired involved in any of this would have required exactly the same work (in addition to modifying the PointerInputModule to read from a variable instead of Input.mousePosition.)

    The only part of this issue that was in Rewired's scope was setting the PlayerMouse.movementArea to clamp the PlayerMouse to the chosen display.
     
    Last edited: Apr 30, 2020
  23. danbg

    danbg

    Joined:
    May 1, 2017
    Posts:
    65
    Hi guavaman, thanks :)
     
  24. shotoutgames

    shotoutgames

    Joined:
    Dec 29, 2013
    Posts:
    290
    I can't figure out how to use touchstick and touchpad at same time. They work fine until I build and run in android.. I use the joystick to move and touchpad area to aim.
     
  25. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Look at the example that comes with Rewired that does exactly that.

    https://guavaman.com/projects/rewired/docs/Examples.html#touch-controls-1

    Touch controls are completely platform agnostic. If your UI RectTransform / Canvas that is containing these controls is scaling in some way that causes them to overlap, the're not going to work.
     
  26. IceBeamGames

    IceBeamGames

    Joined:
    Feb 9, 2014
    Posts:
    170
    Hey @guavaman

    Thanks for the last advice, its working well.

    One thing, I am getting null from player.controllers.maps.GetFirstElementMapWithAction(controller, actionId, false);

    The player has the action map, but the controller hasn't been assigned to them yet, as I am using the manual controller assignment discussed previously. Is that why its coming back as null? Is there a way of getting a ActionElementMap back from a player without having the controller assigned to them yet? Or is there a better way of handling it?
     
  27. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    https://guavaman.com/projects/rewired/docs/ControllerMaps.html#joystick-maps

    When a controller (excluding mouse and keyboard) is attached to the system, Rewired will attempt to identify that controller and load a hardware definition. When the Joystick is assigned to a Player, it will load Joystick Maps into the Player if you have created any Joystick Maps in the Rewired Input Manager that are compatible with that controller. (You can see the the current list of recognized controllers with extended support here.)

    ---

    If it were not to work like you're describing, your Player would contains hundreds of Joystick Maps for all joysticks that are recognized by the system.

    No.

    If you want to preview a Controller Map that does not yet exist, you have to get a new instance of that Controller Map from the Rewired Input Manager.

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

    Check whether they have any joysticks assigned first and add a null check when you get the Action element map.

    https://guavaman.com/projects/rewired/docs/HowTos.html#get-controller
     
    Last edited: May 1, 2020
  28. shotoutgames

    shotoutgames

    Joined:
    Dec 29, 2013
    Posts:
    290
    Thanks,
    The sample confirmed I was doing it correctly. It's just me. I didn't set to mobile on menu game manager so when run from menu mobile touch ignored. Duh .. next question below
     
  29. shotoutgames

    shotoutgames

    Joined:
    Dec 29, 2013
    Posts:
    290
    Thanks so much as always,
    Vector form center confusion now.
    It says vector from center of screen but when I look at the raw pixel value the Y starts at the top of the touchpad and goes from -1 to -y size. the x is from the center as I would expect. Is this the intended behavior? I was trying to use the touch pad (Small rectangle) center (without coordinate adjustments) as the start shot point and the if upper half player shoots in front and lower half behind, continuing in all directions from center.
     
  30. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Vector From Center does not say it is a vector from the center of the screen.

    https://guavaman.com/projects/rewired/docs/TouchControls.html#touch-pad

    "Vector From Center - Returns a vector from the center of the Touch Pad to the current touch position."

    After testing it again, it's broken. Ugh! The center of the vector is being affected by the pivot of the RectTransform. Unity UI's RectTransform layout system is FAR too complicated with little in the way of coordinate transformation functions. It's extremely difficult calculate anything in a RectTransform with all the pivots, anchor points, and Canvas scaling, Canvas rendering modes, etc. going on with it. You can never be sure what you are trying to do is actually going to work in every scenario.

    Change your pivot to the center. If you can't, nest the touch pad inside another RectTransform and set the inner-most's pivots to 0.5, 0.5.
     
    Last edited: May 1, 2020
  31. shotoutgames

    shotoutgames

    Joined:
    Dec 29, 2013
    Posts:
    290
    Yes I didn't word it correctly but thanks for taking a look. I will give it a try. Double yes on unity UI. It's a mess. I try not to use raw sizes and just position everything relative to scale better but seems to make it worse. . I could have sworn that yesterday I had a UI setup where it worked correctly too so who knows..
     
  32. shotoutgames

    shotoutgames

    Joined:
    Dec 29, 2013
    Posts:
    290
    Changed Y pivot from 1 to .5 and voila!
    Kind of makes sense actually
    Thanks
     
  33. ObsidianSpire

    ObsidianSpire

    Joined:
    Sep 13, 2013
    Posts:
    48
    Is there a way to access the mapped axis or button for an action? Trying to make a tutorial that displays dynamically the user's selection for each input field in case they change it from the default, but I'm not seeing anything in the API that corresponds. Maybe I'm missing it.
     
  34. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    The entire mapping API is exposed. You have access to literally everything about mappings.

    https://guavaman.com/projects/rewired/docs/HowTos.html#get-element-name-for-action
    https://guavaman.com/projects/rewired/docs/HowTos.html#display-glyph-for-action
    https://guavaman.com/projects/rewired/docs/HowTos.html#display-glyph-for-active-elements

    https://guavaman.com/projects/rewired/docs/api-reference/html/T_Rewired_ControllerMap.htm
    https://guavaman.com/projects/rewired/docs/api-reference/html/T_Rewired_ActionElementMap.htm
     
    ObsidianSpire likes this.
  35. MM47

    MM47

    Joined:
    Sep 7, 2012
    Posts:
    25
    Hello!
    Is there a way to disable Rewired on a headless/batchmode build?
    Apparently I am getting this error on my dedicated server in linux and I suspect it is Rewired. So best to just disable it.

    Plugins: Couldn't open libudev, error: libudev: cannot open shared object file: No such file or directory
     
  36. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Rewired is a MonoBehaviour. You can disable it just like any other MonoBehaviour Unity. Do not enable or instantiate the Rewired Input Manager GameObject in the first place.
     
    MM47 likes this.
  37. IceBeamGames

    IceBeamGames

    Joined:
    Feb 9, 2014
    Posts:
    170
    Hello again Guavaman.

    So, I am also getting null back from GetFirstElementMapWithAction using the system player with the controller (which is reporting as connected) and also a map that is assigned to the system player. Also reinput is saying it is ready.

    Any idea what I am doing wrong?
     
  38. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    GetFirstElementMapWithAction returns only Action Element Maps that match the criteria you give it. If it's returning null, there is no Action Element Map that matches those criteria. There is no other possible way it would ever return null.

    Your System Player does not contain the Action Element Map you are searching for based on your search criteria used in GetFirstElementMapWithAction. Use Debug Information to see exactly what Controller Maps and Action Element Maps exist in System Player at runtime. Search parameters you use must match exactly to an Action Element Map that currently exists in the Player.
     
  39. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    Rewired 1.1.34.0 is available on the Unity Asset Store.

    See Updating Rewired before updating.

    Release Notes:

    1.1.34.0:

    Changes:
    - Added support for horizontal mouse wheel.
    - Windows Standalone, Native Mouse Handling: Added remote desktop mouse support.
    - Added RewiredEventSystem component.
    - Rewired Standalone Input Module: Changed axis movement threshold to use Input Behavior Button Dead Zone.
    - Changed method for finding canvas position from screen position in UIPointer.cs example.

    API Changes:
    - Added MouseInputElement.Axis4 value.
    - Added PlayerMouse.clampToMovementArea property.
    - Added PlayerMouse.Definition.clampToMovementArea property.
    - Added Rewired.Components.PlayerMouse.clampToMovementArea property.

    Integration Chagnes:
    - PlayMaker: Added "By Axis Contribution" selection criteria option to RewiredPlayerGetFirstElementMapIdWithAction action.

    Bug Fixes:
    - Eliminated calls to EditorPrefs every frame when using Debug Information in Rewired Input Manager inspector in the editor causing heavy CPU usage.
    - Rewired Editor controller map bindings list no longer displays positive/negative Action names if a positive/negative name was set in the Action as an Axis-type Action then changed to a Button-type Action without clearing these values.
    - Fixed PlayerMouse inspector display of certain values not updating when changing them by scripting.
    - Touch Controls: Fixed bug in Touch Pad when Touch Pad Mode is set to Vector from Center causing vector to be calculated from the pivot point of the Rect Transform instead of the center.
    - Player Mouse no longer applies Absolute To Relative Sensitivity to axis values is axis Coordinate Mode is set to Absolute and Action value supplied to the axis is in absolute coordinates.
    - Player Mouse no longer adds Absolute axis values to the screen position but passes the value through unmodified.
     
    shotoutgames and Bartolomeus755 like this.
  40. shotoutgames

    shotoutgames

    Joined:
    Dec 29, 2013
    Posts:
    290
    Just wondering if anyone tested rewired in 2020.1 beta?
     
  41. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    shotoutgames likes this.
  42. shotoutgames

    shotoutgames

    Joined:
    Dec 29, 2013
    Posts:
    290
  43. AlejMC

    AlejMC

    Joined:
    Oct 15, 2013
    Posts:
    149
    Small suggestion, it would be nice if all the touch controls, components, etc from the Rewired library would have it's own entry on the 'Add Component' menu of a game object... sometimes I type 'Rewired' I don't think anything is named like that.

    Great library by the way
     
  44. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    All MonoBehaviour-based classes do appear when you start typing. The class name is what you have to type. These class names do not begin with the term Rewired, so nothing will show up when you type that. Rewired uses namespaces to designate that the classes belong to Rewired. It does not use the convention of prefixing every class with the word Rewired like some libraries do that don't use namespaces. Controller is Controller, not RewiredController, etc.
     
  45. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Hello, I hit a little problem, I unchecked "assign mouse" and "assign keyboard" from all players (except system obviously) and when I do this:

    Code (CSharp):
    1. void Update() {
    2.     foreach (Player player in ReInput.players.GetPlayers(true)) {
    3.     if (player.GetAnyButton()) Debug.Log(player.descriptiveName);
    4. }
    I still get input response on the mouse and keyboard for player 0, any idea what could be the wrong?

    I'm trying to get a response only from the system user for all controllers.
     
    Last edited: May 7, 2020
  46. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    https://guavaman.com/projects/rewired/docs/UserDataStore.html#saved-xml-not-synced

    You are probably using UserDataStore_PlayerPrefs and it saves controller assignments by default.

    If not, then you are doing one of the following:
    1. Assigning the Keyboard and Mouse to Player 0 in a script.
    2. You are testing with a different Rewired Input Manager than you are editing. For example, you've changed the checkboxes in a prefab instance but not the prefab master and are testing with the prefab master in your scene, therefore using the old data.
     
  47. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    I will go confirm all that, thank you!
     
  48. Gooren

    Gooren

    Joined:
    Nov 20, 2015
    Posts:
    332
    Hi, we did the mistake of using the New Unity Input system for our new project.
    The problem is - the system no longer supports processing input in BOTH fixed and dynamic updates. (see 0.9.0-preview changelog entry here with rationale).
    We need this feature though. For mouse delta based smooth rotation of a rigidbody with joint attached non-kinematic rigidbodies in both Update (for rendering) and FixedUpdate (so that the physics ends up perfectly aligned/synced with the rendering).
    This issue is most noticeable when you move the mouse at a ~ constant speed. Player camera is rotating beautifully, but the joint rigidbodies are not. They seem to "jitter" a bit.

    Would this still be an issue in Rewired as well?

    Cheers!
     
  49. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,637
    If you enable Fixed Update in the settings, it will update input in both Update and Fixed Update. You cannot, however, call a function to make input update at an arbitrary time like in the middle of an update or on another thread.

    I suggest you try the trial and see if it does what you want it to with regard to mouse input smoothness:
    http://guavaman.com/rewired/trial

    I don't think it will result in any difference vs Unity's new input system because of how all of this works.

    Windows uses Raw Input for mouse input, but those values are delivered by Windows at the beginning of the cycle (before Update or Fixed Update ever run). This means no new mouse values are ever delivered to Rewired during a cycle (while potentially multiple Fixed Updates are executing). Even if it could deliver events mid-frame, this wouldn't help because of how Fixed Update works, executing bursts of updates as fast as the CPU will allow at the beginning of the cycle before Update runs, making polling for new input in each successive Fixed Update pointless because of how fast they execute.

    Rewired applies the mouse delta value only to the first Fixed Update frame and then it becomes zero for remaining Fixed Update frames that process during the cycle, so it would result in the same jitter you are describing. If you knew how many Fixed Update frames were going to execute during a cycle, you could conceivably divide the input values up by that number and deliver them evenly across the frames (what Unity calls timeslicing) which would result in smoother movement in fixed update, but as far as I know you cannot query how many Fixed Update frames will execute during a cycle, so Rewired can't do it.
     
    Last edited: May 10, 2020
    Gooren likes this.
  50. Why485

    Why485

    Joined:
    Jun 30, 2013
    Posts:
    45
    Is it possible to make the Control Mapper UI appear as a child of another Canvas?

    My settings menu uses pages which load different items onto a canvas. I've tried putting the ControlMapper object as a child of the Controls page, but I never see anything come up. There is a brief pause indicating that it's loading something, but I don't see it anywhere, even if I start hiding images that the Control Mapper UI might be under due to sorting issues.



    It seems like even in the most basic configuration possible it does not appear.



    1. Create new Canvas
    2. Set the ControlMapper object as a child of the new Canvas
    3. Hit play
    4. ControlMapper does not appear.

    When not parented to anything, this same ControlMapper works correctly.