Search Unity

  1. All Pro and Enterprise subscribers: find helpful & inspiring creative, tech, and business know-how in the new Unity Success Hub. Sign in to stay up to date.
    Dismiss Notice
  2. Dismiss Notice

Rewired - Advanced Input for Unity

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

  1. SaxOps1

    SaxOps1

    Joined:
    Mar 8, 2016
    Posts:
    3
    Hey, maybe this is my own lack of understand around the package manager, but if I install this into a project, then push to git, then pull/open it on another machine, should I have to redownload the package to make it work?
     
  2. Flazone

    Flazone

    Joined:
    Jan 25, 2015
    Posts:
    3
    Hi @guavaman ,

    Did Rewired supports the Enter Play Mode Options? Especially the no domain reload feature. Thanks!

    upload_2021-5-19_0-12-19.png
     
  3. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    No. I have done no testing on this and have made no changes to the DLL or scripts to support it. I was not even aware this experimental feature made it into base Unity.
     
    Flazone likes this.
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    Rewired isn't managed by the Package Manager. Unity moved all asset store asset management into the Package Manager, but the functionality did not change a single bit from when they were managed by the Asset Store window in Unity. Rewired is an asset store product, and is nothing more than a .unitypackage file that is extracted into the Project folder. It is not managed like true Package Manager packages that are installed in a separate directory outside the Project folder.

    If Rewired's folder in the project is copied to a new project, it will still not work because the Unity InputManager.asset which was modified by Rewired when the installation script ran was not copied. This will cause exceptions when you enter Play mode because Unity Input Manager entries that Rewired uses for certain data are missing. Run the installation script again or copy the InputManager.asset to the new project.
     
  5. SaxOps1

    SaxOps1

    Joined:
    Mar 8, 2016
    Posts:
    3
    Ok, that makes more sense now. It is the same project, but in GitHub- I guess I'll just have to get all my team members (this is a student project) to install the .unitypackage
     
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    I'm not sure you understand. A Unitypackage is nothing more than an archive like a zip. It extracts its files into the Project folder and that's it. It does nothing after the files are extracted. It is not needed or even referenced after that. The files are what's important. Copying the files to another project will work. But you have to also update the InputManager.asset by running the installer (from the menu) or copy that from the other project.
     
  7. afrayedknot

    afrayedknot

    Joined:
    May 14, 2021
    Posts:
    1
    Hi. Great package, you've done some amazing things, really glad I bought this.

    I'm just trying to clarify the current documentation about the settings on the Input Manager for "Update Loop": https://guavaman.com/projects/rewired/docs/RewiredEditor.html

    The documentation says: "Each loop is updated and tracked independently so all input calls will work in either loop"

    But then it says two lines down: "Updates input in the FixedUpdate loop. If you try to get input from the Update loop, you will miss some input data."

    So I'm a bit confused. Are the loops tracked independently or are they combined?

    So for the scenario where I select `FixedUpdate()` as one of the inputs; if the players presses the 'up' button as a quick press, and there are two calls to 'Update()' before the next 'FixedUpdate()', will the 'up' press be visible in the 'FixedUpdate()' loop, or was it only visible to the first 'Update()' that occurred and now its missing because it is only registered for one frame?
     
    Last edited: May 19, 2021
  8. lanihou

    lanihou

    Joined:
    Jul 9, 2015
    Posts:
    4
    hi, is there a way to configure a touch pad to work like a ( 4 directions joystick + touch region) ?
    basically I want the user to freely swipe on the touch pad and get the direction of the swipe constrained to 4 as in an arcade joystick .

    thank
     
    Last edited: May 19, 2021
  9. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    "Each loop is updated and tracked independently" is the important phrase. Controller and Action values are calculated and tracked independently for each loop.

    Unity is a frame-based system. Every "frame" is a loop of the callback like Update, Fixed Update, or On GUI.

    Frame events like GetButtonDown (this button is on for this frame only) cannot work unless it is tracked and calculated for the specific loop in which you are trying to consume it.

    "Updates input in the FixedUpdate loop. If you try to get input from the Update loop, you will miss some input data."

    If you were able to disable the Update loop and enable only FixedUpdate this would be true. It's not possible to disable Update due to the fact Unity UI requires it. I can see I'm going to have to change the wording.

    The primary use of these settings is to enable input tracking in Fixed Update. If you are trying to get input in FixedUpdate and you have not enabled Rewired to track input in that loop, this sequence of events will happen:
    If multiple FixedUpdates run in a particular cycle and input is not being tracked specifically for FixedUpdate:

    1. Input is sampled and frame events are calculated in Update.
    2. The next cycle, FixedUpdate executes (because it runs before Update) and reads the stale data from the last Update loop. If a ButtonDown event was True on the last Update Frame, it is also true on this Fixed Update frame.
    3. If a second FixedUpdate frame executes sequentially in this cycle, it will also use the exact same stale data and you will get 2 ButtonDown events reported, one in each frame.

    All of this also affects the accumulation of delta input like mouse axes, so this affects more than just button events.
     
    afrayedknot likes this.
  10. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    You're going to have to be much more specific. I don't know whether you're talking about on-screen Touch Controls, the Dual Shock 4 / Dual Sense touch pad, Apple remote touchpad, or something else.

    On-Screen Touch Controls:
    Use a Joystick control, not a Touchpad control for that purpose. You can make it look like whatever you want.

    DualShock 4 / Dual Sense:
    No. Rewired does not handle anything related to the touchpad except to expose the values to you in the Controller Extension for you to use as you wish.

    Apple remote:
    Rewired does not provide any wrappers for the native API. Unity does. Apple exposes a boolean that changes the remote from swipe mode to joystick mode.
     
    lanihou likes this.
  11. SaxOps1

    SaxOps1

    Joined:
    Mar 8, 2016
    Posts:
    3
    Yeah, I understand the archive part, and I thought that all I'd need to do was extract it once, upload into the git repo for our project, and then everyone could just use it? It would appear the Rewired menu option doesn't exist for other people, and gives errors until they install the package themselves? Maybe I've just set this up incorrectly somehow?
     
  12. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    Yes it would. The menu option is created by the Rewired_Editor.dll. If the DLL is in the project, the menu item should be there. If it's not, then something is wrong with the repo or Unity is refusing to import the DLL. All the .meta files must be retained. If the Rewired files are in the project, it should work. Apart from having to copy the Unity InputManager.asset or running the installer again, there are no other steps.
     
  13. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    After getting a mouse capable of 8000 Hz polling, I am able to reproduce the problem. I am seeing massive lag with the profiler showing > 100ms per frame when rapidly moving the mouse. I initially tested Rewired and found no evidence of it being involved in the slowdown. A telling sign being the the Rewired InputManager_Base entry in the profiler showed no increase in CPU time when the slowdown occurred. Then I tried testing Unity alone without Rewired even running or in the scene and was able to reproduce the slowdown exactly. Even a fresh project in the latest version of Unity with nothing in it exhibits the same slowdown. So this doesn't have anything to do with Rewired at all.
     
    Last edited: May 20, 2021
  14. Toficor

    Toficor

    Joined:
    May 6, 2015
    Posts:
    27
    Hello,
    I was assigned to project to make input mapping and input glyphs displaying. I wasn't before in this project and I noticed that there are many maps that are unnecessary and also enabled. There is no chance to clean up it because we don't have enough time. My problem is: when I change controller from keyboard to joystick (Xbox Controller), method GetFirstButtonMapWithAction() returns null, but when I change controller from mouse to controller works in most cases correctly. What should I do? Is there way to load maps befor controller changed? Method responsible for inptu glyphs is subscribed to AddLastActiveControllerChangedDelegate.
     
  15. richard-firehose

    richard-firehose

    Joined:
    May 31, 2019
    Posts:
    1
    Hey Guavaman,

    I'm curious if there is a way to use the Rewired Constants to edit Map Enablers. From what I can tell from the docs, it seems that the only way to retrieve Rule Sets is via their tags using List.Find(). The Rule Sets don't seem to expose their integer ids, so I cant do something like:

    ruleSets.Find(item => item.id == RewiredConsts.MapEnablerRuleSet.Movement)

    There seems to be a way to get copies of the Default Map Enabler's Rule Sets via integer id using ReInput.mapping.GetControllerMapEnablerRuleSetInstance(), but no way to retrieve ones for specific Players such that I could enable/disable the Rule Set and apply it to that Player. If possible I would like to avoid hard coding in the tags, so I wanted to ask if there was a way to retrieve Rule Sets using the integer ids.

    Thanks!

    Richard
     
  16. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    That's not possible.

    The Controller Maps are always loaded as long as the Controller is connected and assigned to the Player. Changing what the active controller is by picking up a controller and using it has absolutely no effect on the Controller Maps. That is, unless you have some code in your scripts that is doing something to disable Controller Maps. You are going to have to debug exactly what is going on with your Controller Maps to understand what is happening. This is definitely not something Rewired itself is doing.

    Controller Maps do not change because the Last Active Controller changed.
     
  17. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    No you can't. That is intentional.

    ReInput.mapping is an interface to the data saved in the Rewired Input Manager (think of it as a database or a bunch of prefabs). This is a read-only database at runtime It provides the pre-defined set of base data from which to create runtime data. Nothing of the live game exists in this database, and you cannot change anything inside it at runtime. It is developer-defined default data.

    Everything that exists live at runtime is first instantiated from the pre-defined data when Rewired initializes just like a prefab in Unity. For example, Players. If you want to change something in a Player, you access that live Player object and change it. You do not change the Player's definition (prefab parent) in the Rewired Input Manager to change data in a Player. In the same way, you change the Rules and Rule Sets for the Layout Manager or the Map Enabler in the live Player you're interested in at runtime, you don't change it in the database.

    player.controllers.maps.mapEnabler.ruleSets

    That contains the list of all the rule sets for that Player.

    Accessing the live Map Enabler rule sets in a live Player is explained in the documentation:
    https://guavaman.com/projects/rewired/docs/MapEnabler.html

    The list of Rule Sets you assign to the Player in the Rewired Input Manager is nothing more than a list of initial rules to be instantiated and added to the Player when Rewired initializes. After Play mode starts, that data is irrelevant and can't be modified. The only thing that is relevant at runtime is the list of Rule Sets in the live Player at player.controllers.maps.mapEnabler.ruleSets.

    Rule Sets and Rules only have an id that represents the "prefab id" in the database and it can only be used to retrieve an instance of that Rule or Rule Set from the database. They do not retain this id once instantiated. Rule and Rule Set instances can be modified at runtime, duplicated as many times as you want and modified, or even be created entirely at runtime through code without using the editor. Because of this, they don't have any link back to their parent data (if they even have any parent data at all, which they don't if created from a script) and cannot be accessed by using a constant.
     
    Last edited: May 20, 2021
    richard-firehose likes this.
  18. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    999
    Hi @guavaman , does Rewired support the new InputSystem... want to try it for adding SteeringWheel support for a game that relies on it ?
     
  19. okaybenji

    okaybenji

    Joined:
    Mar 10, 2017
    Posts:
    3
    Is it possible to disable mouse wheel acceleration? I have a menu where you're choosing between two or three options. In this instance, scroll acceleration doesn't really make sense. However much you scroll, it should be easy to predict where the selection will land. Thanks!
     
  20. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    No.

    https://guavaman.com/projects/rewired/docs/KnownIssues.html#not-compatible-unity-new-input-system

    There are many reasons for this, one of which is the fact that it's impossible for Rewired and Unity to both consume Raw Input events at the same time on Windows. Windows allows one single subscription to events. If Rewired subscribes, Unity loses them and vice versa.

    Unity's old input system did not use Raw Input for controllers. The new one does.
     
    Last edited: May 22, 2021
  21. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    Rewired does not control or set any mouse wheel acceleration. You're probably talking about Unity UI. If you are, that is not a function of the input module. That is entirely controlled by the Selectable that receives the input events (slider, scroll area, button, etc.) The inspector gives you options for speed, inertia, navigation, etc. That is completely outside of and unrelated to Rewired.
     
  22. little_box

    little_box

    Joined:
    Aug 22, 2017
    Posts:
    19
    Hi, guavaman
    When I switched platform from iOS to Mac, console show "PDEBUG Skipping device because it is ignored by Steam.". And the gamepad device is no longer available. What's going on? How can I solve it?
     
  23. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    What version of Rewired and version of Unity is this? PDEBUG messages should never be visible in builds. PDEBUG is only for my use internally and no release should ever have this flag enabled. I have checked all the OSX projects and none of them have PDEBUG enabled. The warning should not be logged in public releases, but the result is the same -- the controller is hidden from the application.

    You can't fix it. It exists because Steam must hide HID devices from the system so it can manage what the system sees. Rewired checks the Steam environment variable that lists the Steam-managed devices and skips all of them that are Steam-managed. Steam then exposes another device to the system which is its virtual device that Steam can map and manage.

    Devices are managed by Steam because of your settings in Steam. Read this:
    https://guavaman.com/projects/rewired/docs/Troubleshooting.html#steam
     
  24. little_box

    little_box

    Joined:
    Aug 22, 2017
    Posts:
    19
    version is 1.1.38.4.U2020.
    I upgrade rewired after switching from Unity2019 to Unity 2020, and then it showed PDEBUG
     
  25. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    The current version is 1.1.39.2 and I can confirm it does not have the PDEBUG issue.

    This is even in the release notes now that I look:

    1.1.39.1:

    Bug Fixes:
    - Fixed IL2CPP compile errors and runtime exceptions on some platforms due to error in obfuscation introduced in 1.1.39.0.
    - Disabled debug logging in OSX builds in Unity 2020 and 2021 branches introduced in 1.1.39.0.
     
  26. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    41
    Hey @guavaman !
    I purchased Rewired back in Nov of 2020 and it works beautifully. I've had no complaints or any reason to ask for support so far!

    But I'm trying to do something that I'm sure has been done before at least in part and I'm hoping to not have to go through 145 pages to find the answer. Could you point me in the right direction?

    What I want to do is simulate a controller. This would be used by AI to 'play' a character when not controlled by a player. In my current project I already have a working version of this setup outside of rewired. If AI is turned on, rewired is bypassed and the AI sets the button/axis states directly on a simple monobehavior which are used instead to control the character. If AI is off, then the button/axis states are retrieved directly from Rewired.

    But I'd like to make use of the other embedded features of Rewired, such as being able to apply InputBehaviors to them, or use the analytics that Rewired is already doing like seeing how long a button has been held. I don't want to recreate this logic when it's already done (and certainly better tested).

    I know I need a CustomController, and I've started the implementation, but I have some big questions on whether or not this can even work:

    1) I estimate at least 20+ characters active at any one time. Most of them will be AI controlled all the time. But I'm designing them to be playable as well. What I don't want, though, is to have to set up 20 players in rewired just to satisfy this. The project is only 1 player (to start), they just have the option to take control of AI driven characters one at a time.

    With that being said, will a CustomController work for this scenario? I'm talking about having a CustomController instantiated for each of those 20 characters, yet there's only 1 REAL player. The idea is for each of those AI characters to still be using the same input system, albeit virtual. Hypothetically this would provide a seamless transition if the player took control of one in the middle of some complicated movement. To Rewired, there'd be no difference to which is controlling it.

    2) Is there a way to set Axis/Button values in a CustomController outside of using an Id or Index? Can I not use the button/axis name I gave it to set the value just like what's used to retrieve the input values?
    My apologies if this one is a bit basic. This maybe something that's solved via using custom controller layouts and maps?

    It maybe helpful to think of my project more like a zoo simulator. Some characters will have a large number of emotes/action, even more than can fit on a normal joystick. I want the AI to be able to do all of those emotes/actions even if when the AI is turned off and a player takes over the player can't do ALL of them themselves because there aren't enough buttons. That's where the joystick/customcontroller mapping will need to take place I'm assuming.

    I know this was long and I appreciate you reading this! I hope I articulated what I'm going for. I'm trying to figure out the system that would be flexible enough to handle any number of characters using a CustomController but only 1 real player. I will also need to update the CustomController actions/buttons dynamically based on the character it's applied to. Making a custom controller or a player for each character just isn't feasible to do manually.

    Thanks!
    Will
     
  27. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    You cannot create Players at runtime. You cannot use Rewired's Player-Action system with anything but the Players you create in the Rewired Input Manager. The entire system is based on those Players. Controller assignment, Controller Maps, Actions, Input Behaviors, and anything else. How you choose to use those Players is totally up to you. Rewired has no concept of "real" or "fake." They're just containers for controllers and controller maps. If you want to expose only one to the user, that's up to you.

    https://guavaman.com/projects/rewired/docs/HowTos.html#excluding-players-from-joystick-assignment

    Export constants:
    https://guavaman.com/projects/rewired/docs/HowTos.html#exporting-constants

    Why?

    You create a list of 20 Players.
    You create one or more Custom Controller definitions depending on how many different controller types you need.
    You create the Controller Maps for those controllers and assign them to the Players.
    You instantiate and assign the Custom Controllers to Players at runtime as needed.
    Depending on your needs, Layout Manager and Map Enabler can be used to switch controller maps.

    You probably only really need one Custom Controller definition with a bunch of elements and different Controller Maps for the different purposes. But you could do with multiple Custom Controller types with different elements if you want. The system is designed to be used however you want it, so there is no right way to use it. A Custom Controller is nothing more than a custom interface for pushing input into the system from an external source.
     
    Last edited: May 25, 2021
  28. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    41
    Fair enough. I understand the design decision for Players being the core of the functionality.

    And I'm betting I only need one Custom Controller as long as it's flexible enough with the buttons. Or worse case I create a Custom Controller base class and extend it for the various controller types I need.

    But being locked to adding Players manually in the Rewired Input Manager just makes no sense for my situation. My project is more of a content creation tool than a game with fixed players. I've spent as much time on editor tools as game code to streamline this process. (I have an import manager that will read Aseprite files directly, their layers, tags, etc. It creates the textures, sprites, animation clips based on the tags, animator, and the SO containing all the metadata as well as the character prefab itself. So I'm no stranger to editor tools)

    1) Create new scene using tilemaps / props
    2) DragNDrop characters in the scene to populate how I want.

    There will be many scenes with any number of characters in each of them. I don't want to manually create players for each of these, but if I'm understanding you I can do this:

    1) Create 100 (or 1000) empty players in the Rewired Input Manager. While most may never be used, the important thing is to have more than enough players to satisfy the need for any scene.
    2) Activate/Deactivate those players dynamically at runtime? You say I can't add players at runtime but I assume I can disable/enable them based on current character count. I mean yes sure they can always be active and may not 'hurt' anything but just for sanity and organization it'd be nice to have only the ones in use enabled. Or not and I keep track of that outside of Rewired that's fine too.
    3) This is the basic mechanism I can use to instantiate characters dynamically? I was hoping to be able to instantiate some characters at runtime, so I suppose I just need to have enough players in the system to handle the maximum number?
    4) Even the process of creating 100-1000 players in edit mode would be tedious and I'd write an editor script for it. I assume there are editor callable API functions that can be called that execute the same functionality as what the Input Manager is doing? Such as adding players or even custom controllers.

    The idea is to start with simple characters and build upon them, meaning I could very well have many more custom controllers in the future. I already have editor tools to manage these characters and their actions, it wouldn't be beyond my scope to create a 'prep' editor window that's sole purpose is to 'gather' the needed controllers/players for the current scene character count and create them in Rewired in edit mode using those API calls. Eventually this could even be automated to happen before entering play mode.

    Thanks for this! I'd probably create an editor tool to streamline this as well. I'm hoping the functionality for this can be called as well externally. Or worse case I make the functions public.

    Look I know this is a weird edge case and I appreciate your time helping me to understand. I'm trying to leverage the the 8+ years you've pumped into making this robust system. To me this makes sense and could provide extra tools with which to build more intelligent and realistic AI if that AI could also make use of the button press times and input behaviors. Consider some moderately complex movements like combo moves from fighter games. You already have a system in place that tracks button presses. Why would I recreate that functionality outside of Rewired if I don't have to?

    Or maybe it's a dumb idea that I should scrap. I don't know. I am just hoping to get some guidance to make that decision.

    I appreciate your patience! Thanks again!
    Will
     
  29. BigGreenPillow

    BigGreenPillow

    Joined:
    Dec 2, 2013
    Posts:
    23
    Hi, we are trying to use the right glyphs for the controller being used by the player and everything seems to be working alright but for some reason we noticed that if someone is using the DS4Windows emulator with a PS4 controller the game keep alternating between recognizing the controller as a PS4 controller and thinking this is an Xbox controller.

    I'm not sure if this is something that can be fixed or not and probably a side effect of the emulator trying to replicate an Xbox controller at the same time that the game is trying to get the input from the PS4 controller, it works fine without the emulator, but though it best to ask just in case there is something we might be doing wrong here.

    Thanks!
     
  30. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    This is an important distinction. Rewired is not the right tool for creating game builders. This comes up periodically. Other users have wanted to be able to create Actions, Controller Maps, and everything else at runtime so their users could design the input for their custom game, but Rewired is not designed for this purpose.

    Based on the rest of this post, I don't think Rewired is suitable for what you want to do.

    Yes.

    I would definitely recommend against creating 1000 Players. Every Player will have some amount of code executed every frame, and it will waste resources having so many Players.

    Controller Maps in any Player that is not being used should be disabled to reduce CPU usage.

    And handling input for 1000 units by piping input into Custom Controllers is going to have a much bigger overhead than if you were to control them directly from a script as you are currently doing.

    You don't activate or deactivate Players in Rewired. They're always active. Your scripts should be what flow control whether you should consume input from a Player or not or what Player to get that input from. There's an isPlaying property on the Player class for your own use, but it has no impact on anything as far as Rewired's internal code is concerned.

    No, there isn't. Rewired's editor API is internal and undocumented.

    Rewired is designed for games where the developer defines the input for their game in the Rewired Editor. It isn't suitable to power content creation systems, except in the case where you are just using the Controller layer and not the Player-Action system. The Player-Action system is intended to be defined by the developer at edit time in the Unity editor, while the end user can customize their bindings at runtime and save/load them to/from XML/JSON.
     
    Last edited: May 26, 2021
  31. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    There's nothing that can be done about 3rd party tools that change what the various OS input APIs report. The controller is showing up as both an XInput device and a HID device. Both are valid devices as far as Rewired is concerned because both are being exposed by the system.

    Best Practices mentions these issues and gives advice:

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

    Controller Assignment:
    • Always provide some means for your users to change controller assignments. It is especially important if you are making a multi-player game. You cannot know what devices, physical or virtual, will be present on a user's system, appear as Joysticks to Rewired, and be assigned to a Player. Device emulation software (VJoy, DS4Win, SCPToolkit, etc.) and certain device drivers can and frequently do cause problems by creating extra, non-functional virtual devices. Allowing the user to make their own controller assignments solves this issue as well as making it possible for users to swap controllers, etc. You can either include Control Mapper directly in your game or create your own system.
     
  32. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    41
    Alright man, I get it. This isn't what it was designed for.

    With most assets I've purchased, though, I had access to the source code. I guess we don't with Rewired. I get why it isn't, though. I sure as hell wouldn't want to after supporting all the controllers and platforms you do.

    Yes, I'm sure the overhead would be ridiculous with 1000 players as you described it. But if I could've extracted or even just learned from the timing code you use in just the button timings alone, it would've saved me time in my own implementation. Or more importantly, if I wanted the AI to behave in a similar manner even if I had to recreate the logic outside of Rewired I could mirror the code used for players in a very stripped-down way.

    Thanks for the feedback, though. I do appreciate it.
    Will
     
  33. idibil

    idibil

    Joined:
    Oct 10, 2015
    Posts:
    17
    Hi Guavaman,

    Backing to this. When the player is not using Joystick, he is using keyboard + Mouse. Accord the controller type, in an example, we can get the key for SPRINT, using:

    Code (CSharp):
    1.  tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, "Forward", skipDisabledMaps).elementIdentifierName;
    What if the player changes it to the Mouse Left button? He is using this button to Sprint instead of the Keyboard Button, but the code will continue calling to ControllerType.Keyboard.

    As keyboard and Mouse works together, is there a way for the code to recognize the keys regardless of whether one or the other is the last controller?
     
  34. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    You can't use GetLastActiveController and have that give you information about multiple controllers. There is only one LastActiveController and Keyboard and Mouse are not a single combined controller.

    You could always check for both mappings when the controller type returned by last active controller is either keyboard or mouse. But what if the user has the Action mapped on both the keyboard and the mouse? If you display help based upon the last active controller type directly but the Action is mapped on both keyboard and mouse, as the user is presses keys and moves the mouse, the last active controller will switch back and forth between keyboard and mouse causing your UI help to flicker between the two bindings. You will need to prioritize one over the other in this case. How you choose to prioritize them is up to you. Does Keyboard outweigh Mouse or vice versa?
     
    Last edited: May 26, 2021
  35. idibil

    idibil

    Joined:
    Oct 10, 2015
    Posts:
    17

    It doesn't really matter whether the player uses the mouse or keyboard, I can create a case for both. And if he uses one of them, I know he is using keyboard + mouse (since they work together) instead of Joystick.

    The problem is that when assigning the key to show in the tutorial message, the code is calling only the Keyboard, but there could really be a key in both, as you say, or only in the mouse (which will report an error).

    I do not know if I'm explaining myself well. With the Joystick we use the same type, therefore it always calls joystick keys, but in the case of the Keyboard and the mouse, when working with two types and the player being able to change keys to their liking between both there is conflict.

    My original idea was, as in your code (https://guavaman.com/projects/rewired/docs/HowTos.html#get-element-name-for-action), leaves the type in black, so the system will call the first key available, but then the first keys are from Joystick instead of Keyboard+Mouse :) Maybe I can change the order in some way and the first keys can be called fro Keyboard+Mouse, we can use the code here this way for them:

    Code (CSharp):
    1. tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction("Forward", skipDisabledMaps).elementIdentifierName;
    Is this possible or is there a better solution? The idea is to show these keys on a tutorial message popup.

    Thank you in advance.
     
  36. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    I said above "You could always check for both mappings when the controller type returned by last active controller is either keyboard or mouse." This is nothing more than an if statement to check the controller type and get the first binding for either keyboard or mouse.

    Code (csharp):
    1. Controller controller = Rewiredplayer.controllers.GetLastActiveController();
    2. string actionName = "Forward";
    3. if (controller != null) {
    4.     if(controller.type == ControllerType.Keyboard || controller.type == ControllerType.Mouse) {
    5.         tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, actionName, skipDisabledMaps).elementIdentifierName;
    6.         if(tempKey == null) tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Mouse, actionName, skipDisabledMaps).elementIdentifierName;
    7.     } else {
    8.         tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(controller, actionName, skipDisabledMaps).elementIdentifierName;
    9.     }
    10. }
    This prioritizes keyboard over mouse if the binding exists for both.
     
    Last edited: May 27, 2021
  37. idibil

    idibil

    Joined:
    Oct 10, 2015
    Posts:
    17

    Yes, sorry, I thought it can have a third way. Thank you. I updated my code:

    Code (CSharp):
    1.             if (controller != null)
    2.             {
    3.                 switch (controller.type)
    4.                 {
    5.                     case ControllerType.Joystick:
    6.                         tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "Savegame", skipDisabledMaps).elementIdentifierName;
    7.                         tempKey2 = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "Loadgame", skipDisabledMaps).elementIdentifierName;
    8.                         break;
    9.                     case ControllerType.Keyboard:
    10.                     case ControllerType.Mouse:
    11.                         tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, "Savegame", skipDisabledMaps).elementIdentifierName;
    12.                         if (tempKey == null) tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Mouse, "Savegame", skipDisabledMaps).elementIdentifierName;
    13.                         tempKey2 = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, "Loadgame", skipDisabledMaps).elementIdentifierName;
    14.                         if (tempKey2 == null) tempKey2 = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Mouse, "Loadgame", skipDisabledMaps).elementIdentifierName;
    15.                         break;
    16.                     default:
    17.                         tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction("Savegame", skipDisabledMaps).elementIdentifierName;
    18.                         tempKey2 = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction("Loadgame", skipDisabledMaps).elementIdentifierName;
    19.                         break;
    20.                 }
    21.             }
    22.  
    What elementIdentifierName back? I am getting this error on Unity that stop the code:
    NullReferenceException: Object reference not set to an instance of an object

    when
    Code (CSharp):
    1. tempKey2 = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Mouse, "Loadgame", skipDisabledMaps).elementIdentifierName;:
    If "load game" key for Mouse does not exist for example.
     
  38. Jihaysse

    Jihaysse

    Joined:
    Mar 29, 2020
    Posts:
    44
    Hello,

    I'm having issues that sometimes the input keeps being processed (e.g. the player keeps walking for 5-10 secs after I stopped pressing the Z key).

    Code (CSharp):
    1. public void HandleUpdate()
    2.     {
    3.         GetInput();
    4.         ProcessInput();
    5.     }
    6.  
    7.     void GetInput()
    8.     {
    9.         moveVector.x = player.GetAxis("Horizontal");
    10.         moveVector.y = player.GetAxis("Vertical");
    11.     }
    12.  
    13.     void ProcessInput()
    14.     {
    15.         float vertical = moveVector.y;
    16.         float horizontal = moveVector.x;
    17.  
    18.         float speed = baseSpeed * Mathf.Abs(vertical);
    19.         if (vertical > 0.2f)
    20.         {
    21.             animator.SetBool("WalkBackwards", false);
    22.             animator.SetFloat("Speed", speed);
    23.             animator.SetBool("IsMoving", true);
    24.         }
    25.         else if (vertical < -0.2f)
    26.         {
    27.             animator.SetBool("WalkBackwards", true);
    28.             animator.SetFloat("Speed", speed / 2);
    29.             animator.SetBool("IsMoving", true);
    30.  
    31.         }
    32.         else
    33.         {
    34.             animator.SetFloat("Speed", 0);
    35.             animator.SetBool("IsMoving", false);
    36.             animator.SetBool("WalkBackwards", false);
    37.         }
    38.  
    39.         Vector3 move = new Vector3(0, 0, vertical * Time.deltaTime);
    40.         Vector3 rotation = new Vector3(0, horizontal * Time.deltaTime * rotationSpeed, 0);
    41.  
    42.  
    43.         move = transform.TransformDirection(move);
    44.         if (vertical > 0.2f || vertical < -0.2f)
    45.            characterController.Move(move * speed);
    46.  
    47.         velocity.y += gravity * Time.deltaTime;
    48.         characterController.Move(velocity * Time.deltaTime);
    49.  
    50.         transform.Rotate(rotation);
    51.  
    52.  
    53.     }
    HandleUpdate() is being called in Update() in my GameManager instance.


    Thank you for your time!
     
  39. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    You are not checking whether or not the result is null before you attempt to use the binding. GetFirstElementMapWithAction is returning null because there is no mapping for that Action in the Player for the Mouse, so you are trying to get the .elementIdentifierName property from a null object.
     
  40. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    Use Debug Information to watch the Horizontal and Vertical values live or log the value of moveVector. Rewired only provides the input value. What you do with that value is up to you. If moveVector isn't showing you a value that lasts longer than the key you're pressing, then the problem is in your input consumption logic. If moveVector is showing a value that retains a value longer than you are pressing, it could only be one of two possibilities.

    1. Input Behavior settings:
    https://guavaman.com/projects/rewired/docs/Troubleshooting.html#digital-axis-smoothing

    2. A Unity editor bug causing Raw Input to fail that is not fixable and seems to come and go depending on the Unity version:
    https://guavaman.com/projects/rewir...#windows-editor-keyboard-keys-stuck-raw-input
     
  41. idibil

    idibil

    Joined:
    Oct 10, 2015
    Posts:
    17
    You are right. Thank you!
    Well, I post a usable code here, maybe it can be interesting for somebody in order to show a tutorial msg

    Code (CSharp):
    1.     private string tempKey = "";
    2.  
    3.     public int RewiredPlayerId = 0; // The Rewired player id of this character
    4.     private Rewired.Player Rewiredplayer; // The Rewired Player
    5.     private bool skipDisabledMaps = true;
    6.     private Controller controller = null;
    7.  
    8.     private string completeText = "";
    9.  
    10.     void Awake() // Rewired
    11.     {
    12.         Rewiredplayer = ReInput.players.GetPlayer(RewiredPlayerId);
    13.         // If set to true, only enabled maps will be returned
    14.         skipDisabledMaps = true;
    15.     }
    16.  
    17.     void OnTriggerEnter(Collider other)
    18.     {
    19.         //  InputComponent = GetComponent<InputControl>();
    20.         if (other.gameObject.tag == "Player")
    21.         {
    22.             tempKey = "";
    23.             CallTutorialMsg();
    24.         }
    25.     }
    26.  
    27.     public void CallTutorialMsg()
    28.     {
    29.         controller = Rewiredplayer.controllers.GetLastActiveController();
    30.  
    31.             if (controller != null)
    32.             {
    33.                 switch (controller.type)
    34.                 {
    35.                     case ControllerType.Joystick:
    36.                         if (Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "INVENTORY", skipDisabledMaps) != null)
    37.                             tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "INVENTORY", skipDisabledMaps).elementIdentifierName;
    38.                         break;
    39.                     case ControllerType.Keyboard:
    40.                     case ControllerType.Mouse:
    41.                         if (Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, "INVENTORY", skipDisabledMaps) != null)
    42.                             tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, "INVENTORY", skipDisabledMaps).elementIdentifierName;
    43.                         if (Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Mouse, "INVENTORY", skipDisabledMaps) != null && string.IsNullOrEmpty(tempKey) == true)
    44.                             tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction(ControllerType.Mouse, "INVENTORY", skipDisabledMaps).elementIdentifierName;
    45.                         break;
    46.                     default:
    47.                         tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction("INVENTORY", skipDisabledMaps).elementIdentifierName;
    48.                         break;
    49.                 }
    50.             }
    51.             else
    52.             {
    53.                 tempKey = Rewiredplayer.controllers.maps.GetFirstElementMapWithAction("INVENTORY", skipDisabledMaps).elementIdentifierName;
    54.             }
    55.             completeText = "Your Text Here" +
    56.                 "[<color=#8BCB16>" + tempKey.ToString() + "</color>]";
    57.             completeText = completeText.ToUpper();
    58.             //move your text to UI here
    59. }
     
  42. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    497
  43. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,305
    is there an official way to detect dragging regardless of the peripheral in Rewired?

    is there a way to detect an actual click, so the action to hold and release in a specific amount of time?

    I am experimenting with
    GetButtonShortPressDown and
    GetButtonTimedPressDown but I would like the click to not be detected if too much time is passed, still pondering if it makes sense

    edit: found it


    if (player.GetButtonTimedPressUp(RewiredConsts.Action.Secondary_Action, 0.05f, 0.1f))
     
    Last edited: Jun 2, 2021
  44. phdhamster

    phdhamster

    Joined:
    Jun 16, 2020
    Posts:
    4
    Hello, I have a quick question. I went back and added button-conflict swapping to my rebinding screen over the weekend using parts of ControlMapper as a model, and it seems to work great. However in my UI settings I have some redundant controls (same action bound to multiple keys) which cause some unintended behavior when swapped. I'd like to disable swapping for these redundant elements. Is there a way I can count how many times an action has been bound to a different button/key within a given layout?
     
  45. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    Every single thing in the Controller Map is exposed. Search the bindings for whatever information you want and take action.

    The Player exposes the Controller Maps it contains:
    https://guavaman.com/projects/rewir...Rewired_Player_ControllerHelper_MapHelper.htm

    A controller map contains lists of button mappings and axis mappings. Iterate the lists or use one of the search convenience functions to find the information you want. There is no count-redundant-action-bindings convenience function.

    https://guavaman.com/projects/rewired/docs/api-reference/html/T_Rewired_ControllerMap.htm

    https://guavaman.com/projects/rewired/docs/HowTos.html#managing-controller-maps-runtime
     
  46. phdhamster

    phdhamster

    Joined:
    Jun 16, 2020
    Posts:
    4
    Thanks, that's all the information I needed. I was able to get this using your example code as a jumping off point.

    Code (CSharp):
    1. int bind_count=0;
    2.             foreach(var actionElementMap in controllerMap.AllMaps)
    3.             { // iterate over all maps regardless of type
    4.         InputAction action = ReInput.mapping.GetAction(actionElementMap.actionId); // get the Action from the binding
    5.                 if (action.id==swapActionId)
    6.                 {
    7.                     bind_count++;
    8.                 }
    9.             }
    Then later on I swap or don't swap depending on the value of bind_count.
     
  47. ninuxw

    ninuxw

    Joined:
    Jul 8, 2014
    Posts:
    23
    How would you recommend implementing this once I already have my game setup with rewired? FYI after ages of getting bugs related to this I find the clue here :) (mainly cause there are many ways for the player of my game to do the same action related to the issue, so it appeared randomly when it was related to certain users play style)!
     
  48. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    The comments I was making in that post were describing why the problem happens at the Windows/keyboard level, but not a solution to make any play style just work, just work around the particular issue that user was having at the time. Making something that universally just works is not going to be possible as the behavior of how modifier keys affect the events sent by Windows isn't changeable. While I can choose to process certain events and not others under certain circumstances, I can't make it generate events it doesn't send. And deciding what to modify or not to attempt to work around the Windows limitations is really just a subjective judgement call. Some users may want it to work one way, and other users another, and others yet another. There are no options for you to change anything regarding this low-level, platform-specific key event handling in Rewired. You set up your input and the modifier key events behave how they behave. There are probably certain combinations of keys you just wouldn't want to use, but none of that has been documented by me since this is really a problem at the Windows VKey level and not the input system.

    It looks like my recommendation at the time for that particular issue was to tell your users to disable Num Lock.
     
  49. Kiragan

    Kiragan

    Joined:
    Jan 8, 2016
    Posts:
    19
    Hey,
    Im testing dualshock4 controller on iOS, but still no luck. Controller recognized, all logs are okay, but all the axis and buttons still not working. Even if i using clean project with only rewired installed. Demo scenes are not working too. What im missing?
     
  50. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    4,696
    Last time I tested, it worked on iOS 13+. Nothing has changed in Rewired. If the controller really no longer works, then something changed or broke in Unity. There is absolutely nothing DS4-specific you can or are supposed to do to make it work. It's just recognized as an MFI controller.

    You should verity the controller doesn't actually work. There are many, many other reasons a controller may not work.

    Go through the checklist:
    https://guavaman.com/projects/rewir...l#debug-information-diagnosing-input-problems
     
unityunity