The player jumps correctly when moving left but not when moving right

My player should always do the following animation sequence: idle/run → jump → fall → idle/run, but when he falls while moving to the right, the fall animation will remain even after he’s touched the ground, fading out only when I stop his movement.
I’ve already checked the state machine for my player as well as his script, but everything seems alright.

6193986--679359--Caspar_Bug.gif
Player’s bug.


Player’s state machine.

Player’s script:

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

//Todas as informações do jogador se encontram aqui.
public class Player : Character
{
    //Booleano que determina se o jogador pode pular novamente.
    private bool resetjump = false;
    //Booleano que determina se o jogador está no chão.
    private bool grounded = false;
    //Float para o tempo de espera do jogador após atirar.
    private float nextFireTime = 0;

    //Float para o tempo de recarga da arma do jogador.
    [SerializeField] private float gunCooldown;
    //Float para a altura do pulo do jogador.
    [SerializeField] private float jumpForce;



    //Função de inicialização do jogador:
    protected override void Init()
    {
        //Obtém os comandos de inicialização da classe pai,
        base.Init();
        //Determina que o jogador está virado para a direita,
        facingRight = true;
        //Determina a altura do pulo,
        jumpForce = 14f;
        //A velocidade do movimento e
        moveSpeed = 8f;
        //O tempo de recarga da arma do jogador.
        gunCooldown = 0.35f;
    }



    //Aplica a função de inicialização no primeiro frame do jogo.
    void Start()
    {
        Init();
    }



    //Aguarda os comandos de tiro e movimento do jogador a cada frame.
    void Update()
    {
        Shoot();
        Movement();
    }



    //Função de tiro do jogador:
    public override void Shoot()
    {
        //Se chegar o tempo onde o jogador pode atirar novamente e
        if (Time.time > nextFireTime)
        {
            //Se o botão de tiro for apertado,
            if (Input.GetKeyDown(KeyCode.L))
            {
                //Reproduz a animação de tiro do jogador,
                anim.SetTrigger("shoot");
                //Instancia a bala do jogador e
                Instantiate(shotPrefab, firePoint.position, firePoint.rotation);
                //Acrescenta o tempo de recarga da arma ao float de espera.
                nextFireTime = Time.time + gunCooldown;
            }
        }
    }



    //Função de movimento do jogador:
    void Movement()
    {
        //Obtém o registro horizontal do jogador, que vai de -1 a 1.
        //Valor negativo = movimento para a esquerda.
        //Valor positivo = movimento para a direita.
        float move = Input.GetAxisRaw("Horizontal");
        //Verifica se o jogador está no chão.
        grounded = IsGrounded();

        //Se o registro for positivo e o jogador estiver virado à esquerda,
        if (move > 0 && !facingRight)
        {
            //O jogador dá meia-volta.
            Flip();
        }//Se o registro for negativo e o jogador estiver virado à direita,
        else if (move < 0 && facingRight)
        {
            //O jogador dá meia-volta.
            Flip();
        }

        //Se o botão de pulo for apertado e o jogador estiver no chão,
        if (Input.GetKeyDown(KeyCode.W) && IsGrounded())
        {
            //Aplica no jogador a força vertical do pulo,
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            //Inicia a corrotina de reabilitação de pulo e
            StartCoroutine(resetJumpRoutine());
            //Reproduz a animação de pulo do jogador.
            anim.SetBool("jump", true);
        }

        if (rb.velocity.y < 0)
        {
            anim.SetBool("fall", true);
            anim.SetBool("jump", false);
        }

       

        //
        //tentar aplicar GetKeyUp com mudança na gravidade para mudar intensidade do pulo
        //

        //Por fim, aplica no jogador a força horizontal do movimento e
        rb.velocity = new Vector2(move * moveSpeed, rb.velocity.y);
        //Se o valor do registro não for 0, reproduz a animação de corrida do jogador.
        anim.SetFloat("speed", Mathf.Abs(move));
    }



    //Função que verifica se o jogador está no chão:
    bool IsGrounded()
    {
        //Desenha na cena uma linha de debug partindo do jogador até o chão e
        Debug.DrawRay(transform.position, Vector2.down * 1.4f, Color.green);
        //Gera uma linha de colisão invisível correspondente à linha de debug.
        RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 1.4f, 1 << 9);

        //Se a linha colidir com algo (implicando que o jogador pousou em algo sólido) e
        if (hit.collider != null)
        {
            //Se atualmente o jogador não puder pular,
            if (resetjump == false)
            {
                //Para a reprodução da animação de pulo do jogador e
                anim.SetBool("fall", false);
                //Confirma que o jogador está no chão.
                return true;
            }

        }//Senão, confirma que o jogador não está no chão.
        return false;
    }



    //Corrotina de reabilitação do pulo do jogador:
    IEnumerator resetJumpRoutine()
    {
        //Reabilita o pulo do jogador,
        resetjump = true;
        //Espera um determinado tempo e
        yield return new WaitForSeconds(0.1f);
        //O desabilita novamente.
        resetjump = false;
    }

   

    private void OnCollisionEnter2D(Collision2D other)
    {
        Debug.Log("Trigger called");
        if (other.gameObject.CompareTag("Moving Platform") && !IsGrounded())
        {
            grounded = true;
            transform.parent = other.gameObject.transform;
        }
        if (other.gameObject.CompareTag("Enemy"))
        {
            anim.SetTrigger("damage");
        }
    }
   

    private void OnCollisionExit2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Moving Platform"))
        {
            transform.parent = null;
        }
    }







    public override void TakeDamage()
    {
        //HP--;

    }

   
   

}

I speculate the problem is in your Flip() routine perhaps? I don’t see that code included above…

Ah yes, the Flip() function is from the Character class. Here it is:

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

//Informações genéricas dos personagens presentes na gameplay do jogo:
public abstract class Character : MonoBehaviour
{
    //Todo personagem possui pontos de vida,
    [SerializeField] protected int HP;
    //Velocidade de movimento,
    [SerializeField] protected float moveSpeed;
    //Um tipo de bala para atirar e
    [SerializeField] protected GameObject shotPrefab;
    //Um ponto de onde essa bala será atirada.
    [SerializeField] protected Transform firePoint;

    //Também possui um gerenciador de animação,
    protected Animator anim;
    //Um corpo gravitacional e
    protected Rigidbody2D rb;
    //Um booleano que armazena a direção à qual está virado.
    protected bool facingRight;



    //Função de inicialização do personagem:
    protected virtual void Init()
    {
        //Instancia o gerenciador de animação e
        anim = GetComponent<Animator>();
        //O corpo gravitacional do personagem.
        rb = GetComponent<Rigidbody2D>();
    }



    //Função de reorientação do personagem:
    protected void Flip()
    {
        //Dá ao booleano a direção oposta à anterior e
        facingRight = !facingRight;
        //Vira o personagem horizontalmente em 180° graus.
        transform.Rotate(0f, 180f, 0f);
    }

   

    //Os personagens possuem funções de atirar e
    public abstract void Shoot();
    //Receber dano diferentes entre si,
    public abstract void TakeDamage();
    //Então devem implementá-las separadamente.

}