Multiple Mice Input in Unity

I’m a big fan of local multiplayer – as far as I’m concerned, being bundled up with your mates cajoling each other and screaming at the TV is the very essence of gaming. I had an absolute blast at the recent Hugs ‘n Uppercuts local multiplayer event in Norwich, playing the likes of Gang Beasts, Nidhogg, Friendship Club etc.

CLYp9gfWwAAv7JR.jpg large

Multiplayer games where players use joypads for input is easy – just connect additional USB/wireless controllers and away you go (AFAIK, Unity supports up to 11, which is a strange limit, but there you go…). But what about local multiplayer games where players use a mouse for input? I’m not aware of any such games, but I couldn’t think of a valid reason why not to try. Perhaps it’s simply the logistics of having enough surface space on which to operate the mice… or perhaps it’s because it turns out to be a bit of a technical challenge….

Connecting additional USB mice is, at first glance, just as easy as connecting additional USB joysticks. And Windows will recognise them just fine too. The problem is that every mouse will control the same, single cursor. And, if you ask Unity’s Input class for the mousePosition, or to GetMouseButtonDown(), you’ll get the response from all connected mice, with no way to distinguish them.

Recognising the mice separately requires hooking into the Raw Input events at the OS level. This needs a native (non-managed) plugin, so this solution is very much Windows-specific. There’s probably an equivalent for Mac/Linux, but who cares about those? Not me.

While researching this problem, I came across a few relevant projects:

So, I rolled my sleeves up and hacked together various bits of the above into a Frankenstein-ish solution. It supports both 32/64 bit and will work in the editor and in a standalone build, though not a web build. To capture the mouse input, the program needs to create a window handle via System.Forms. Unity doesn’t really support System.Forms, and it will throw some warnings in the Editor (not in a build though), but it will (should) work just fine after that. Tested with up to 4 mice on Windows 8.1 64 bit and it works fine.

To use, you need to copy both the following dlls into the /Plugins directory of your project.

And the following script shows basic usage to access 4 mice:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RawMouseDriver;
using RawInputSharp;

public class MouseInput : MonoBehaviour {

    RawMouseDriver.RawMouseDriver mousedriver;
    private RawMouse[] mice;
    private Vector2[] move;
    private const int NUM_MICE = 4;

    // Use this for initialization
    void Start () {
        mousedriver = new RawMouseDriver.RawMouseDriver ();
        mice = new RawMouse[NUM_MICE];
        move = new Vector2[NUM_MICE];
    }

    void Update() {
        // Loop through all the connected mice
        for(int i=0; i<mice.Length; i++){
            try { 
                mousedriver.GetMouse(i, ref mice[i]);
                // Cumulative movement
                move[i] += new Vector2(mice[i].XDelta, -mice[i].YDelta);
            }
            catch {  }
        }
    }

    void OnGUI(){
        GUILayout.Label("Connected Mice:");
        for(int i=0; i< mice.Length; i++){
            if(mice[i] != null)
                GUILayout.Label("Mouse[" + i.ToString() + "] : " + move[i] + mice[i].Buttons[0] + mice[i].Buttons[1]);
        }
    }

    void OnApplicationQuit()
    {
        // Clean up
        mousedriver.Dispose ();
    }
}

And here it is in action:

This entry was posted in Game Dev and tagged , , , , . Bookmark the permalink.

3 Responses to Multiple Mice Input in Unity

  1. Great work, Ali!
    I did a unity port of Ryan C. Gordon’s ManyMouse a while back (https://icculus.org/manymouse/).

    Got it just barely working. I think Brendon Chung wanted to use it so I packaged it up for him. Haven’t tried to gussy it up at all, so use at your own risk, but it is Mac/Lunix/Windows compatible:

    https://drive.google.com/file/d/0BzlnW3oVU52falI3a3ByZU15N2M/view?usp=sharing

    Probably not a pretty implementation, but I do believe I got it working, yeah.

  2. Also, what’s happening with your GetMouse call? Is the dll accumulating input delta until it’s called in a unity update? Just wondering because I’m obsessive about polling rates.

  3. ComanderXXY says:

    I tried to use it, but it’s causing an Internal compiler error.
    Message was: “Internal compiler error. See the console log for more information. output was:
    Unhandled Exception: System.TypeLoadException: Could not load type ‘RawMouseDriver.RawMouseDriver’ from assembly ‘RawMouseDriver, Version=1.0.5660.39238, Culture=neutral, PublicKeyToken=null’.”

    which Unity version do i have to use?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s