Android FPS Control Script

Hi Guys,

I just made an FPS Control Script for Android from scratch, and I have decided to release it to the forums for people who want to use it. What’s special about this one from the Unity default one is threefold:

  1. The move pad is “floating,” which means that its position is determined by where ever you press.
  2. Rotation uses a full half of the screen, instead of being confined to a rotation pad.
  3. There is now (togglable) jumping and double-jumping

Here is a screenshot of the setup:

And here is the script:

#pragma strict

var cameraPivot : Transform;

var speed : float = 4;

private var thisTransform : Transform;
private var character : CharacterController;
private var cameraVelocity : Vector3;
private var velocity : Vector3;
private var canJump = true;

var movementOriginX : float;
var movementOriginY : float;

function Start ()
{
	thisTransform = GetComponent(Transform);
	character = GetComponent(CharacterController);
	originalRotation = transform.rotation.eulerAngles.y;
	movePad.transform.position = new Vector2(-1,-1);
	moveOutline.transform.position = new Vector2(-1,-1);
	jump = false;
	doubleJump = false;
}

function Update ()
{
	var moveDiff : Vector2;
	for (var touch : Touch in Input.touches)
	{
		if (touch.phase == TouchPhase.Began)
		{
			if (jumpButton.HitTest(touch.position))
			{
				jump = true;
			}
			else if (touch.position.x < Screen.width / 2)
			{
				leftFingerID = touch.fingerId;
				leftFingerCenter = touch.position;
				moveOutline.transform.position.x = touch.position.x / Screen.width;
				moveOutline.transform.position.y = touch.position.y / Screen.height;
				movePad.transform.position.x = touch.position.x / Screen.width;
				movePad.transform.position.y = touch.position.y / Screen.height;
			}
			else
			{
				rightFingerID = touch.fingerId;
			}
		}
		else if (touch.phase == TouchPhase.Moved)
		{
			if (touch.position.x < Screen.width / 2)
			{
				if (leftFingerID == touch.fingerId)
				{
					mDiff = touch.position - leftFingerCenter;
					var distPer = mDiff.magnitude * 100 / moveStickDiff;
					if (distPer > 100)
					{
						distPer = 100;
					}
					leftFingerInput = mDiff.normalized * distPer / 100;
					
					movePad.transform.position.x = leftFingerCenter.x / Screen.width + mDiff.normalized.x * distPer / 100 * moveStickDiff / Screen.width;
					movePad.transform.position.y = leftFingerCenter.y / Screen.height + mDiff.normalized.y * distPer / 100 * moveStickDiff / Screen.height;
				}
			}
			else
			{
				if (rightFingerID == touch.fingerId)
				{
					rightFingerInput = touch.deltaPosition * Time.smoothDeltaTime;
				}
			}
		}
		else if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
		{
			if (touch.fingerId == leftFingerID)
			{
				movePad.transform.position = new Vector2(-1,-1);
				moveOutline.transform.position = new Vector2(-1,-1);
				leftFingerID = -1;
				leftFingerInput = new Vector2(0, 0);
			}
			if (touch.fingerId == rightFingerID)
			{
				rightFingerID = -1;
				rightFingerInput = new Vector2(0, 0);
			}
		}
	}
	
	rotationX += rightFingerInput.x * 25;
	rotationY += rightFingerInput.y * 25;
	rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);
  	transform.rotation =  Quaternion.Slerp (transform.rotation, Quaternion.Euler(0, originalRotation + rotationX, 0),  0.1);
	cameraPivot.localRotation =  Quaternion.Slerp (cameraPivot.localRotation, Quaternion.Euler(cameraPivot.localRotation.x-rotationY, 0, 0),  0.1);
	
	moveDirection = thisTransform.TransformDirection(new Vector3(leftFingerInput.x, 0, leftFingerInput.y));
	moveDirection *= speed;
	moveDirection += Physics.gravity;
	
	if (character.isGrounded)
	{
		doubleJump = false;
		if (jump  jumpingEnabled)
		{
			velocityJ = character.velocity / 3;
			velocityJ.y = jumpSpeed;
		}
		else
		{
			velocityJ = new Vector3(0, 0, 0);
		}
	}
	else
	{
		if (!doubleJump  jump  doubleJumpingEnabled)
		{
			velocityJ = character.velocity / 3;
			velocityJ.y = jumpSpeed;
			doubleJump = true;
		}
		velocityJ.y += Physics.gravity.y * Time.smoothDeltaTime;
	}
	
	moveDirection += velocityJ;
	
	character.Move(moveDirection * Time.smoothDeltaTime);
	jump = false;
}

