Joystick Plugin

Hi.

I have created a little plugin to use joysticks with the unreal engine 4. The source is based on the hydra plugin.
The plugin is still untested but quite usable.
I’m still very new to Unreal Engine development, so please be clement, if the source code has architectural mistakes…

Any comment or suggestion is very welcome.

Resources:
Plugin download: GitHub

Sounds awesome! Personally, I’d like to see more joystick games.

Elite Dangerous is a good example!

, you spelled “Steering Wheel” wrong :stuck_out_tongue:

Hey Ikarus76 this is very awesome!

Just tested this plugin on my Saitek Evo Force and it worked out of the box! Because you used the hydra plugin as a basis, I felt straight at home and the component and event driven interface implementation makes me happy. Glad you could make use of the base code :slight_smile:

Feedback(This is my opinion):
-[Bug]Each event emits twice, I believe this is because you call the delegate event both from within FJoystickPlugin and in JoystickBlueprintDelegate. The hydra plugin was structured like this to support both C++ events and the interface events, but it did this by forwarding the C++ events to the interface events in BlueprintDelegate, whereas you check for changes and emit the interface events a second time.
-Add input mapping for the buttons and axis
-Maybe normalize joystick input to 0-1.0 (but this may be difficult since one joystick may emit a different range from another, mine was 0-65536 (2^16) for all axis and sliders, Pov -1 for neutral, 0-31500 for directions)
-In events I would recommend merging all the axis values into one event e.g. JoystickAxisMoved(FVector) instead of 3 separate events.
-My joystick has force feedback and I was wondering if there is a way to control or call vibration from within WinJoystick?

My test graphs:

where print functions are defined by

and

How do I use the joystick plugin? I enabled the plugin but I don’t see anything related to joysticks in Edit, Project Settings, Input window.

Made some updates in a fork and I’ve made a pull request to have those included in the main branch.

The updates include:
-Added input mapping support, drag and drop the actor or component and
use the input mapping system for quick joystick support
-Automatically normalizes values into a range of -1.0 to 1.0
-Events emit controller reference with each event allowing for
in-context additional value lookup
-POV changed event now emits a enum type, but can query the controller for
conversion into POV axis
-16 input mapping buttons are currently supported, can extend to more
buttons should the need arise
-Fixed duplicate event emit bug
-Trimmed blueprintdelegate, not needed in this plugin context

While the main branch updates you can get the fork build from here. Please test the update with any joysticks you all have as I’m unsure if I haven’t simply ‘fixed’ the range to my joystick or if the range is more or less the same for all joysticks.

Example of using the input mapping system to add joystick control to the flying template with a Saitek Evo Force


Edit:

You can use the fork if you want input mapping support now or wait for Ikarus to merge/implement his own version in the main branch. You can also use custom input mapping plugin to add input mapping to the plugin indirectly.

Hey man, grabbed your fork of the plugin, but still no joystick showing up in Input mapping. I put it in the /Plugins folder of the Engine, rebuilt it (4.5 source), and the enabled the plugin in-editor. Any ideas?

Thanks!

Hi getnamo!
Nice to have you on board. Thank you for your awesome contribution. As I told, I have no experience with the unreal engine plugin architecture and i feel, it lacks documentation. Your hydra source was very well structured and I needed to adapt just small parts of the code. I hope I have not destroyed too much :)!

How did you get your knowledge about the plugin architecture?

This plugin was meant to add support for the X52 Pro System, so I need at least 32 Buttons. I have also plans to add MFD-Support. But for now I will try to learn from your contribution to understand a little bit more the architecture of the ue4 plugins.

Again, thank you very much for your effort, and I hope to hear from you sometimes!

Best regards,

Whoops! It seems due to how the architecture is set up you need to not only have a plugin actor dropped into the scene (or add a component to a blueprint) but you also have to have the joystick plugged in before you launch your project for the input mapping events to show up. Obviously this isn’t ideal, I’ll have a think and push a fix.

Thanks for the kind words, I think you did a great job merging the architecture with Direct Input, but maybe we need to rethink the architecture for joysticks a little bit. I agree the plugin architecture isn’t well documented, I imagine part of the reason is that epic themselves haven’t fully committed to how it’s currently set up. That said if you poke around enough you can decipher the way plugins currently work, which is what I did back a while ago. It’s a great way to learn how to extend blueprints and get a feel for how memory management is done (because you need cross that line by mixing your custom classes with the unreal uobjects which have garbage collection). Things that are missing from plugin support at the moment are automatic dll copying in packaging for launch and shipping modes (currently have to manually copy dlls to support shipping) and blueprint-only shipping support (right now you have to add dummy code to the project for the plugin to get included). Still haven’t heard anything from epic on either of these issues.

In terms of this plugin, I was thinking about it and I think most people simply want the input mapping, which is typically not enough by itself for more complicated controllers such as a the Leap, Hydra, or Myo. I wonder if it wouldn’t be better to have this as some sort of blueprint library that automatically enables the input mapping for the device and auto-ticks, that way people don’t have to add any extra steps to get straight into the binding. The event driven nature is actually completely covered by the input mapping events, so maybe our custom events are not needed. Will tinker around and see what I come up with. Extending the input mapping button support to 32 buttons should be fairly straight forward, if a little copy-paste tedium :), but if we want to support all 128 buttons we probably need to make a function jump list since switching for button functions would grow exponentially and a worst case scenario would be 128*128 (16384) operations to check all button events (vs current worst case of 256). We could get away with that though, because I highly doubt any human can push 128 buttons at the same time :p.

