ScoreKeeper - Singleton

Not quite sure what’s happening with my code, but when I follow the lecture to the letter I don’t get a score on my game over screen; however if I don’t change the LevelManager and as long as I don’t have an instance of the ScoreKeeper on the MainMenu screen, everything works perfectly with score and reset.

As its working I’m not planning to do anything about it currently, but I’d sure like to have some guesses why?

My best guess. You think your “I follow the lecture to the letter” variable is set to true where it’s probably false.

Without details, that’s my best guess.

1 Like

It was a good place to start looking – I figured out what was happening, though I’m still not sure why it was happening.

//static ScoreKeeper instance;


private void Awake()
{
    ManageSingleton();
}

private void ManageSingleton()
{
    //if(instance != null)
    int instanceCount = FindObjectsOfType(GetType()).Length;
    if (instanceCount > 1)
    {
        gameObject.SetActive(false);
        Destroy(gameObject);
    }
    {
        //instance = this;
        DontDestroyOnLoad(gameObject);
    }
    
}

Basically, using the static version of the singleton, extra instances of objects weren’t being destroyed all the time. Testing with Debug.Logs the new instances were shown being triggered and destroyed (meaning no new object being created) every second time an object was created (Actually every second time minus 1).

If I do it without the static and based on the count method (like I originally stuck to with the AudioPlayer) everything gets destroyed just fine and the Debug. Log is triggered every time.

Obviously having multiple of these in the hierarchy just bad process, more of random luck that at first I was having the correct scorekeeper link up with the level manager since I wasn’t really aware.

The question still remains for me on why the static singleton version wasn’t working as I expected? (You can see the implementation commented out in the code above. I would really hope its something simple like a bool incorrectly put in place.)

I don’t know what your static version is and what you’re doing to get it all wrong, so it’s hard to know. It could also be due to how statics are handled in regards to multiple scenes (the data is owned by the class, not the instance) if you don’t do the DontDestroyOnLoad.

Why do you think that? It’s really not that much of an issue. If it’s only searching for objects when the scene loads, it’s often how you should be doing it. Even if you have hundreds of these kinds of calls. Regardless of what some people say, don’t worry about expensive calls like this in awake/start. Just be careful if you’re throwing them in something like Update or a very frequently used method. On top of that, Unity caches a lot of these things, so they’re not as expensive as they used to be.

Unity is a component based system. To keep your code reusable and single responsibility Unity forces you to do a lot of things like this instead of using a lot of best practices OOP methodologies.

Thanks. I was more worried about possibly relying on something that might act differently because their were several of these in the hierarchy and only one of them might be called. What was happening in my occurrence was that of the half of the ScoreKeeper objects that weren’t destroyed on awake, only one of them would hold the actual score – every other instance had a score variable of zero (before then resetting after the game over) and the level manager wasn’t being consistent about which value it picked (though maybe from a computer’s perspective – I’m not sure which ScoreKeeper loads first in the scene).

(Now that I think of it does this even make sense for static classes? Shouldn’t they all be updated the same way? Just a part of the learning curve for me.)

I don’t rally have any more code to show that relates to the static variable.

That depends. If you’re thinking the same thing as I’m thinking, then yes it does. If you’re thinking something different, then maybe not. It’s hard to tell what you mean.

I don’t even see where you do anything with a static in your code… with the exception of comment it out.

But yes, statics are updated in the same way, but they’re not reset as you might expect. It’s the second part that causes issues for some people.

Does GetType() even do what’s expected without a reference variable in there?

I’m using get type and counting the number of existing objects of the type in the scene as an alternative to the static singleton pattern – just given this is the method from the video that worked consistently for me.

Changing to use the comment outs to use static method, my code looks like this (all contained within the ScoreKeeper class):

static ScoreKeeper instance;


private void Awake()
{
    ManageSingleton();
}

private void ManageSingleton()
{
   
    if(instance != null)
    //int instanceCount = FindObjectsOfType(GetType()).Length;
    //if (instanceCount > 1)
    {
      
        gameObject.SetActive(false);
        Destroy(gameObject);
    }
    {
        
        instance = this;
        DontDestroyOnLoad(gameObject);
    }
    
}

Which now actually explains what when wrong – If you look between the if statements set of brackets I’m missing an else, so the instance setting wasn’t working correctly. If I understand correctly this would mean the code always tried to set an instance which would explain why sometimes on load of a new scene the static would be set to null and new objects wouldn’t be destroyed, I think.

Anyways it really did turn out being something like that. Thanks for taking the time to respond.

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

Privacy & Terms