Jump, double jump and high jump errors

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;
        }
    }
}

You can find the answer by debugging, comparing your expectations to what the program is actually doing then making adjustments.

You can also look at working examples, such as mine here:

Coyote Time Jumping and disconnecting input gathering from input processing:

Otherwise… time to start debugging!

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

Remember with Unity the code is only a tiny fraction of the problem space. Everything asset- and scene- wise must also be set up correctly to match the associated code and its assumptions.

If you do need more technical guidance from complete strangers a world away from you, I like this format:

How to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, log output, variable values, and especially any errors you see
  • links to actual Unity3D documentation you used to cross-check your work (CRITICAL!!!)

The purpose of YOU providing links is to make our job easier, while simultaneously showing us that you actually put effort into the process. If you haven’t put effort into finding the documentation, why should we bother putting effort into replying?

If you post code, only post the relevant code and always use the format button above. Do not post photographs of code.

dumping all the code in one script is fine for simple prototypes. when you start creating complex movements, inputs and interaction you need to start using coding patterns. in your case a state pattern is needed so you can focus the code on specific part and have parts of code running only when needed.

the problem is that when you use game engines you are injecting/pushing stuff inside this big complex machine that the engine is. the engine is constantly doing a lot of stuff that you are not aware off so when you add your code it may not do what you were expected the engine to do.

So you either learn the complexity of the engine loop which good luck with that. Or you compartmentalize your code better using code patterns. So just search youtube for a tutorial about state pattern for character controller

I did some debugging and seems like the jump and doublejump does at the same time, the same for the jumping frog the charge, jump and doublejump at the same time. even though it still looks like they both have switched roles. so i will try and see why it’s like this

and the reason for that is because I can’t sent in more links

that one is hurting my head from the complexity