AirState sometimes moves to IdleState

Link: Assets - Google Drive

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

public class Player_airState : PlayerState
{
// Start is called before the first frame update
public Player_airState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
{
}

public override void Enter()
{
base.Enter();
Debug.Log(“air”);
}

public override void Update()
{
base.Update();
if (player.IsGroundDetected()){//return true even it is in air
stateMachine.changeState(player.idleState);
}

}

public override void Exit()
{
base.Exit();
}
}

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Player : MonoBehaviour
{
[Header(“Move Info”)]
public float moveSpeed = 4f;
public float jumpHeight = 12f;
public bool Ground;

[Header(“Collision Info”)]
[SerializeField] public LayerMask whatIsGround;
[SerializeField] public LayerMask whatIsWall;

[SerializeField] public Transform groundCheck;
[SerializeField] public float groundCheckRadius;
[SerializeField] public Transform wallCheck;
[SerializeField] public float wallCheckRadius;

#region Components
public Animator anim{ get; private set; }
public Rigidbody2D rb{ get; private set; }
#endregion

#region States
public PlayerStateMachine stateMachine{ get; private set; }
public Player_idleState idleState{ get; private set; }
public Player_moveState moveState{ get; private set; }
public Player_groundState groundState{ get; private set; }
public Player_jumpState jumpState{ get; private set; }
public Player_airState airState{ get; private set; }

#endregion

public void Awake()
{
stateMachine = new PlayerStateMachine();

idleState = new Player_idleState(this,stateMachine,“Idle”);
moveState = new Player_moveState(this, stateMachine, “Move”);
jumpState = new Player_jumpState(this, stateMachine, “Jump”);
airState = new Player_airState(this, stateMachine, “Jump”);

}
// Start is called before the first frame update
void Start()
{
Debug.Log(“Player Started”);
anim = GetComponentInChildren();
rb = GetComponent();
stateMachine.initialize(idleState);
}
public bool IsGroundDetected() => Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckRadius, whatIsGround);
public bool IsWallDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right, wallCheckRadius, whatIsWall);

// Update is called once per frame
void Update()
{
stateMachine.currentState.Update();
}

public void SetVelocity(float _xvelocity, float _yvelocity)
{
rb.velocity = new Vector2(_xvelocity, _yvelocity);
}

private void OnDrawGizmos()
{
Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x+wallCheckRadius, wallCheck.position.y));
Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y-groundCheckRadius));
}
}

Sounds like you wrote a bug! 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.

If you post a code snippet, ALWAYS USE CODE TAGS:

How to use code tags: Using code tags properly

Some more possibly-relevant scribblings about FSM finite state machines:

I suggest never using the term “state machine.” Instead, just think:

  • I have to keep track of some THING(s)
  • That THING might change due to reasons
  • Depending on that THING, my code might act differently

That’s it. That’s all it is. Really!! The classic example is a door:

  • track if it is open or closed
  • if it is open, you could close it
  • if it is closed, you could open it
  • if it is open you could walk through it
  • if it is closed you could bump into it

Wanna make it more complex? Try this:

  • put a latch on one side of the door.
  • handle all the above with the latch locked or open

This is my position on finite state machines (FSMs) and coding with them:

I’m kind of more of a “get it working first” guy.

Ask yourself, “WHY would I use FSM solution XYZ when I just need a variable and a switch statement?”

All generic FSM solutions I have seen do not actually improve the problem space.

Your mileage may vary.

“I strongly suggest to make it as simple as possible. No classes, no interfaces, no needless OOP.” - Zajoman on the Unity3D forums.

1 Like

Also, if you’re going to post code here, please format it. It makes it much less difficult to read – and people will more likely to respond with help — myself included :slight_smile: . There’s a “Code” widget at the top of the message form.