The fix was surprisingly simple.

Update to 0.2.1, pull request added. See fork to test the update.
-Input mapping keys and axis now always get exposed.
-Hot-plugging of the joystick is now supported.

For now I think this is a good solution, because to support hot plugging otherwise (e.g. automatically ticking plugin) would burden any project which has the plugin enabled with a ‘tick check’ whenever a joystick isn’t plugged in. This way the tick cost is only taken by projects which explicitly choose to add the plugin actor or component and otherwise incurs no runtime cost (the cost in either case is absolutely tiny though).

Thought I’d add basic setup instructions here:

Installation

  1. Download
  2. Create new or choose project.
  3. Browse to your project folder (typically found at Documents/Unreal Project/{Your Project Root})
  4. Copy Plugins folders into your Project root.
  5. Restart the Editor and open your project again. Plugin should be enabled.

Setup for Use

  1. Input mapping should be automatically enabled, so you can setup your input mapping binds. But you will not receive joystick input until you’ve added *either *a JoystickPluginActor to the scene, *or *a JoystickComponent to any of your blueprints
  2. Option A: JoystickPluginActor for simple input mapping support

2.1. Select Class Viewer

2.2. Find JoystickPluginActor and drag it into the scene. You can confirm it’s in the scene by looking at the Scene Outliner.

2.3. You’re done. Play around with input mapping!

  1. Option B: Joystick Component and JoystickInterface. If you want control over the joystick in blueprint directly for more fine-tuned control (scaling/mixing etc) as well as full button support (up to 128) past the 16 currently supported IM, this is the method to use.

3.1. add a Joystick Component to the relevant blueprint

3.2. add a Joystick Interface to the same blueprint

3.3. You’re done. Right click on the event graph and type ‘Joystick’ to narrow your events to Joystick related

3.4. You can poll by dragging from the component return node, both latest frame and all events emit a JoystickSingleController reference

I got my Logitech G27 Racing Wheel working in UE4. Go to Start/Devices and Printers, right-click on G27 Racing Wheel, Choose Properties and Settings, and enable “Combined Pedals”. After adding the “Joystick Component” and “Joystick Interface” to the blueprint for controlling the vehicle, go to Edit/Project Settings/Input, and assign the steering wheel to “Joystick Axis X” and the brake/throttle pedals to “Joystick Slider”. Set the scale for “Joystick Slider” to -1. I didn’t assign anything to the clutch pedal or H-shifter yet.

I couldn’t get the clutch pedal working. I got the H-shifter working. I don’t know which joystick axis is used by the clutch pedal.

Maybe a second slider is used… We should implement the 3 pov and 3 sliders available by directinput.

I suspected it was possible, but it’s awesome that this supports steering wheels as well.

I agree, I’ll leave the DirectInput part to you so have a look if you can extend it and maybe add the Input Mapping extension to 32 buttons.

Other possible extensions:
-MFD
-Vibration/Force feedback (I think it uses this part of direct input, but I haven’t found C++ examples of it), I’ll take a look at this next week when I get some time.

Hi,
I’ve just added Button support for 128 Buttons. Input mapping added until Button 32.
Also 2 additional POVs and 1 slider has been added. I’ve tested the buttons above 32, but I can’t test Slider2 and POV2&3 because lack of hardware…
Maybe someone can find some time to test with the wheel… :wink:

@ Force Feedback: I don’t have FF supporting hardware…
@ X52 MFD - This will be my next task

I got the pedals working using Joystick Slider 1 for combined brake/throttle pedals and Joystick Slider 2 for clutch pedal. How do I convert the axis values from “-1 to 1” to “0 to 1” for the clutch pedal?

Hi,
thanks for trying the wheel! Good to hear, that it’s working.

To get a value from 0 to 1, you can use the following:
021.PNG

In my case, the value has to be inverted:
021inv.PNG

Hope this helps.

I used the Vehicle Template for my driving game. The template has MyHUD blueprint for displaying the speed and gears. How do I display the joystick values using MyHUD blueprint? UE4 4.5 has Advanced Vehicle Template. What’s the difference between regular Vehicle Template and Advanced Vehicle Template besides the animated suspension? I asked a question about manual gear shifting at https://answers.unrealengine.com/questions/4903/question-vehicle-gear-shifting.html and they told me that the ability to set gears is not yet functional. I also want the vehicle to stop and stay when I apply the brakes and not to go into reverse.

Updated to 0.2.3 with a pull request
-Hot plugging method swapped to a windows event and will no longer cause
your FPS to drop whenever the joystick is not plugged in. Tested with
different joysticks between plugs.
-Added PluggedIn and Unplugged events for convenience.
-Fixed input mapping to support 32 buttons. They were previously
declared but not emitted.
-Fixed misc logging spam.
-Attempted force-feedback, seems very hard to get right so left for
another day/smarter dev.
-Added readme with instructions found on this page.

The hot plugging fix is pretty big, we were doing lazy enums earlier which caused pretty significant FPS drops whenever the joystick wasn’t plugged in and now its a windows device event with 0 performance impact. Tested it with two different joystick types and it seems stable, but please test and let me know if it works for you as well (also try the new plugged in/unplugged events).

Feel free to delete the force feedback code that is commented out, I tried to implement it, but Windows DirectInput API is not my strength. Hopefully someone with better knowledge will be able to patch it in correctly.