Character is not jumping properly

So, my character doesn’t jump properly. I have tried a few things and the current state is that if I press space the character nudges up a small amount and back down. Trying to get the character to jump as you would expect from a 2d side scroller and I know I am just overlooking something, so any guidance is appreciated.

void checkMovement()
{
   float vSpeed = 0f;
   MoveVector = Vector3.zero;
   if(Input.GetKey(KeyCode.D)){
      MoveVector += new Vector3(MoveSpeed * Time.deltaTime,0,0);
      faceDirection = 1;
   }
      else if(Input.GetKey(KeyCode.A)){
      MoveVector -= new Vector3(MoveSpeed * Time.deltaTime,0,0);
      faceDirection = -1;
   }
   if(Input.GetKeyDown(KeyCode.Space)){
      MoveVector += new Vector3(0,JumpSpeed * Time.deltaTime,0);
   }
   MoveVector -= new Vector3(0,Gravity* Time.deltaTime,0);
   CharacterController.Move(MoveVector);
}

Hi,

What values are you setting Gravity and JumpSpeed at? Make sure JumpSpeed is a higher value than Gravity.

You will also find that with your current code, you will be able to press space in quick succession and your character will keep rising upwards :slight_smile:

You need to add a condition to check if the character is on the ground before jumping. Unless you want a double jump ability?

Good luck!

Gravity is 9
Jumpspeed is 20

I was going to fix that issue with double jumping later. Right now I am just trying to get controlled jumping working cause I whipped out what I had before to try and simplify lol. Right now it nudges up maybe .2 and then back down.

What I am mostly trying to work on is getting the character to jump up gracefully. The “gravity” seems to be working okay now. The character seems to make the upwards part of the jump almost instantly and I want to smooth it out. Gravity is set to 4 and jumpspeed is 80. The 80 seems to give me the height I need.

void checkMovement()
	{
		float vSpeed = 0f;
		//VerticalVelocity = MoveVector.y;
		MoveVector = Vector3.zero;
		if(Input.GetKey(KeyCode.D)){
			MoveVector += new Vector3(MoveSpeed,0,0);
			//xMove = MoveSpeed * Time.deltaTime;
			faceDirection = 1;
		}
		else if(Input.GetKey(KeyCode.A)){
			MoveVector -= new Vector3(MoveSpeed,0,0);
			//xMove = -MoveSpeed * Time.deltaTime;
			faceDirection = -1;
		}
		if(Input.GetKeyDown(KeyCode.Space)){
			MoveVector += new Vector3(0,JumpSpeed,0);
			//CharacterController.Move(MoveVector);
			//CharacterController.Move(Vector3.up * JumpSpeed);
			//vSpeed = JumpSpeed;
			//MoveVector.y = 100;// * Time.deltaTime;
			//CharacterController.Move(MoveVector * Time.deltaTime);
		}
		//MoveVector -= new Vector3(0,Gravity * Time.deltaTime,0);
		MoveVector.y -= Gravity;// * Time.deltaTime;
		CharacterController.Move(MoveVector * Time.deltaTime);		
	}

Bump.

So, what should I look at to fix my characters upward part of the jump?

Hey check out my post at on this thread, that is how my character jumps and it works perfect.
http://forum.unity3d.com/threads/212612-I-can-t-jump-when-I-m-not-moving

For some reason rigidybody does not work for me. Does gravity or something need to be set for rigidbody?

My old code jumps the character up instantly but with velocity the character isn’t moving.

Bump.

So, still trying to refine my jump. Applying “gravity” makes the character fall at a rate I like. My problem now is trying to get the character to move upwards at the same rate.

Here is the current jump function

void jumpUp()
	{
		MoveVector.y += JumpSpeed;// * Time.deltaTime;
		CharacterController.Move(MoveVector * Time.deltaTime);
	}

And here is the code that calls it and also has the “gravity”.

void checkMovement()
	{
		float vSpeed = 0f;
		//VerticalVelocity = MoveVector.y;
		MoveVector = Vector3.zero;
		if(Input.GetKey(KeyCode.D)){
			MoveVector += new Vector3(MoveSpeed,0,0);
			//xMove = MoveSpeed * Time.deltaTime;
			faceDirection = 1;
		}
		else if(Input.GetKey(KeyCode.A)){
			MoveVector -= new Vector3(MoveSpeed,0,0);
			//xMove = -MoveSpeed * Time.deltaTime;
			faceDirection = -1;
		}
		if(Input.GetKeyDown(KeyCode.Space)  CharacterController.isGrounded){
			//StartCoroutine(jump());
			jumpUp();
			//MoveVector += new Vector3(0,JumpSpeed,0);
			//this.rigidbody.velocity = new Vector3(0,JumpSpeed,0);    // Jumps in air
			//rigidbody.velocity += new Vector3(0,100f,0);
			//this.rigidbody.velocity.y -= 4f;
			//CharacterController.Move(MoveVector);
			//CharacterController.Move(Vector3.up * JumpSpeed);
			//vSpeed = JumpSpeed;			
			//CharacterController.Move(MoveVector * Time.deltaTime);
		}
		//MoveVector -= new Vector3(0,Gravity * Time.deltaTime,0);
		MoveVector.y -= Gravity;// * Time.deltaTime;
		CharacterController.Move(MoveVector * Time.deltaTime);		
	}

