Here’s another first-person character controller I made for the Leap Motion Controller. In this demo, I’m aiming to simplify first-person camera controls by limiting what it can do.
In traditional first-person shooters, players have a lot of freedom – you can strafe and look independently. The issue with this is that for non-core players it can be difficult to pick up how to use, and when mapping motion controls to that type of control scheme, it’s easier for the user to accidentally do something unintentional.

In this demo, I intentionally stripped down a first person controller to the following:
- Players can only look left and right, as looking up and down can become disorienting for some people. (I might add that feature in later, but I’m starting small and simple for now.)
- Players cannot strafe, but can only move in the direction they are looking, or slowly backwards.
- Players can pull and pick up objects by closing their fist, and drop items by opening their hand. (Right now, it’s one object at a time, but this can be easily modified to pick up several objects at once to get a cool “force” feel.)
Hand GetForeMostHand() {
Frame f = m_leapController.Frame();
Hand foremostHand = null;
float zMax = -float.MaxValue;
for(int i = 0; i < f.Hands.Count; ++i) {
float palmZ = f.Hands[i].PalmPosition.ToUnityScaled().z;
if (palmZ > zMax) {
zMax = palmZ;
foremostHand = f.Hands[i];
}
}
return foremostHand;
}
We start off by finding the foremost hand, that is, the hand furthest away from the user and closest to the screen. Since everything in this demo is only using one hand, it’s important to pick a hand and stick with it. I’ve found that picking the furthest hand along the z-axis works quite well.
Once we’ve identified the hand to use for our first-person control scheme, we can use the absolute x position to determine if we should be looking left or right.
void ProcessLook(Hand hand) {
float handX = hand.PalmPosition.ToUnityScaled().x;
transform.RotateAround(Vector3.up, handX * 0.03f);
}
It’s possible to adjust the sensitivity of the look by changing the multiplier to handX. You can also introduce a “dead zone” for how far the hand has to move from 0 to start looking left and right.
void ProcessLook(Hand hand) {
float handX = hand.PalmPosition.ToUnityScaled().x;
if (Mathf.Abs(handX) > 1.0f) {
transform.RotateAround(Vector3.up, handX * 0.03f);
}
}
I’ve found that while it’s not really necessary, it’s usually best to modify the curve if the look feels too sensitive, rather than to introduce dead-zones.
The character translation/movement code is similarly simple. You can look at the absolute positioning of the hand along the z-axis to determine if the player should move forward or backwards.
void MoveCharacter(Hand hand) {
if (hand.PalmPosition.ToUnityScaled().z > 0) {
transform.position += transform.forward * 0.1f;
}
if (hand.PalmPosition.ToUnityScaled().z < -1.0f) {
transform.position -= transform.forward * 0.04f;
}
}
Notice that I have fixed speeds for the character movement; you can modify this to take into account how far the hand is along the z-axis to introduce variable speeds. You can also add acceleration if you wish – this all depends on how you want the character controller movement to feel.
I also have a small dead zone between -1.0 and 0.0 where the player isn’t moving at all. This is to allow players to stand still.
So there you have it. In only a few lines of code, you can get a first-person controller in Unity3D. You can check out the full project example here to see how I set up my project.
I also have binaries in the downloads section for those of you who don’t have Unity.
All of the bulk work happens in LeapCharacterController.cs and it’s only around 100 lines of code to perform the character controller logic and to perform the Object Grabbing logic.
I’d like to hear your thoughts on this project. What are some other useful approaches to first-person camera controls with the Leap Motion Controller? What factors would you consider when deciding how to define what can (or can’t) be done?