Increase jumpheight while holding down a key

Hello!

I have made a jumpscript that makes the Player jump and double jump. I just realized that this mechanism is not the best for the game that i am making. What i have now is that when i press a key, a set amount of force is added to the player.

Id like to make a new script in which the players jumpheight is dependant on how long you hold down a button, left mouse button for example.

The player should ofcourse have a maxheight, so that he wont be able to fly up forever. This could also be dependant on the time passed. I want the jumpheight to be increased expontentially, what i mean is that when you first press the key, you gain a burst of speed upwards that fades as you reach the maxheight (fast to slow). When you reach the maxheight the player gets a downward force that increases slow to fast, until you have reached the ground.

If you stop pressing the key before you reach the maxheight, the maxheight could be set to the point the player was on when you stopped pressing the key. So that the player gains the downwards force he otherwise would have gotten if he had reached the actual maxheight.

I hope my text was not too confusing…

This is my old script if its to any use:

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

	public float jumpPower;
	public float doubleJumppower;
	public int jumpCount;

	private int j;

	public bool isGrounded = true;
	
	void Update () {

		if (Input.GetButtonDown ("Fire1") && isGrounded == true && j != 0) 
		{	
			Vector3 velo = rigidbody2D.velocity;
			velo.y = 0;
			rigidbody2D.velocity = velo;

			jump ();
			j = j - 1;
		}
		if (Input.GetButtonDown ("Fire1") && isGrounded == false && j != 0)
		{	
			Vector3 velo = rigidbody2D.velocity;
			velo.y = 0;
			rigidbody2D.velocity = velo;

			Doublejump ();
			j = j - 1;
		}
	}
	
	void jump (){
			rigidbody2D.AddForce (transform.up * jumpPower);
			Debug.Log("Jumped");
		}
	void Doublejump (){
			rigidbody2D.AddForce (transform.up * doubleJumppower);
		}	
	void OnTriggerEnter2D(Collider2D other) {
			
		if(other.tag == "Ground")
		{	
		j = jumpCount;
		isGrounded = true;
		}
		else 
		{
		isGrounded = true;
		}
	}
}

Thank you in advance!

In order to achieve this, my approach would be to use a timer and a max time.

First, change line 25 to:

if (Input.GetButton("Fire1") && isGrounded == false && j != 0)

Next, lets add some variables at the top of your script. Something like:

public float jumpTime, maxJumpTime;

Now lets set the jumpTimer value to zero if we just jumped off the ground. To do this, lets add a statement 18 such as:

jumpTimer = 0;

Finally, lets apply the jumpTimer in your DoubleJump method:

    public void DoubleJump()
    {
        if (jumpTime >= maxJumpTime) return; //Return if we have already hit the max time.
        jumpTime += 1 * Time.deltaTime; //Add jump velocity each second.
        rigidbody2D.AddForce(transform.up * jumpTime,ForceMode.Acceleration));
    }

As far as the gravity thing - that’s probably best handled by another script. Are you saying that you want gravity to become stronger the higher he goes? Is there a terminal velocity that you’d like to reach? Rigidbodies usually do a pretty good job with physics.

hello I have this code for you, I added the comments that I would have typed into this so will not say much but feel free to ask also I changed OnTriggerEnter2D to OnCollisionEnter2D so I could make a quick prototype without needing custom collision logic you may need to change this back for yours

using UnityEngine;
using System.Collections;

