Saving healthPoints and isDead creates weird behavior

So I decide to create a struct to save health points and the death state of the enemies. But then weird behavior appear. I test by killing one enemy, then save, and killing another one and load the save game. What happens next is:

  • 1st enemy still dead
  • 2nd enemy, suppose to be still alive, now still alive but in dead posture, he still chasing me around while lying dead but cannot hit me :joy:

If I then unplay and play again, then:

  • 1st enemy still dead, but stand still and doing nothing, he died in living posture :joy:
  • 2nd enemy is alive and behaves normally as expected

It must be in the way that heathPoints, Die() and other methods and classes interact with each other. Is there anyway in Health class alone can signify a character should be dead (based on isDead and healthPoints) when save or scene reload

Here is my code where I implement the struct

[System.Serializable]
struct HealthSaveData
{
    public float healthPoints;
    public bool isDead;
}

public object CaptureState()
{            
    HealthSaveData data = new HealthSaveData();
    data.healthPoints = healthPoints; 
    data.isDead = isDead;
    return data;

    //return healthPoints;            
}

public void RestoreState(object state)
{            
    HealthSaveData data = (HealthSaveData)state;
    healthPoints = data.healthPoints;
    isDead = data.isDead;

    //healthPoints = (float)state;
   
    if (healthPoints == 0)
    {
        Die();
    }
}

Comparing a float like this can lead to unpredictable results. Occasionally you can go float answer = 5.5f - 5.5f and you can get 0.00000000001 which is not == 0. I find it best to use:
if (Mathf.Approximately(healthPoints, 0f) )

See if that helps.

1 Like

The L)oad key as presented doesn’t really take into account a scene that already has a state. Ultimately, in the final course in the series, we’ll always be loading the scene from a menu which ensures that all characters start from alive, and then death is determined by the hitpoints…

This can be fixed by changing L)oad’s method in SavingWrapper to

StartCoroutine(LoadLastScene());

(Note, if you have’t gotten to that part, implement it when you get to LoadLastScene(); in the lessons.)

For now, here’s another trick. In Health.RestoreState, if the character is alive, add this:

GetComponent<Animator>().Rebind();

This will reset the animator and the dead will come back to life (unless they were dead before the save, don’t ressurect those who were dead before the save, as this is not a Zombie RPG).

1 Like

Thank you Michael, though it did not solve the problem but now I know the possibility that some float did not get to integer and mess up everything when I use (healthPoints == 0)

Thank you Brian, that solve the problems but I undo it back and will follow up to the final course as your advice, then change everything as a whole afterward if needed.
Thanks a lot!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.