i am having a problem with something is that ever since I put in the coyote timer, the jumping is getting messed up by that when I do a normal jump, I jump so high, but when I go to the high jump power-up and jump, I jump normally and sometimes the doublejump don’t work, so how do I fix that? (I am not so good at coding so…) I’ve been trying to figure out even for the jump, frog jump, coyote timer distance, and that why double jump deosn’t work sometimes but I can’t to find a solution, do you know the answer?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class Player2D : MonoBehaviour
{
// Serialized fields
[SerializeField] KeyCode interactionButton;
[SerializeField] private List<Transform> _groundCheckPoints = new List<Transform>();
[SerializeField] private Attack _attackObject;
[SerializeField]
private float dropforce = 5f;
[SerializeField]
private float stopTime = 0.5f;
[SerializeField]
private float gravityScale = 1f;
[SerializeField] private Attack _groundPoundAttackObject;
[SerializeField] private int _groundPoundDamage = 1;
public bool canControl = true;
public bool _player2 = false;
public bool canAttack = true;
public checkpoint lastCheckpoint;
public bool isDead = false;
// Non-serialized fields
private bool _isFlipped = false; //en variabel
private bool _isGrounded = false; //Bool - sant eller falsk
private bool _doubleJump = false;
private bool TeleportPlayer = false;
private bool canInteract = true;
private DoorInteraction door;
private bool _isRunning = false;
private float _frogJumpForce = 13.0f;
private float _currentJumpForce = 0.0f;
private float _currentJumpForceMultiplier = 4.0f;
// References
private Rigidbody2D _rb2D;
private Animator _ani;
private AudioSource _as;
private Transform ladder;
// this is messy maybe consider tidying up
private bool _smash = false;
private float _smashTimer = 0.0f;
private bool _doGroundPound = false;
private bool _isGroundPounding = false;
private string _horiz = "Horizontal";
private string _verti = "Vertical";
private string _jump = "Jump";
private string _fire = "Fire";
private string _run = "Run";
private string _groundPound = "GroundPound";
private bool _jumpSuit = false;
private bool _suitOff = false;
private bool isUnderPlatform = false;
private bool isCloseToLadder = false;
private bool hasStartedClimb = false;
public bool IsClimbing
{
get { return hasStartedClimb; }
}
internal bool isGrounded()
{
return _isGrounded;
}
private float _vertical = 0f;
private float climbSpeed = 2.0f;
private bool crouchHeld = false;
private bool climbHeld = false;
private object rigidBody2D;
// Serialized fields
[Header("Movement")]
[SerializeField] private float _walkSpeed = 2.0f;
[SerializeField] private float _runSpeed = 3.0f;
[SerializeField] private float _jumpForce = 5.6f;
[SerializeField] private int _maxJumps = 2;
[SerializeField] private float _maxJumpBuffer = 0.1f;
[SerializeField] private float _maxCoyoteTime = 0.1f;
[SerializeField] private Collider2D _collider;
[SerializeField] private float _rayLength = 0.1f;
[SerializeField] private LayerMask _groundLayer;
// Non-serialzed fields
private Vector2 _moveInput;
private Vector2 _currentVelocity;
private float _verticalVelocity;
private int _jumpsUsed = 0;
[SerializeField] private float _acceleration = 5f;
[SerializeField] private float _deceleration = 5f;
private float _jumpBufferCounter = 0f;
private float _coyoteTimeCounter = 0f;
private const string horizontal = "Horizontal";
private const string vertical = "Vertical";
void Awake()
{
_rb2D = GetComponent<Rigidbody2D>();
_collider = GetComponent<Collider2D>();
pause.OnGamePaused += HandlePause;
}
void OnDestroy()
{
pause.OnGamePaused -= HandlePause;
}
void HandlePause(bool paused)
{
this.enabled = !paused;
}
void Start()
{
_rb2D = GetComponent<Rigidbody2D>();
_collider = GetComponent<Collider2D>();
_ani = GetComponent<Animator>();
_as = GetComponent<AudioSource>();
if (_player2)
{
_horiz += "1";
_verti += "1";
_jump += "1";
_fire += "1";
_run += "1";
_groundPound += "1";
}
if (_rb2D != null)
{
_rb2D.constraints = RigidbodyConstraints2D.FreezeRotation;
}
}
void Update()
{
HandleJump();
InitiateJump();
if (!isDead && !_isGroundPounding)
{
//Climbing
_vertical = Input.GetAxisRaw(_verti);
crouchHeld = (_isGrounded && !isCloseToLadder && Input.GetAxis(_verti) < 0) ? true : false;
climbHeld = (Input.GetAxis(_verti) > 0) ? true : false;
if (climbHeld && isCloseToLadder)
{
if (!hasStartedClimb)
{
hasStartedClimb = true;
_rb2D.velocity = Vector2.zero;
}
}
else
{
if (hasStartedClimb)
{
_ani.SetBool("isClimbing", true);
}
}
}
//Ground Pound
if(Input.GetButtonDown(_groundPound) && !isGrounded() && !hasStartedClimb && !isDead)
{
_doGroundPound = true;
}
if (!isDead)
{
_isGrounded = CheckGrounded();
if (!_isGroundPounding)
{
FlipModel();
Movement();
Attack();
Climbing();
}
GroundPoundFixedUpdate();
}
else
{
_rb2D.velocity = Vector2.zero;
RigidbodyConstraints2D newRB2D = RigidbodyConstraints2D.FreezePositionY;
_rb2D.constraints = newRB2D;
}
if (Input.GetKeyDown(interactionButton) && canInteract)
{
if (door != null)
{
door.TeleportPlayer(transform);
canInteract = false; // Disable interaction
StartCoroutine(InteractionCooldown(2f)); // Start cooldown coroutine
}
}
IEnumerator InteractionCooldown(float cooldownTime)
{
yield return new WaitForSeconds(cooldownTime);
canInteract = true; // Enable interaction after cooldown
}
}
public void StopAttack()
{
canAttack = true;
_attackObject.attack = false;
}
public void JumpSuit(bool putOn)
{
if (!_jumpSuit && putOn)
{
_ani.SetTrigger("Transform");
_jumpSuit = putOn;
_ani.SetBool("JumpSuit", putOn);
}
else if(!putOn)
{
_jumpSuit = putOn;
_ani.SetBool("JumpSuit", putOn);
}
}
public void SuitOff(bool putOn)
{
if (!_suitOff && putOn)
{
_ani.SetTrigger("Transform");
_suitOff = putOn;
_ani.SetBool("SuitOff", putOn);
}
else if (!putOn)
{
_suitOff = putOn;
_ani.SetBool("SuitOff", putOn);
}
}
void FixedUpdate()
{
Movement();
}
private void Climbing()
{
if (hasStartedClimb && (Input.GetAxis(_horiz) > 0 || Input.GetAxis(_horiz) < 0))
{
ResetClimbing();
}
else if (hasStartedClimb && ladder!= null)
{
float height = GetComponent<CapsuleCollider2D>().size.y + GetComponent<CapsuleCollider2D>().offset.y;
float topHandlerY = Half(ladder.GetComponent<LadderHandlers>().topHandler.position.y + height);
float bottomHandlerY = Half(ladder.GetComponent<LadderHandlers>().bottomHandler.position.y);
float transformY = Half(transform.position.y);
float transformVY = transformY + _vertical;
if (transformVY > topHandlerY || transformVY < bottomHandlerY)
{
ResetClimbing();
}
else if (transformY <= topHandlerY && transformY >= bottomHandlerY)
{
_rb2D.bodyType = RigidbodyType2D.Kinematic;
if (!transform.position.x.Equals(ladder.transform.position.x))
{
transform.position = new Vector3(ladder.transform.position.x, transform.position.y, transform.position.z);
}
_ani.SetBool("isClimbing", true);
_ani.SetFloat("ClimbSpeed", _vertical);
Vector3 forwardDirection = new Vector3(0, transformVY, 0).normalized;
Vector3 newPos = Vector3.zero;
if (_vertical < 0)
{
newPos = transform.position - (forwardDirection * Time.fixedDeltaTime * climbSpeed);
}
else if (_vertical > 0)
{
newPos = transform.position + (forwardDirection * Time.fixedDeltaTime * climbSpeed);
}
if (newPos != Vector3.zero)
{
_rb2D.MovePosition(newPos);
}
}
}
else if (hasStartedClimb && ladder == null)
{
ResetClimbing();
}
}
public static float Half(float value)
{
return Mathf.Floor(value) + 0.5f;
}
private void ResetClimbing()
{
if (hasStartedClimb)
{
_ani.SetBool("isClimbing", false);
hasStartedClimb = false;
_rb2D.bodyType = RigidbodyType2D.Dynamic;
//transform.position = new Vector3(transform.position.x, Half(transform.position.y), transform.position.z);
}
}
private void Movement()
{
_moveInput = new Vector2(Input.GetAxisRaw(horizontal), Input.GetAxisRaw(vertical));
_moveInput.Normalize();
Vector2 targetVelocity = Vector2.zero;
float speed = 0f;
if (_moveInput != Vector2.zero)
{
// speed = useGUILayout ur sprint key here ? _runSpeed : _walkSpeed;
speed = _walkSpeed;
targetVelocity = _moveInput * speed;
_currentVelocity = Vector2.Lerp(_currentVelocity, targetVelocity, _acceleration * Time.deltaTime);
}
else
{
_currentVelocity = Vector2.Lerp(_currentVelocity, Vector2.zero, _deceleration * Time.deltaTime);
}
_currentVelocity.y = _rb2D.velocity.y;
_rb2D.velocity = _currentVelocity;
if (canControl)
{
if (!_jumpSuit)
{
PreformJump();
}
else
{
FrogJump();
}
Walking();
}
}
void InitiateJump()
{
if (_jumpBufferCounter > 0f && _coyoteTimeCounter > 0f)
{
PreformJump();
}
else if (_jumpBufferCounter > 0f && _jumpsUsed < _maxJumps)
{
PreformJump();
}
}
public void InputJumpWater()
{
PreformJump();
}
void PreformJump()
{
if (canControl)
{
if (Input.GetButtonUp(_jump) && _isGrounded && _rb2D.velocity.y < 0.01f)
{
_verticalVelocity = Mathf.Sqrt(_jumpForce * -2f * Physics2D.gravity.y);
_rb2D.velocity = new Vector2(_rb2D.velocity.x, _verticalVelocity);
_ani.SetBool("Jump", true);
_as.Play();
_isGrounded = false;
_jumpBufferCounter = 0;
_coyoteTimeCounter = 0;
}
else if (Input.GetButtonUp(_jump) && !_isGrounded && _doubleJump)
{
_doubleJump = false;
_verticalVelocity = Mathf.Sqrt(_jumpForce * -2f * Physics2D.gravity.y);
_rb2D.velocity = new Vector2(_rb2D.velocity.x, _verticalVelocity);
_ani.SetBool("Jump", true);
_as.Play();
}
}
}
void HandleJump()
{
if (Input.GetButtonUp(_jump) && _isGrounded && _rb2D.velocity.y < 0.01f)
{
_jumpsUsed++;
_jumpBufferCounter = _maxJumpBuffer;
}
_jumpBufferCounter -= Time.deltaTime;
if (_jumpBufferCounter <= 0f)
{
_jumpBufferCounter = 0f;
}
if (_isGrounded)
{
_jumpsUsed = 0;
_coyoteTimeCounter = _maxCoyoteTime;
}
else
{
_coyoteTimeCounter -= Time.deltaTime;
if (_coyoteTimeCounter <= 0f)
{
_coyoteTimeCounter = 0f;
}
}
}
private void FrogJump()
{
if (Input.GetButton(_jump) && _isGrounded)
{
_jumpBufferCounter = 0;
_coyoteTimeCounter = 0;
_currentJumpForce += (Time.deltaTime * _currentJumpForceMultiplier);
_currentJumpForce = Mathf.Clamp(_currentJumpForce, _jumpForce, _frogJumpForce);
_ani.SetBool("Jump", true);
_ani.SetFloat("JumpPower", (2 *_currentJumpForce)/ _frogJumpForce);
_rb2D.constraints = RigidbodyConstraints2D.FreezePositionX | RigidbodyConstraints2D.FreezeRotation;
}
if (Input.GetButtonUp(_jump) && _isGrounded && _rb2D.velocity.y < 0.01f)
{
_jumpBufferCounter = 0;
_coyoteTimeCounter = 0;
_ani.SetBool("Jump", false);
_rb2D.velocity = new Vector2(_rb2D.velocity.x, 0.0f);
_rb2D.AddForce(new Vector2(0.0f, _currentJumpForce), ForceMode2D.Impulse);
_currentJumpForce = 0.0f;
_ani.SetTrigger("FrogJump");
_as.Play();
_isGrounded = false;
_rb2D.constraints = RigidbodyConstraints2D.None | RigidbodyConstraints2D.FreezeRotation;
}
else if (Input.GetButtonUp(_jump) && !_isGrounded && _doubleJump)
{
_ani.SetBool("Jump", false);
_doubleJump = false;
_rb2D.velocity = new Vector2(_rb2D.velocity.x, 0.0f);
_rb2D.AddForce(new Vector2(0.0f, _jumpForce), ForceMode2D.Impulse);
_ani.SetTrigger("FrogJump");
_as.Play();
}
}
private void Walking()
{
if (canControl)
{
if (Input.GetAxisRaw(_horiz) > 0.1f || Input.GetAxisRaw(_horiz) < -0.1f)
{
_ani.SetBool("walking", true);
_isRunning = Input.GetButton(_run);
}
else
{
_ani.SetBool("walking", false);
_isRunning = false;
}
if (_isRunning)
{
_rb2D.velocity = new Vector2(Input.GetAxis(_horiz) * _runSpeed, _rb2D.velocity.y);
_ani.SetBool("isRunning", true);
}
else
{
_rb2D.velocity = new Vector2(Input.GetAxis(_horiz) * _walkSpeed, _rb2D.velocity.y);
_ani.SetBool("isRunning", false);
}
}
}
private bool CheckGrounded()
{
for (int i = 0; i < _groundCheckPoints.Count; i++)
{
Vector2 boxCastOrigin = new Vector2(_collider.bounds.center.x, _collider.bounds.min.y);
Vector2 boxCastSize = new Vector2(_collider.bounds.size.x, _rayLength);
RaycastHit2D hit = Physics2D.BoxCast(boxCastOrigin, boxCastSize, 0f, Vector2.down, _rayLength, _groundLayer);
if (hit.collider != null)
{
_isGrounded = true;
_ani.SetBool("isGrounded", true);
_doubleJump = true;
return true;
}
else
{
_isGrounded = false;
}
}
_ani.SetBool("isGrounded", false);
return false;
}
//GetComponent<SpriteRenderer>().color = _notGrounded;
private void FlipModel()
{
if( (Input.GetAxisRaw(_horiz) > 0 && _isFlipped)
|| (Input.GetAxisRaw(_horiz) < 0 && !_isFlipped)
)
{
_isFlipped = !_isFlipped;
Vector3 scale = transform.localScale;
scale.x *= -1;
transform.localScale = scale;
}
}
private void Attack()
{
if (Input.GetButton(_fire) && canAttack)
{
_attackObject.attack = true;
canAttack = !canAttack;
_ani.SetBool("isAttacking", true);
}
}
#region GroundPound
private void GroundPoundFixedUpdate()
{
if (_doGroundPound && !_isGroundPounding)
{
GroundPoundAttack();
}
if (_smash)
{
DropAndSmash();
}
_doGroundPound = false;
}
private void GroundPoundAttack()
{
_isGroundPounding = true;
//cc.enabled = false;
StopAndSpin();
_smash = true;
_smashTimer = stopTime;
}
private void StopAndSpin()
{
ClearForces();
_rb2D.gravityScale = 0;
_ani.SetTrigger("isSpinning");
}
private void DropAndSmash()
{
_smashTimer -= Time.deltaTime;
if (_smashTimer < 0)
{
_rb2D.AddForce(Vector2.down * dropforce, ForceMode2D.Impulse);
_smash = false;
_ani.SetBool("isDropping", true);
_attackObject.attack = true;
}
}
private void CompleteGroundPound()
{
_rb2D.gravityScale = gravityScale;
//cc.enabled = true;
_isGroundPounding = false;
_ani.SetBool("isDropping", false);
_attackObject.attack = false;
}
public bool IsGroundPounding()
{
return _isGroundPounding;
}
private void ClearForces()
{
_rb2D.velocity = Vector2.zero;
_rb2D.angularVelocity = 0;
}
#endregion
/*private void UpAttack()
{
if (Input.GetButton("W") && canAttack)
{
_attackObject.attack = true;
canAttack = !canAttack;
_ani.SetBool("isUpAttacking", true);
}
}*/
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
if (_isGroundPounding)
{
collision.gameObject.GetComponent<HitPoints>().TakeDamage(_groundPoundDamage);
}
else
{
GetComponent<HitPoints>().TakeDamage(1);
}
}
if (collision.contacts[0].normal.y >= 0.5f)
{
CompleteGroundPound();
}
}
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.gameObject.tag.Equals("Ladder"))
{
isCloseToLadder = true;
ladder = collision.transform;
}
if (collision.TryGetComponent(out DoorInteraction d))
{
door = d;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag.Equals("Ladder"))
{
isCloseToLadder = false;
ladder = null;
}
if (collision.TryGetComponent(out DoorInteraction _))
{
door = null;
}
}
}