Strafe speed and unwanted jumping

When I strafe and walk forward/backward using the FPSWalker.js script from Unity3d I end up walking faster than I'm supposed to.

function FixedUpdate() {
	if (grounded) {
		// We are grounded, so recalculate movedirection directly from axes
		moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
		moveDirection = transform.TransformDirection(moveDirection);
		moveDirection *= speed;

		if (Input.GetButton ("Jump")) {
			moveDirection.y = jumpSpeed;
		}
	}

	// Apply gravity
	moveDirection.y -= gravity * Time.deltaTime;

	// Move the controller
	var controller : CharacterController = GetComponent(CharacterController);
	var flags = controller.Move(moveDirection * Time.deltaTime);
	grounded = (flags & CollisionFlags.CollidedBelow) != 0;
}

How do I tackle this problem? Also there's a problem using the MouseLook.cs script. When I use it in combination with the FPSWalker.js I get unwanted jumping when I look upward into the sky and walk forward. In short:

  • How do I get normal strafe speeds when strafing and walking forward/backward at the same time? [solved]
  • How do I prevent jumping when looking upward with the mouse and walking forward?

To solve the strafe speed problem, add this line just before you multiply by the speed variable:

if (moveDirection.sqrMagnitude > 1)
{
    moveDirection.Normalize();
}

Regarding the "Jumping when looking upward" problem, this shouldn't be happening if you are using the first-person controller prefab from the standard assets, so it may be that you have changed the setup to cause this. Rather than guess at what change you might have made, I'll explain why this problem might happen and maybe you'll be able to spot the cause once you know what you're looking for!

If you look carefully at how the prefab is set up initially, you'll see there's two instance of the MouseLook script used.

One is placed on the base "First Person Controller" GameObject, and one on the "Main Camera" GameObject (which is a child of the "First Person Controller").

The instance of MouseLook on the base ("First Person Controller") GameObject is set to only operate on the MouseX axis, and therefore only controls the rotation around the Y axis - i.e. spinning around, but not looking up and down.

The instance of MouseLook on the Main Camera object is set to only work on the MouseY axis, and therefore controls the looking up and down. The camera inherits its rotation from the parent "First Person Controller" object.

When you look at the FPSWalker script, you'll notice it uses the "TransformDirection" function to convert the motion direction to world space, via the 'transform' of the GameObject that it's placed on - which should be the "First Person Controller" GameObject. Because this isn't affected by looking up & down, the movement also isn't affected by looking up & down.

So, in your setup, you have either modified the axes on the first person controller script, or modified the parent-child relationship of the camera and the base object, or some other change which means the "TransformDirection" function is now taking the looking up & down into consideration when calculating the world-space direction for your "moveDirection" variable. The result is that when looking up and attempting to move forward, you also move upwards - in the direction that you're looking.

Hopefully from this information you'll be able to spot what you've done wrong and correct it! :-)