04 Aug 2013

Unity Hacks: Dual sticks

This is my third post in what looks like is going to turn into a series, examining parts of the example project I provided for the Unity Hacks presentation – delivered at a couple of the Unite conferences this year.

You can find the project and a recording of the presentation in the videos section of this site.


The DualControls interface has a very straight forward purpose: Provide a 2 × 2 axis input interface across platforms and compatible units. This is exposed via the DualControls.Left and DualControls.Right accessors – each returning a Vector2.

Supported out of the box is:

  • WASD + mouse.
  • Xbox360 controller (windows-only)
  • ps3 controller (OS X-only)
  • Shadowgun-style touch controls (left/right screen split)

However abstraction is relaxed enough that virtual sticks or alternative input like the leap motion could be added fairly easily (assuming you have a means of capturing that input data in the first place).


So controllers are not exactly nicely wrapped up in the current version of Unity. Which ungodly hack did I have to apply to get them to play along with just working out of the box in an easily installable package? It is actually not so bad. However I had to concede to some compromises up front. Basically when it comes to joysticks and controllers, you generally have two complications: the hardware itself and the driver.

So? What is so bad about that? Well, in a perfect world you had one driver for each controller type or at least all the drivers for the same hardware would map the buttons and axes in the same way, right?

Enter: This world. For every controller you always have at least two drivers set up differently: One for OS X and one for Windows (the Linux one often being based on the Windows one as I understand it). Why would anyone be content with just two drivers though? There exists a good number of different packages and open source solutions, vendor and OS provided drivers for the different controllers.

The way these are differentiated in the Unity runtime is via the joystick name string – as accessible via Input.GetJoystickNames.

This is what DualControls checks for in its Update handler. If a new joystick is found connected, it runs the name by the controller wiring and activates the appropriate controller (optionally if accepted by a callback).

Per default I have compromised and only provided wiring for the Xbox360 controller on Windows and the ps3 controller on OS X. This particular configuration stems from the fact that those OS’es ship with a pre-installed default driver for those controllers.

Microsoft clearly should support their own hardware and I’m assuming that Apple just supports the ps3 controller because it’s hardware from a direct Microsoft competitor.

However, again, the abstraction is loose enough that if you want to, you should be able to add support for more controllers fairly easily. See the end of the Controllers.cs script for that.

Oh, but I almost forgot the hack: As I am using the standard Unity Input API for this, the input manager needs configuring, right? So with no API for it, how do you go about doing that for a package?

You use the AssetDatabase API to load ProjectSettings/InputManager.asset and then the ScriptableObject API to modify it.

I hope you find this useful. For more details, these are the Unity Hacks scripts related to this post:

New Gear
Unity, iOS, TeamCity, AppCenter
RAID0 NVMe on Ubuntu
A Change of Gears
Unity Protocol Buffers
Behave 2.7
Behave 2.6
Trusted Gear
Mad Mash Versioning
Behave 2.5
Behave 2.4
The Engine Wars: Numbers
GDC 14: The Quest For Fun
Moving in Unity
Behave 2.3
Unity and .net assemblies
Behave 2.2
Behave 2.1
Behave 2.0
Unity Hacks: Dual sticks
Unity Hacks: Cameras
Unity Hacks: Touch gestures
Unite 13 video "Unity Hacks" available
The implicit local network interface
Talks and progress
Five years of Unity expertise looking for contracts
Automagic Unity Android Java gadget OF DOOM!
Invading Planet from your couch
Mountain Lion and laggy bluetooth and duct-tape
Unite 12 video and new videos section available
Asia Bootcamp videos now available
Path is now MIT licensed
Behave 1.4 released
So I've been a bit busy lately
Behave 1.3 released
IGDA Unity SIG slides
Second Unity IGDA SIG this evening: Scene construction and AI
First IGDA Unity SIG this evening
Alternative licensing available
Pathfinding in two lines
Path 2 released
Assembling and assimilating
Path 2 intro screencast
Path 2 beta release for GGJ
AIgameDev master class video now online
Expanding beta
Behave AIgameDev master class public stream
Behave master class on open AIgameDev stream tomorrow
Interview with AIGameDev
New video: From tree to code
Issue tracking on github Behave release project
IT University Copenhagen Unity course completed
IT University Copenhagen Unity course files Thursday
CPH IT University Unity course files
Behave 1.2 released
Video: Behave - starting from scratch
Behave runtime documentation updated
Behave 1.1 released
FAFF cleanup: Sketch
Building a menu of delegates and enums
Pick me! Pick me!
Optimising coroutine yielding in C#
Downloading the hydra
New license of Path: GPL
GUI drag-drop
Logging an entire GameObject
I bet you can't type an A!
Where did that component go?
New and improved: Behave 1.0 released
Behave 0.3b and unity 2.5
Behave 0.3b hotfix
Path tutorial video available
Path 1.0 launched!
Continued community tutorials
Community tutorial
New tutorial
First tutorial available
Behave 0.3b
unite '08 open-mic session
Behave 0.2b
Behave 0.1b
Behave pre-release
Path beta 0.3b
Path beta 0.2b
Path beta 0.1b
Path pre-release