Fix NullReferenceExceptions by ensuring providers are initialized in Dead state

This commit is contained in:
MaddoScientisto 2026-02-28 10:42:08 +01:00
commit 8492c3644b

View file

@ -35,6 +35,12 @@ public partial class Dead : BaseState<PlayerState, CharacterBody3D>
_animationProvider ??= StateMachine.GetModule<PlayerAnimationProvider3D>();
// The input provider was not initialized after the FSM refactor which caused
// a NullReferenceException in ProcessState when accessing it. Try to obtain
// it from the state machine modules as well. If it's still null, ProcessState
// will early-return to avoid throwing.
_inputProvider ??= StateMachine.GetModule<InputProvider>();
}
public override void EnterState()
@ -42,8 +48,17 @@ public partial class Dead : BaseState<PlayerState, CharacterBody3D>
base.EnterState();
//MainObject.Hide();
_animationProvider.PlayDeathAnimation();
// Play death animation if provider is available
_animationProvider?.PlayDeathAnimation();
// If we don't have a motivation provider, assume game over and log the problem.
if (_motivationProvider is null)
{
GD.PrintErr("[Dead] MotivationProvider not found - defaulting to Game Over");
Hud.Instance.ShowGameOver();
_isGameOver = true;
return;
}
if (_motivationProvider.CurrentResource < 100f)
{
@ -70,6 +85,14 @@ public partial class Dead : BaseState<PlayerState, CharacterBody3D>
{
base.ProcessState(delta);
// If input provider is missing, bail out to avoid NullReferenceException.
if (_inputProvider is null)
{
// Log once to help debugging, but avoid spamming the console every frame.
GD.PrintErr("[Dead] InputProvider not available - input ignored in Dead state.");
return;
}
if (_inputProvider.GetShootJustPressed())
{
if (_isGameOver)
@ -88,13 +111,29 @@ public partial class Dead : BaseState<PlayerState, CharacterBody3D>
public void Respawn()
{
MainObject.GlobalPosition = GameController.Instance.LastCheckPointPosition;
_healthProvider.FillResource();
if (_healthProvider is null)
{
GD.PrintErr("[Dead] HealthProvider not found - cannot refill health on respawn");
}
else
{
_healthProvider.FillResource();
}
PoolingManager.Instance.ClearBullets();
_motivationProvider.CurrentResource -= 100f;
if (_motivationProvider.CurrentResource <= 1f)
if (_motivationProvider is null)
{
_motivationProvider.CurrentResource = 1f;
GD.PrintErr("[Dead] MotivationProvider not found - skipping motivation deduction");
}
else
{
_motivationProvider.CurrentResource -= 100f;
if (_motivationProvider.CurrentResource <= 1f)
{
_motivationProvider.CurrentResource = 1f;
}
}
ChangeState(PlayerState.Active);