Jumping in my FPS causes the player to teleport instead of smoothly jumping, and gravity doesn't work as it's supposed to

Hello,

I am creating an FPS game in Unity 5.0.1f1 with C# that has Quake-like movement, and as such I have used this excellent resource to get my movement script going. I am not using the default FPS prefabs, but I’m using a Character Controller for my player.

This person had a similar problem to me, but I’m using the same calculations for my jump, so that question (and a lot of similar questions I found) didn’t fix my errors.

I’m not going to quote the entire script (which is pretty lengthy) but I’ll post a few snippets and explain the problems I have.

I run the following function at the start of Update() to know what the player has pressed.

void UpdateInputs()
	{
		playerInput.moveForward = Input.GetAxis("Vertical");
		playerInput.moveRight = Input.GetAxis("Horizontal"); 
		playerInput.wishJump = Input.GetKey (KeyCode.Space);
	}

playerInput is an object of a class that I have created to have access to these values all over the script.

Now that I have my inputs in Update, I handle the rest in FixedUpdate.

This is my FixedUpdate(), which handles Ground Movement, Air Strafe, jumping and gravity.

	void FixedUpdate()
	{
		if (controller.isGrounded) {

			//reset vertical velocity and do a ground move
			new_velocity.y=0;
			new_velocity = MoveGround (PlayerAccelDirection (), prev_velocity);

			if(playerInput.wishJump)
			{
				new_velocity.y+=jump_speed;
				playerInput.wishJump = false;
				Debug.Log ("NEW VELOCITY Y IS " + new_velocity.y);
			}

		}
		else
		{
			//do an air move and do gravity stuff
			new_velocity = MoveAir (PlayerAccelDirection (), prev_velocity);
			new_velocity.y -= gravity * Time.deltaTime;
		}

		controller.Move(new_velocity * Time.fixedDeltaTime);
	}

I’ve omitted the functions MoveGround, MoveAir, and Accelerate (found inside aformentioned functions) because they’re 1-1 copies of the code in the first link I posted.

PlayerAccelDirection() is pretty simple and is as follows:

private Vector3 PlayerAccelDirection()
	{
		Vector3 direction = new Vector3(playerInput.moveRight, 0, playerInput.moveForward);
		direction = transform.TransformDirection(direction);
		return direction;
	}

Now that I’ve posted a bunch of code and put it in context as best as I could, I will explain the problems I am currently facing.

  1. When I jump, my character suddenly teleports to the apex of his jump instead of jumping smoothly.
  2. When I fall from a height, my character falls with a constant velocity instead of accelerating downwards.

I’m thinking that I have either confused my deltaTimes or there’s some logical error in there that I haven’t noticed.

Thank you very much in advance for any help.

I ended up solving this problem myself.

I found out through thorough Debug Logging that for some reason my previous speed Y was not saved, so I added a variable to the start of my script:

private float prev_y;

and adjusted my FixedUpdate like this:

void FixedUpdate()
	{
		if (controller.isGrounded) {
			//reset vertical velocity and do a ground move
			prev_y=0.0f;
			new_velocity = MoveGround (PlayerAccelDirection (), prev_velocity);

			if(Input.GetKey (KeyCode.Space))
			{
				prev_y+=jump_speed;
				wishJump = false;
			}

		}
		else
		{
			//do an air move and do gravity stuff
			new_velocity = MoveAir (PlayerAccelDirection (), prev_velocity);
		}

		new_velocity.y = prev_y;
		new_velocity.y -= gravity * Time.deltaTime;
		prev_y = new_velocity.y;
		Debug.Log ("Prev Y: " + prev_y + "| New velocity after: " + new_velocity.y);
		controller.Move(new_velocity * Time.deltaTime);
	}

And this solved both of my problems, so it shall be marked as solved.