- Home /
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!
Answer by Eno-Khaon · Sep 29, 2015 at 02:22 AM
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.
Answer by Addyarb · Sep 27, 2015 at 11:06 PM
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.
Thank you for the comment, i tried this and rigidbody2D.AddForce(transform.up * jumpTime,Force$$anonymous$$ode.Acceleration));
does not work since it needs to have Force$$anonymous$$ode2D when working with rigidbody2D and Force$$anonymous$$ode2D does unfortunetaly not have the .acceleration component.
Answer by Runalotski · Sep 27, 2015 at 11:53 PM
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.
Thank you very much, it was something like this i was looking for. I will try to implement it first thing in the morning!
Your answer
![](https://koobas.hobune.stream/wayback/20220612035244im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Hey Guys I have a problem with a single jump script. 1 Answer
Sphere can jump, but doesn't stop. 1 Answer
can anyone help me to smooth the jump? 0 Answers
Jumping only once (2D) 2 Answers
Multiple jump C# Script. 2 Answers