Looking for a Work Around

Hi Guys,

I’m using a script for collectibles necessary to progress to the next level. The problem is that when the player dies and respawns, the number of collectibles necessary doubles but the number of collectibles on the level stays the same. From my understanding, when a new instance of the player is instantiated, the collectibles are as well. I need some brainstorming to find a workaround. It’s a two part script with one script on the object that marks it as a collectible and the other part on the Event System that counts the collectibles.

Script on the objects:

using UnityEngine;

public class ObjectstoCollect : MonoBehaviour
{
    public static int objects = 0;
    //Use for initialization
    void Awake()
    {
        objects++;
    }

    void OnTriggerEnter(Collider player)
    {
        if (player.gameObject.tag == "Player")
            objects--;
        gameObject.SetActive(false);
    }
}

Script on the Event System

using UnityEngine;
using UnityEngine.UI;

public class CountObjects : MonoBehaviour {
    public string nextLevel;
    public GameObject objToDestroy;
    GameObject objUI;

    // Use this for initialization
    void Start () {
        objUI = GameObject.Find("ObjectNum");
       
    }
   
    // Update is called once per frame
    void Update () {
        objUI.GetComponent<Text>().text = ObjectstoCollect.objects.ToString();
        if (ObjectstoCollect.objects == 0)
        {
            Destroy(objToDestroy);
            objUI.GetComponent<Text>().text = "Find The Exit";
        }
       
    }
}

Since your objects variable is static, restarting the scene will always keep the remaining value. (or if the objects are destroyed and recreated). So, you either have to reset the value of objects. Or you make a manager type class that handles the list for you. You could simply have a manager script that cleared out the list in awake and have the objects register to the list in start.

There are many ways to do what you want to do. But without knowing more about your setup, it’s hard to say. I had a game where you would collect stuff and I’d simply turn them off when collected. If the player died, they would all be turned back on again and the player was just teleported back to the start. Thus, the reset was simple. Now, I wasn’t registering to a master list, but you could using onenable and ondisable.

Yeah, I’m trying to figure out a way to code a reset in the Awake. I’m also thinking that if I can figure out a different way to reload after the player dies, it might make a difference. I doubt it, but you never know.

Anyway, on my enemy script, I’m just doing a basic SceneManager.LoadScene(“blahblah”);

purge the list/count before you call SceneManager.LoadScene.

Or like was suggested, purge the count on Awake, and count on start:

using UnityEngine;

public class ObjectstoCollect : MonoBehaviour
{
    public static int objects = 0;
    //Use for initialization
    void Awake()
    {
        objects = 0;
    }
  
    void Start()
    {
        objects++;
    }

    void OnTriggerEnter(Collider player)
    {
        if (player.gameObject.tag == "Player")
            objects--;
        gameObject.SetActive(false);
    }
}

Of course this only works if all objects are present at start rather than some being spawned mid scene.

If they spawn mid scene move the Awake code to a ‘SceneStartupScript’ of some sort.

using UnityEngine;

public class ObjectstoCollect : MonoBehaviour
{
    public static int objects = 0;

    void Start()
    {
        objects++;
    }

    void OnTriggerEnter(Collider player)
    {
        if (player.gameObject.tag == "Player")
            objects--;
        gameObject.SetActive(false);
    }
}

public class SceneStartupScript : MonoBehaviour
{
  
    void Awake()
    {
        ObjectstoCollect.objects = 0;
    }
  
}

Put that SceneStartupScript on a GameObject in the scene.

Of course these are all just hack fixes for the fact you’re using a poorly design static global… probably shouldn’t do that.

Turns out there are good reasons why static variables are considered bad.

You can either reset the static variable. Or you can do this without using static. I would strongly suggest moving to a solution without using static.

One simple way to do this would be use another GameObject to keep track of the count. It can have references to the collectibles and count them that way.

Huh… Why did I not think of this? Let’s see if it works.

This worked! It’s such an easy answer for something that’s been kicking my butt for a couple days! Thank you so much!