well, If I would make a character jump I would use just and only forces like
rigidbody.addforce(Vector3.up, jumpspeed);
rigidbody.addforce(trasform.forward,forwardspeed);

than apply gravity and drag in order to make it falling back and stopping.

I thought I had read somewhere that rigidbody movement didn’t work well with character controller attached. Is this not the case.

I did try to add force before but have never got the character to move. Tried just now and still the same, even with the gravity line of code commented out. Just not sure what I am overlooking.

What I would do is use RigidBody and get rid of Character Controller which is I think a special case of RigidBody.
After that all you have to do is:

if(Input.GetKeyDown(KeyCode.Space)  CharacterController.isGrounded)
   player.GetComponent<Rigidbody>().AddForce(jumpVel, ForceMode.VelocityChange);

This way you instantly accelerate character the instance space is pressed and then allow Unity physics engine to handle the rest - apply gravity to decelerate your jumpVel and then accelerate downwards.

EDIT:

We now use AddForce instead of Move anyway so no need using CharacterController

If you want your character no to be affected by other physical happenings then you can make RigidBody Cinematic. AddForce will longer work I think and you’ll have to apply gravity, movement etc. manually like you did with CharacterController. You say you had downward movement working. Upward is the same just opposite direction.

Is it still easy to have collision work without character controller?

I will play around with this when I get home and hopefully get things the way I want finally.

Collisions will work perfectly with a rigidbody. You will also get perfect momentum, falling, bouncing, friction, etc. and everything else the physics engine can do. The problem with using a rigidbody is that you have to constrain that motion into something your player can control easily. This can be very difficult because you have to fight against the physics engine by applying forces, constraining axes, tweaking materials, etc.

The character controller is entirely the opposite approach. A character controller gives the player precise and responsive controls, but you have to fake enough physics so that the movement feels fluid. This is what people generally use because it is a bit easier unless you really need to have authentic physics for your players.

This is also why you can’t combine rigidbodies and character controller. The rigidbody is giving all the control to the physics engine while the character controller is trying to control the movement so they just end up fighting and nothing works.

The problem in your case is that you are not conserving momentum. You jump by simply moving the character in a single frame so that is exactly what you get. Your problem is that you are zeroing your MoveVector every frame:

MoveVector = Vector3.zero;

What you need to do is use a velocity vector instead.

void checkMovement()

{

// Friction is a factor between 0 and 1 that reduces your characters speed. 
// Low values gives lows of control, and higher values makes for a slippier surface
// Only applied only to horizontal movement
// You will also want to change it if the character is in the air or on different surfaces
     VelocityVector.x *= friction;  

   if(Input.GetKey(KeyCode.D)){

      VelocityVector += MoveSpeed * Time.deltaTime;
      faceDirection = 1;  
// Note, with this code a player could be facing one direction 
// while still moving in the other if they had a lot of speed 
// and are on a slippery surface.  That may or may not be what you want.

   }

      else if(Input.GetKey(KeyCode.A)){

      VelocityVector -= MoveSpeed * Time.deltaTime;
      faceDirection = -1;

   }

   if(Input.GetKeyDown(KeyCode.Space)){

      if (playerIsGrounded || playerCanDoubleJump){
           VelocityVector  += JumpSpeed * Time.deltaTime;
      }

   }

   VelocityVector  -= Gravity* Time.deltaTime;

   CharacterController.Move(VelocityVector);

}

Since you are not zeroing out the velocity vector, the JumpSpeed that you applied last frame will be conserved. Each frame will add more gravity until your entire jump velocity is gone and your character will start falling.

It has been a while since this thread has a post, but I recently came up against this very issue, and the solution is to use a coroutine to create a smooth set of sequential upwards motions.

void FixedUpdate() {
        float yVal = 0;
        if (jumping)
            yVal = jumpSpeed;
        moveDirection = new Vector3(Input.GetAxis("Horizontal"), yVal, Input.GetAxis("Vertical"));
        moveDirection = transform.TransformDirection(moveDirection);
.
.
.
doJump();
.
.
.}

Then in doJump() you can say jumping is true and start the coroutine which will keep jumping true for several frames.

    private void doJump() {
        if (!jumping) {
            jumping = true;
            StartCoroutine(jumpUpForceOverTime());
        }
    }

    IEnumerator jumpUpForceOverTime() {
        for(int i = 0; i < 10; i++) {
            yield return new WaitForFixedUpdate();
        }
        jumping = false;
        yield return null;

I found 10 iterations to provide a smooth jump feel, but you could increase it for a longer jump, over more frames.

This is my character jumping and I am using a Character controller, no rigid body.
link: https://zippy.gfycat.com/LegalImpartialEidolonhelvum.webm