Trying to set up a jump buffer and it's not working...

Hi everyone, this is my first time posting on here so I hope I am asking in the right place.

I am pretty new to coding and have been doing it less that 6 months. I have seen lots of post and watch a bunch of tutorials but can’t seem to find a solution for my issue, not sure what I am missing. I have a pretty simple character controller and want to implement a jump buffer but no matter how I move things around I can’t seem to get it.

I currently have the jump buffer in the FixedUpdate() looking to see if jump = true; for it to run. I have also tried running it in Update when the jump input has been pressed. Neither ways seem to work.

Any help would be greatly appreciated or if there is a solution on another thread already just point me in the right direction.

Here is my Character controller script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    private Rigidbody2D playerRb;

    [Header("Player Movement")]
    public float moveSpeed;
    public float jumpforce;
    [Space]
    public float wallSlideSpeed;
    public float hangTime = .2f;
    public float jumpBufferLength = .2f;

    private float hangCounter;
    private float jumpBufferCounter;
    private float h;
    private bool jump;
    private bool halfJump;
    private bool isSliding;

    [Header("Collision Check")]
    public LayerMask whatIsGround;
    public LayerMask whatIsWall;
    [Space]
    public float groundCheckRadius;
    public float wallCheckRadius;
    public Transform groundCheckPoint, groundCheckPoint2, wallCheck;
   
    private bool isGrounded, isWall;

    [Header("Player Sprite")]
    //public Animator anim;
    public SpriteRenderer playerSr;


    // Start is called before the first frame update
    void Start()
    {
        playerRb = GetComponent<Rigidbody2D>();  
    }

    // Update is called once per frame
    void Update()
    {
      

        //Horizontal Input
        h = Input.GetAxisRaw("Horizontal");

        //Jump
        if (Input.GetButtonDown("Jump"))
        {
            jump = true;
        }
       

        //Less Jump
        if (Input.GetButtonUp("Jump"))
        {
            halfJump = true;
        }


        //Wall Slide
        if (isWall && !isGrounded && h != 0)
        {
            isSliding = true;
        }
        else
        {
            isSliding = false;
        }

        PlayerFlip();
    }

    private void FixedUpdate()
    {
        //Check if the player is grounded
        isGrounded = Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckRadius, whatIsGround) || Physics2D.OverlapCircle(groundCheckPoint2.position, groundCheckRadius, whatIsGround);
        //Check if the player is touching wall
        isWall = Physics2D.OverlapCircle(wallCheck.position, wallCheckRadius, whatIsWall);

        //Coyote Time
        if (isGrounded)
        {
            hangCounter = hangTime;
        }
        else
        {
            hangCounter -= Time.deltaTime;
           // Debug.Log("hang counter = " + hangCounter);
        }
         
        //Jump Buffer
        if (jump)
        {
            jumpBufferCounter = jumpBufferLength;
        }
        else
        {
            jumpBufferCounter -= Time.deltaTime;
            Debug.Log("buffer counter = " + jumpBufferCounter);
        }

        //Horizontal Movement
        playerRb.velocity = new Vector2(h * moveSpeed, playerRb.velocity.y);

        //Jumps
        if (jump)
        {
            Jump();
        }

        if (halfJump)
        {
            HalfJump();
        }

        if (isSliding)
        {
            playerRb.velocity = new Vector2(playerRb.velocity.x, Mathf.Clamp(playerRb.velocity.y, -wallSlideSpeed, float.MaxValue)); 
        }
    }

    private void Jump()
    {
       

        if ( jumpBufferCounter > 0 && hangCounter > 0)
        {
            playerRb.velocity = new Vector2(playerRb.velocity.x, jumpforce);
            hangCounter = 0;
            jumpBufferCounter = 0;
        }
        jump = false;
       
    }

    private void HalfJump()
    {
        if(playerRb.velocity.y > 0)
        {
        playerRb.velocity = new Vector2(playerRb.velocity.x, playerRb.velocity.y *.5f);
        }
        halfJump = false;
    }
  
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(groundCheckPoint.position, groundCheckRadius);
        Gizmos.DrawWireSphere(groundCheckPoint2.position, groundCheckRadius);
        Gizmos.DrawWireSphere(wallCheck.position, wallCheckRadius);
    }

    private void PlayerFlip()
    {
        //flip the player
        if (Input.GetAxisRaw("Horizontal") > 0)
        {
            playerSr.flipX = false;
        }
        else if (Input.GetAxisRaw("Horizontal") < 0)
        {
            playerSr.flipX = true;
        }
    }
}

Let me tell you how I did it:

originally I had (pseudocode):

if (jumpButtonDown)
{
  DoJumpIfGrounded();
}

Instead I changed it to:

if (jumpButtonDown)
{
  JumpTimer += 0.2f;  // buffer amount
}

if (JumpTimer > 0)
{
  JumpTimer -= Time.deltaTime;

  if (DoJumpIfGrounded())
  {
    JumpTimer = 0;
  }
}
1 Like

NOTE: I just edited the above because I had a logic bug in my original post.