Lives not reducing after initial decrease

I am making a simple platformer. I have made the game such that there is a trigger at the bottom of each level tagged levelRestart and whenever player triggers that, i run the levelRestart() function

Now i created a new script called level manager and i added a few functions like takeLife() and giveLife().

using UnityEngine;

public class LivesManagementScript : MonoBehaviour
{ 
    public int lives = 3;

    public void takeLife()
    {
        lives--;
        Debug.Log("You have " + lives + " lives left");
    }

    public void giveLife()
    {
        lives++;
    }

    public void giveAllLives()
    {
        lives = 3;
    }
}

I tried referencing these to player script so that i will reduce lives as soon as player collides with level restart layer and will load game over scene if lives == 0

using UnityEngine;

public class BlokScript : MonoBehaviour
{
    public SceneManagementScript scene;
    public LivesManagementScript lives;

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "levelRestart")
        {
            lives.takeLife();
            scene.RestartLevel();

            if (lives.lives == 0)
            {
                scene.gameOverScreen();
            }
        }

        else if (collision.gameObject.tag == "loadNextLevel")
        {
            scene.LoadNextLevel();
        }
    }
}

But this is not working cause the lives get reduced to 2 but not further from there

Please solve this problem asap

I think the problem might be because it is detecting collisions/triggers only once with each object but no idea on how to fix that

I don’t see a problem here. The level should restart when the player hits the collider meaning it will no longer be in the collider. The next time they hit the collider it will trigger again. When you restart the level, does the lives get reset to 3? Because this will be a problem. You will never get to 0 if you keep resetting the lives when the scene reloads.


Edit
Yeah, I see it now. Your script reloads with the scene, so the lives are reset to 3. You need to persist the lives across scene loads. Two quick ways would be to

  • Store the lives in PlayerPrefs every time it changes and then manage it that way, or
  • Put the LivesManagementScript script in DontDestroyOnLoad while the scene is running, and then just kill it on game over.

For the first option, add this to the LivesManagementScript

using UnityEngine;

public class LivesManagementScript : MonoBehaviour
{ 
    public int lives = 3;

    void Awake()
    {
        LoadLives();
    }

    void OnDestroy()
    {
        SaveLives();
    }

    public void takeLife()
    {
        lives--;
        Debug.Log("You have " + lives + " lives left");
    }

    public void giveLife()
    {
        lives++;
    }

    public void giveAllLives()
    {
        lives = 3;
    }

    private void SaveLives()
    {
        PlayerPrefs.SetInt(nameof(lives), lives);
    }
    private void LoadLives()
    {
        lives = PlayerPrefs.GetInt(nameof(lives), 3);
    }
}

For the second option - which is the one I’d go with - just put the script in DDoL

using UnityEngine;

public class LivesManagementScript : MonoBehaviour
{ 
    public int lives = 3;

    void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }

    public void takeLife()
    {
        lives--;
        Debug.Log("You have " + lives + " lives left");
    }

    public void giveLife()
    {
        lives++;
    }

    public void giveAllLives()
    {
        lives = 3;
    }
}

When you are ready to move on - like going to the game over screen, you have to remember to destroy it again

// probably the SceneManagementScript
public LivesManagementScript lives;
public void gameOverScene()
{
    Destroy(lives.gameObject);
    SceneManagement.LoadScene("gameOverScene");
}

These methods will also help presist the lives across levels

Yep this makes a lot of sense. I will try this. Thanks

Any specific reason to use awake btw?
We can use start too right?

Ok frick it suddenly started working

I made all references private and found them on scene using FindObjectOfType<> function

Maybe i messed up because of keeping all script references as public

Thank you sooo muchhhhhh :relaxed: :relaxed:

1 Like

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

Privacy & Terms