** I'm trying to double jump mechanic for Unity 2D platformer game. What I want is when the character has finished the double jump and right before it landed, if we hit the any Jump button, the character will still know it is the jump input. The Coyote Jump work just fine but the Buffer Jump is not **
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fox2 : MonoBehaviour {
Rigidbody2D rb;
Animator animator;
//Public Fields
[Range(0, 10f)] public float runSpeed=10f;
[Range(0, 300f)]public float jumpForce=200.0f;
#region private fields
// A small amount of time that player is allowed to jump after leaving a platform
private float coyoteTime = 0.25f;
private float coyoteTimeCounter;
// A small amount of time to detect whether player presses the Jump Buttons or not
private float bufferTime = 0.2f;
private float bufferTimeCounter= 0f;
#endregion
#region SerializeField
[SerializeField] Collider2D headCollider;
[SerializeField] Collider2D crouchingCollider;
[SerializeField] Transform groundCheckCollider;
[SerializeField] Transform ceilingCheckCollider;
[SerializeField] LayerMask groundLayer;
[SerializeField] LayerMask groundLayer2;// High platform
[SerializeField] int totalJumps;
#endregion
#region Variables
int availableJumps;
// Change the current x-axis position of the character
float horizontalValue;
// Change the value of the speed when the player is running
float runSpeedModifier=2f;
// Change the value of the speed when the player is running
float crouchSpeedModifier=0.3f;
// Change the power of the normal jump
float lowJumpForceModifier=0.22f;
// The wide of "groundCheckCollider" will use
float groundCheckRadius=0.5f;
// The wide of "ceilingCheckCollider" will use
float ceilingCheckRadius=0.2f;
// By default, the Fox will facing to the right side of the screen
bool isFacingRight=true;
// If the Fox is on the walking state, he will be changed to running
bool isRunning;
// Check if the Fox is standing on the ground
bool isGrounded;
// Check if the Fox was standing on the ground
bool wasGrounded;
// Check if the Fox is underneath a platform
bool isCeiling;
// Check if the Fox is able to crouch if he is on the ground
bool isCrouching;
bool isJumping;
// the value to indicate if player can do Multiple Jumps or not
bool multipleJumps;
#endregion
// Start is called before the first frame update
void Awake() {
rb=GetComponent<Rigidbody2D>();
animator=GetComponent<Animator>();
}
// Update is called once per frame
// Update will get input from the player
void Update() {
#region Move Input Mechanics
//Walk and Run input
horizontalValue=Input.GetAxisRaw("Horizontal");
if(Input.GetKeyDown(KeyCode.LeftShift))
isRunning=true;
if(Input.GetKeyUp(KeyCode.LeftShift))
isRunning=false;
#endregion
if(isGrounded)
coyoteTimeCounter = coyoteTime;
else coyoteTimeCounter -= Time.deltaTime;
if(availableJumps == 0)
bufferTimeCounter = bufferTime;
else bufferTimeCounter -= Time.deltaTime;
#region Jump Input Mechanics
if(Input.GetButtonDown("Jump"))
Jump();
if(Input.GetButtonUp("Jump") && rb.velocity.y > 0)
lowJump();
#endregion
#region Crouch Input Mechanics
if(Input.GetButtonDown("Crouch"))
isCrouching=true;
else if(Input.GetButtonUp("Crouch"))
isCrouching=false;
#endregion
}
// Check if the character is standing on the ground or not
void GroundCheck() {
wasGrounded = isGrounded;
isGrounded=false;
// Create a collider with the position of GroundCheckCollider (underneath the Fox), Radius: 0.5,
// and only tell the character is on the ground when he standing on the sorted ground layers
Collider2D[] colliders=Physics2D.OverlapCircleAll(groundCheckCollider.position, groundCheckRadius, groundLayer);
// If the colliding area between the GroundCheckCollider and the SortedGroundLayer is above 0,
// the character is on the ground
if(colliders.Length> 0)
{
isGrounded=true;
if(!wasGrounded)
{
availableJumps = totalJumps;
multipleJumps=false;
}
}
// if the Player is not on the ground, play the Jumping animation
// If the player is on the ground, disable the Jumping animation
animator.SetBool("Jumping", !isGrounded);
}
#region Jumping mechanics
// This section will take care of the normal jumps and multiple jumps
void Jump()
{
#region Initial Jumps Mechanics
// If the character is not on the ground and he ism't crouching
// let him do the initial jump
if(!isCrouching && (isGrounded || bufferTimeCounter >= 0f)) {
// Increase the y velocity by the amount of "jumpForce", keep x velocity the same
rb.velocity = Vector2.up * jumpForce;
// After the initial, set the MultipleJumps to true so he can jump multiple times if he wishes to
multipleJumps= true;
// Minus the number of jumps he already do the Initial Jump
availableJumps--;
bufferTimeCounter = 0f;
// Add Jumping animation to the character
animator.SetBool("Jumping", true);
Debug.Log("Initial Jump");
}
#endregion
else
{
#region Coyote Jumps Mechanics
// But if the character is on the edge of a platform but still want to jump,
// change the initial jump into the coyote ones.
if(!isCrouching && coyoteTimeCounter> 0f)
{
// Increase the y velocity by the amount of "jumpForce", keep x velocity the same
rb.velocity = Vector2.up * jumpForce;
// The same with the Initial Jump
multipleJumps = true;
// Minus the number of jumps he already do the Coyote Jump as the Initial ones.
availableJumps--;
// Add Jumping animation to the character
animator.SetBool("Jumping", true);
Debug.Log("Coyote Jump");
}
#endregion
#region Multiple Jump Mechanics
// After the Initial Jump or the Coyote Jump,
// the character will be able to perform the Multiple Jump
// as long as the number of the availableJumps is greater than 0
else if(!isCrouching && availableJumps> 0 && multipleJumps)
{
// Increase the y velocity by the amount of "jumpForce", keep x velocity the same
rb.velocity = Vector2.up * jumpForce;
// Keep minus the number of availableJumps while he do the Multiple Jumps
availableJumps--;
// Add Jumping animation to the character
animator.SetBool("Jumping", true);
Debug.Log("Multiple Jump");
}
#endregion
}
}
// This section will take care of the Low Jump
void lowJump() {
// "Lower Jump" or "Jump Cut" Mechanics
// if the character is on midair and we released the Jump button, reduce the velocity of y axis
// Decrease y velocity by the amount of "jumpForce", keep x velocity the same
rb.velocity = Vector2.up * jumpForce * lowJumpForceModifier;
// Add Jumping animation to the character
animator.SetBool("Jumping", true);
}
#endregion
// FixedUpdate will apply the input to the game character regardless of the speed of the game
void FixedUpdate() {
GroundCheck();
Flip(horizontalValue);
Move(horizontalValue, isRunning, isCrouching);
// Get the current value of Y velocity in order to add jump animation base on the velocity
animator.SetFloat("YVelocity", rb.velocity.y);
}
void Move(float direction, bool runFlag, bool crouchFlag) {
#region Crouching Mechanics
// if the character is standing on the ground
if(isGrounded==true) {
// if the character is not crouching,
if(!crouchFlag)
{
// Check if the character is underneath a surface
if(Physics2D.OverlapCircle(ceilingCheckCollider.position, ceilingCheckRadius, groundLayer2))
{
// If yes, switch to crouching mode
crouchFlag = true;
}
}
// If the character is crouching, disable the headCollider.
// If not, reactive it
headCollider.enabled = !crouchFlag;
}
// Add the crouching animation to the character
animator.SetBool("Crouch", crouchFlag);
#endregion
#region Walking and Running Mechanics
// Push the character to the left or right depending on the input
// Character's normal speed
float walk=direction * runSpeed * Time.fixedDeltaTime * 100;
// If the character want to run and he is not crouching, increase the walking speed
if(runFlag==true && crouchFlag==false) walk *=runSpeedModifier;
// If the character is crouching, decrease the walking speed
if(crouchFlag==true) walk *=crouchSpeedModifier;
rb.velocity=new Vector2(walk, rb.velocity.y); //Change x velocity = "walk", keep y velocity the same
// Adding the Running Animation to the Character
animator.SetFloat("XVelocity", Mathf.Abs(rb.velocity.x));
#endregion
}
// Rotate the character base on the moving inputs
void Flip(float direction) {
// If the player is looking to right and want to turn left (clicked left)
if (isFacingRight && direction < 0) {
transform.localScale=new Vector3(-1, 1, 1);
isFacingRight=false;
}
// If the player is looking to left and want to turn right (clicked right)
if ( !isFacingRight && direction > 0) {
transform.localScale=new Vector3(1, 1, 1);
isFacingRight=true;
}
}
}
I would start with something like that
void GroundCheck(){
[...]
if(!wasGrounded)
{
availableJumps = totalJumps;
multipleJumps=false;
if(Time.time - _lastJumpButtonTime < 0.1f){
Jump();
}
}
[...]
}
void Jump(){
_lastJumpButtonTime = Time.time;
[...]
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.