Variable jump in C#

Hi, I have a code which is basically perfect for jump and doublejump but the character has a fixed jumping height. What I’m looking for is a “super mario jumping effect”. Press the jump button really fast, jump a little, keep it pressed , jump a little higher and so on. (hope I explained myself well, if not, I’ll try again).

this is the code

using UnityEngine;
using System.Collections;

public class CharController : MonoBehaviour
{
    [SerializeField] private float m_JumpForce;
    [SerializeField] private float moveSpeed;
    [SerializeField] private LayerMask m_WhatIsGround;
   
    private Transform m_GroundCheck;
    private Transform m_GroundCheckS;
    const float k_GroundedRadius = .15f;
   
    private bool cir_Grounded;
    private bool cir_GroundedS;
    private bool is_Grounded;
    private bool doubleJump;
   
    private Rigidbody2D m_Rigidbody2D;
   
    // Use this for initialization
    void Start()
    {
        m_GroundCheck = transform.Find("groundCheck");
        m_GroundCheckS = transform.Find("groundCheckS");
        m_Rigidbody2D = GetComponent<Rigidbody2D>();   

        gameObject.transform.position = new Vector2 (10, 30);
    }
   
    void Update()
    {
        cir_Grounded = false;
        cir_GroundedS = false;
        is_Grounded = false;

        Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
        for (int i = 0; i < colliders.Length; i++)
        {
            if (colliders[i].gameObject != gameObject)
                cir_Grounded = true;
        }
       
        Collider2D[] colliders2 = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
        for (int i = 0; i < colliders2.Length; i++)
        {
            if (colliders2[i].gameObject != gameObject)
                cir_GroundedS = true;
        }
       
        if (cir_GroundedS && cir_Grounded)
        {
            is_Grounded = true;
        }

        //m_Rigidbody2D.velocity = new Vector2 (moveSpeed, m_Rigidbody2D.velocity.y); //Moves the player horizontally

        if (Input.GetKeyDown ("space"))
        {
            if (is_Grounded)
            {
                is_Grounded = false;
                cir_Grounded = false;
                cir_GroundedS = false;
                m_Rigidbody2D.velocity = new Vector2(m_Rigidbody2D.velocity.x, 0);
                m_Rigidbody2D.AddForce (new Vector2(0f, m_JumpForce));
                doubleJump = true;
            }
            else if (doubleJump)
            {
                m_Rigidbody2D.velocity = new Vector2(m_Rigidbody2D.velocity.x, 0);
                m_Rigidbody2D.AddForce (new Vector2(0f, m_JumpForce));
                doubleJump = false;
            }
        }
    }
}

Thanks for the attention

Try something like:

float jumpForce = 3f;

//inside FixedUpdate
if(Input.GetButton("Jump"))
{
    m_Rigidbody2D.AddForce(new Vector2(0f, jumpForce));
    jumpForce -= .5f //or whatever amount
    if(jumpForce < 0f)
        jumpForce = 0f;
}

//inside Update
if(Input.GetButtonUp("Jump"))
{
    jumpForce = 3f; //go back to original power
}

This is just off the top of my head, but should get you going the right direction

1 Like

Put it inside FixedUpdate for results that won’t vary wildly depending on framerate.

1 Like

Hah, good point! I wrote the code out quickly in notepad

EDIT: The GetButton should be in fixed update, however the GetButtonUp should be in regular update since FixedUpdate can miss down and up checks

Thank you for replying, as soon as I get them working I’ll let you know. The solution concept is so easy, thanks again.

I know, double post but need to ask you an opinion (actually if we can discuss about a code).
Basically this it the Gamasutra page I took the idea of how to make a variable height jump the first time: http://www.gamasutra.com/blogs/DanielFineberg/20150825/244650/Designing_a_Jump_in_Unity.php

this is the code in short (a simplified version of it):

void Update()
{
    if(jumpButtonDown && !jumping)
    {
        jumping = true;
        StartCoroutine(JumpRoutine());
    }
}

IEnumerator JumpRoutine()
{
    rigidbody.velocity = Vector2.zero;
    float timer = 0;
     
    while(jumpButtonPressed && timer < jumpTime)
    {
        //Calculate how far through the jump we are as a percentage
        //apply the full jump force on the first frame, then apply less force
        //each consecutive frame
         
        float proportionCompleted = timer / jumpTime;
        Vector2 thisFrameJumpVector = Vector2.Lerp(jumpVector, Vector2.zero, proportionCompleted);
        rigidbody.AddForce(thisFrameJumpVector);
        timer += Time.deltaTime;
        yield return null;
    }
     
    jumping = false;
}
}

So, how in the world can they get the button pressed and put it in a while loop without make Unity crash (every time I tried it crashed). To compare the “while loop” with an “if statement” (that holds a “input.getkey”), the while loop never ends until the conditions are met, but what about the “if statement”? does it exits every frame but still holding the condition Input.getkey?

Can somebody please tell me what this ‘jumpVector’ is and which values it should have? Plus, the way this C# code on gamasutra is written, it does not work for me at all. I change that first rigidbody.velocity to the new AddForce standard but the player never reacts to the pressed button. Only to the initial first frame push. Please help.

It’s the direction you’re jumping in!

probably something along the lines of:

Vector2.up + currentVelocity.x;

Note that I’m not normalizing the vector. That gives Mario rules, where a standing jump and a running jump gives the same height.

I stumbled across this tutorial series recently while looking for an alternative solution to my problem.

I remember it having a intuitive variable jump solution. I recommend a watch.

Kind Regards,
Joe