var rightFingerID;
var leftFingerID;
var leftFingerCenter : Vector2;
var mDiff : Vector2;
var moveStickDiff = 100;
var leftFingerInput : Vector2;
var rightFingerInput : Vector2;

var moveOutline : GUITexture;
var movePad : GUITexture;
var jumpButton : GUITexture;

var rotationX : float;
var rotationY : float;
var minimumY = -20;
var maximumY = 20;

var originalRotation : float;
var moveDirection : Vector3;
var jump : boolean;
var doubleJump : boolean;

var jumpSpeed : float = 25;
var velocityJ : Vector3;
var doubleJumpingEnabled : boolean = true;
var jumpingEnabled : boolean = true;

Enjoy!

3 Likes

I tested on my Acer Iconia a 500 and I have a little problem
Move pad has no effect on the Move Outline.
GUI textures are not refundable. Move Outline texture is moving very quickly and is off screen

1 Like

Movepad is supposed to be a 50x50 circle. Moveoutline is supposed to be a 100x100 outline. The outline stays still while the movepad moves with the finger. I still need to write code to constrain the pad to the outline.

1 Like

I have an Acer A500 and it works fine. Just try to keep playing with it.

The outline is now ok.
Movepad is moving outside the ring.
Cancellation touch Movepad not to ring back

I have fixed it. Updating original post right now.

Added double jumping and jumping. You need to make a jump button.

Really good work
after the update is better.
it would need fix a small thing …

What is a license to use?

1 Like

It is free to use for both commercial and free products. I made this for fun, so I am giving it to the community for free. After all, I’ve gotten most of my help from previous forum posts!

1 Like

Thank you very much. This will certainly come in handy for a future project.

can you pack .unitypackage with example pls.

Thank you mate. I am starting my first experiences with android on Unity and I will study the script…

Hello raahilsha! I really dislike the mobile control sticks unity gives you in the mobile standard assets. I’ve been looking everywhere for a floating move pad and yours looks promising. I tried to test your script out on my game on my galaxy s4 but my game crashes the instant I touch the screen. If I press the back button, the game actually pauses.

Any idea what I might have done wrong?

Hi, thaks for share this great script for android developing, but somehow i cant get this to work:

I create two GUI textures on my project, one its named Pad and the other Pad Outline (put 2 images for the Gui textures one 50x50 and the other 100x100 px), then place the FirstPersonSetup from the Standard Assets (mobile) on my project, then deactivate the First Person Control Script from the “Player” on the First Person Controls Prefab in the game (as in the example image) and deactivate the Dual TouchPads from the game, then attach the new My FPSMovement script to the “Player” and drag the Gui textures from the game to the new script, but when i test the game on a Nexus 7 the controls dont shows up and nothing happens…

Thanks in advance for any guide on this, im back to unity after several months and perhaps im doing something wrong…:face_with_spiral_eyes:

Can you add to this movingplatform? ;/ Bicose i don’t cnow how to make lift for this playr :confused:

…Dang, I was actually going to look into this soon! Dead Trigger 2’s controls were, in a way, inspiring and showed how overly simple and distracting my joystick controls are. This’ll save me some time down the road.

And I guess it’s going to be “fun” converting this to C# then dissecting piece by piece as it flies over my head and I try to edit it even further :wink:

Thanks.

Hi, everyone :slight_smile:

Thanks for this. It actually put me on the right track and I was able to make simple controls using the GUI. I have a better idea now though which is, sigh, so darn revolutionary. I’ll keep you all updated if you’re interested.

Oh, and I’m kind of ‘new’ here so sorry for bringing up an old thread.

Any chance you could help me with this. i cant get it working, im newbie with unity…any chance of a package? so i can look at it.

Thankyou very much :slight_smile:

This is the best and easy mobile controls what i ever seen! Thanx you! You saved my time a lot!