Quantcast
Channel: Questions in topic: "state machine"
Viewing all articles
Browse latest Browse all 42

Player velocity becomes 0 for 1 frame during State Machine transition

$
0
0
Hello!
I am currently making a game with a character that can run sideways and jump (for now), and I've already ran into a peculiar issue that I am not sure how to fix.
I am using a class-based State Machine to handle state transitions, and the player's velocity stutters slightly when changing states. If I debug this, I can clearly see that for 1-2 frames, when the player changes states, the player's X velocity is set to 0.
I suspect this is caused by CurrentState.Exit() and CurrentState = state in the StateMachine script, essentially leaving the player stateless for a frame and thus input is not being read. But even if my assumption is correct, I would have no idea how to handle this without violating the state pattern.
Any help is greatly appreciated, thank you in advance!
Relevant code:
public class StateMachine { public State CurrentState { get; private set; } public void Initialize(State state) { CurrentState = state; state.Enter(); } public void ChangeState(State state) { CurrentState.Exit(); CurrentState = state; state.Enter(); } } public abstract class State { protected Player Player; protected StateMachine SM; protected State(Player player, StateMachine sm) { Player = player; SM = sm; } public virtual void Enter() { //Debug.Log($"Entering state: {this}"); } public virtual void HandleInput() { } public virtual void LogicUpdate() { } public virtual void PhysicsUpdate() { } public virtual void LateUpdate() { } public virtual void Exit() { } } public class PlayerState : State { public float HorizontalInput; public PlayerState(Player player, StateMachine stateMachine) : base(player, stateMachine) { } public override void HandleInput() { base.HandleInput(); HorizontalInput = Input.GetAxisRaw(Constants.Axes.Horizontal); } public override void PhysicsUpdate() { base.PhysicsUpdate(); Player.rb.velocity = new Vector2(HorizontalInput * Player.RunSpeed, Player.rb.velocity.y); } } public class AirState : PlayerState { public bool JumpButtonHeld; public float JumpQueueDuration; public AirState(Player player, StateMachine stateMachine) : base(player, stateMachine) { } public override void Enter() { base.Enter(); Player.Grounded = false; JumpQueueDuration = 0f; } public override void LogicUpdate() { base.LogicUpdate(); JumpButtonHeld = Input.GetButton(Constants.Buttons.Jump); if (JumpButtonHeld) JumpQueueDuration += Time.deltaTime; else JumpQueueDuration = 0f; bool queue = (JumpQueueDuration > 0f) && (JumpQueueDuration <= Constants.Game.ActionQueueDuration); if (Player.Grounded) { if (queue) SM.ChangeState(Player.Jumping); else SM.ChangeState(Player.Standing); } } public override void LateUpdate() { base.LateUpdate(); if (Player.rb.velocity.y < -Player.MaxFallSpeed) Player.rb.velocity = new Vector2(Player.rb.velocity.x, -Player.MaxFallSpeed); } } public class JumpingState : AirState { public bool Ascending; public float JumpStart; public float JumpHeight; public JumpingState(Player player, StateMachine stateMachine) : base(player, stateMachine) { } public override void Enter() { base.Enter(); Ascending = true; JumpStart = Player.transform.position.y; JumpHeight = 0f; } public override void Exit() { base.Exit(); } public override void HandleInput() { base.HandleInput(); } public override void LogicUpdate() { base.LogicUpdate(); JumpHeight = Player.transform.position.y - JumpStart; if (Ascending && !JumpButtonHeld) EndJumpEarly(); if (!Ascending && Player.rb.velocity.y < 0f) SM.ChangeState(Player.Falling); } public override void PhysicsUpdate() { base.PhysicsUpdate(); if (Ascending) { Ascend(); } } public override void LateUpdate() { base.LateUpdate(); } void Ascend() { if (JumpHeight <= Player.MaxJumpHeight) Player.rb.velocity = new Vector2(Player.rb.velocity.x, Player.JumpSpeed); else Ascending = false; } private void EndJumpEarly() { if (Player.rb.velocity.y > 0f && JumpHeight >= Player.MinJumpHeight) { Player.rb.velocity = new Vector2(Player.rb.velocity.x, 0f); Ascending = false; } } }

Viewing all articles
Browse latest Browse all 42

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>