public class IncreaseJumpHeightTest : MonoBehaviour {

public float jumpPower;
public float doubleJumppower;
public int jumpCount;

//this is how high realative to the player that the player can jump
public float maxHieght;

//this is the max hight in world space the player can jump
private float targetHieght;

private int j;

public bool isGrounded = true;

//when is jumping is true force will be added to the rigidbgody2D
public bool isJumping = false;

//reach hieght is V squared = U squared + 2as but with s as the subject

/*
 * we make S the subject to make 
 * 
 * S = V squared - U Squared
 *     ---------------------
 *         2 * a
 * 
 * S = distance
 * V = final velocity
 * U = initial velocity
 * a = acceleration
 * 
 * this means that it will tell us how far we have to go to get to the Top of the jump
 * 
 */
float ReachHieght()
{
	//our final velocity at the top of the jump we want as zero
	float v = 0;

	//our initial velocity is our upwards velocity this frame
	float u = rigidbody2D.velocity.y;

	//acceleration is defined in unity's project/physics settings
	float a = Physics.gravity.y;

	//S will tell us how far our current velocity will get us
	float s = (Mathf.Pow (v, 2) - Mathf.Pow (u, 2)) / (2 * a);

	return s;
}

void Update () {

	//if the distance that our current velocity will travle this frame + our current position
	//             is greater than or equal our target hight stop adding force
	if (ReachHieght () + transform.position.y >= targetHieght) 
	{
		isJumping = false;
	}

	if (Input.GetButtonDown ("Fire1") && isGrounded == true && j != 0) 
	{    
		//set isJumping to true
		isJumping = true;

		//get a world position to reach
		targetHieght = maxHieght + transform.position.y;

		Vector3 velo = rigidbody2D.velocity;
		velo.y = 0;
		rigidbody2D.velocity = velo;
		
		jump ();
		j = j - 1;
	}
	else if(Input.GetButtonUp("Fire1"))
	{
		//if player lets go of jump button stop adding force
		isJumping = false;
	}

	if (isJumping) 
	{
		//add jump force
		jump();
	}

	if (Input.GetButtonDown ("Fire1") && isGrounded == false && j != 0)
	{    
		Vector3 velo = rigidbody2D.velocity;
		velo.y = 0;
		rigidbody2D.velocity = velo;
		
		Doublejump ();
		j = j - 1;
	}

}

void jump (){
	rigidbody2D.AddForce (transform.up * jumpPower);
	Debug.Log("Jumped");
}
void Doublejump (){
	rigidbody2D.AddForce (transform.up * doubleJumppower);
}    
void OnCollisionEnter2D(Collision2D other) {

	Debug.Log("Grounded");

	if(other.collider.tag == "Ground")
	{    
		j = jumpCount;
		isGrounded = true;
	}
	else 
	{
		isGrounded = true;
	}
}

}

one limitation of this is if your initial force you add is too great it will launch the player above the target height some code to add a counter force to slow it down in time would be needed if you wanted a really quick launch.

If you’re looking to have this driven through the physics engine, here are some handy formulas you can take into consideration. With that in mind, here’s an approach you can take to handle this while honoring normal gravitational force.

public float jumpHeight = 5.0f; // The basic height in units of your jump. Set it wherever you want it.
public float jumpNegForce = 2.0f; // Cancel out of a jump while not holding the button
private float jumpForce; // This will be the force applied when you jump
private bool jumping; // Are you actually jumping? Or did you simply walk off a cliff?
private bool jumpHeld; // This is used to separate Update() from FixedUpdate() to guarantee appropriate physics interactions
private float jumpScale; // Scale for modifiers like sticky ground or springiness

// ...

void Start()
{
	// Calculate the jump force from the specified height based on the pull of gravity
	jumpForce = CalculateJumpForce(Physics2D.gravity.magnitude, jumpHeight);
	jumpScale = 1.0f;

	jumpHeld = false; // Setting this to false as insurance
}

// ...

void Update()
{
	if(Input.GetButtonDown("Fire1") && fJumpForce * fJumpScale > 0.0f)
	{
		bJumpInput = true;
	}
	else if(Input.GetButtonUp("Fire1"))
	{
		bJumpInput = false;
	}
}

// ...

void FixedUpdate()
{
	// The actual jumping is performed here, for the sake of timing input vs. physics
	if(jumpHeld)
	{
		if(isGrounded && !jumping)
		{
			jumping = true;
			rigidbody2D.AddForce(transform.up * jumpForce * jumpScale, ForceMode.VelocityChange); // Jump force not affected by mass
		}
	}
	else if(!isGrounded && jumping && Vector2.Dot(-Physics2D.gravity, rigidbody2D.velocity) > 0)
	{
		// Are you in the air AND jumping AND moving upward AND no longer holding jump?
		rigidbody2D.AddForce(Physics2D.gravity.normalized * jumpNegForce, ForceMode.Acceleration);
	}
}

// ...

float CalculateJumpForce(float gravityMagnitude, float height)
{
	//h = v^2/2g
	//2gh = v^2
	//sqrt(2gh) = v
	return Mathf.Sqrt(2 * gravityMagnitude * height);
}

I apologize if there are any typos in there. I culled a lot of extra content from one of my previous projects and mixed in as much of what you already had as I could.

Anyway, with this design, you define the maximum height you want to be able to jump to, as well as a force to counteract your jump when you release the button. Additionally, this also enables you to release and hold jump during the same ascent to lower the height slightly.