I am trying to implement a jump buffer in my 2d platformer. There are plenty of tutorials that show how to do this using the old input system, but I’m using the new input and invoking the jump using unity events. There is another post asking this same question, and it’s marked as resolved, but the solution is for coyote time, not jump buffer. I have coyote time working fine. What I’m specifically trying to do is allow the player to jump just before they become grounded. Can someone please help me?
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using UnityEditor.Rendering.LookDev;
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(Rigidbody2D), typeof(TouchingDirections), typeof(Damageable))]
public class PlayerController : MonoBehaviour
{
public float walkSpeed = 5f;
public float runSpeed = 8f;
public float airWalkSpeed = 3f;
public float jumpImpulse = 10f;
private float coyoteTime = 0.2f;
private float coyoteTimeCounter;
private float jumpBufferTime = 0.2f;
private float jumpBufferCounter;
Vector2 moveInput;
TouchingDirections touchingDirections;
Damageable damageable;
public float CurrentMoveSpeed
{
get
{
if (CanMove)
{
if (IsMoving && !touchingDirections.IsOnWall)
{
if (touchingDirections.IsGrounded)
{
if (IsRunning)
{
return runSpeed;
}
else
{
return walkSpeed;
}
}
else
{
// Air move
return airWalkSpeed;
}
}
else
{
// Idle speed
return 0;
}
}
else
{
// Movement locked
return 0;
}
}
}
[SerializeField]
private bool _isMoving = false;
public bool IsMoving
{
get
{
return _isMoving;
}
private set
{
_isMoving = value;
animator.SetBool(AnimationStrings.isMoving, value);
}
}
[SerializeField]
private bool _isRunning = false;
public bool IsRunning
{
get
{
return _isRunning;
}
set
{
_isRunning = value;
animator.SetBool(AnimationStrings.isRunning, value);
}
}
[SerializeField]
public bool _isFacingRight = true;
public bool IsFacingRight
{
get
{
return _isFacingRight;
}
private set
{
// Flip only if value is new
if (_isFacingRight != value)
{
// Flip the local scale to make the player face the opposite direction
transform.localScale *= new Vector2(-1, 1);
}
_isFacingRight = value;
}
}
public bool CanMove
{
get
{
return animator.GetBool(AnimationStrings.canMove);
}
}
public bool IsAlive
{
get
{
return animator.GetBool(AnimationStrings.isAlive);
}
}
Rigidbody2D rb;
Animator animator;
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
touchingDirections = GetComponent<TouchingDirections>();
damageable = GetComponent<Damageable>();
}
private void Update()
{
if(touchingDirections.IsGrounded)
{
coyoteTimeCounter = coyoteTime;
}
else
{
coyoteTimeCounter -= Time.deltaTime;
}
}
private void FixedUpdate()
{
if(!damageable.LockVelocity)
rb.velocity = new Vector2(moveInput.x * CurrentMoveSpeed, rb.velocity.y);
animator.SetFloat(AnimationStrings.yVelocity, rb.velocity.y);
}
public void OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
if(IsAlive)
{
IsMoving = moveInput != Vector2.zero;
SetFacingDirection(moveInput);
}
else
{
IsMoving = false;
}
}
private void SetFacingDirection(Vector2 moveInput)
{
if (moveInput.x > 0 && !IsFacingRight)
{
// Face the right
IsFacingRight = true;
}
else if (moveInput.x < 0 && IsFacingRight)
{
// Face the left
IsFacingRight = false;
}
}
public void OnRun(InputAction.CallbackContext context)
{
if (context.started)
{
IsRunning = true;
}
else if (context.canceled)
{
IsRunning = false;
}
}
public void OnJump(InputAction.CallbackContext context)
{
// To Do Check if alive as well
if (context.started && coyoteTimeCounter > 0 && CanMove)
{
animator.SetTrigger(AnimationStrings.jumpTrigger);
rb.velocity = new Vector2(rb.velocity.x, jumpImpulse);
}
if (context.canceled && rb.velocity.y > 0f)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
coyoteTimeCounter = 0f;
}
}
public void OnAttack(InputAction.CallbackContext context)
{
if(context.started && touchingDirections.IsGrounded)
{
animator.SetTrigger(AnimationStrings.attackTrigger);
}
}
public void OnHit(int damage, Vector2 knockback)
{
rb.velocity = new Vector2(knockback.x, rb.velocity.y + knockback.y);
}
}