void Start() timing is waging war with one of my gameObjects

I know it’s a little bit of a vague Title I put there, but I really could not think of another way to word it haha.

Anyways: I have a List that is supposed to get initialized and filled in the Start() method of my _GameManager gameobject. However, right after that is filled, I need one of my other gameobjects to query the List for a gameobject it needs a reference for in order to pull it’s transform.position. Sometimes the list gets built on time and the game runs great. Other times, however, it seems like the List it built after the query happens and my console goes haywire with “object reference not set to instance of an object” exceptions. The script in question is as follows: https://hastebin.com/pozanusese.cs and the script for the GameManager is as follows: https://hastebin.com/jolegabulo.cs.

Obviously I’m not the most advanced programmer but I still wouldn’t consider myself a beginner as well. I suppose I’m mostly just confused as to why the timing works out great in some cases and in other cases the timing is way too far off. Sorry if this post is a little vague, I just got up and haven’t had my coffee yet. Thanks y’all!

Oh, and the “Object reference not set to instance of an object” exception is thrown in line 19 of LightController.cs

I had already answered your question in another thread.
You may want to add a getter (either get-method or property) and initialize it when something needs a the reference to it.

Or you just use the field initializer so that it gets initialized as soon as your type is accessed.

Not sure why you haven’t tried that until now.

Simple stupid answer is to make Start a coroutine on the thing that is dependent on the list and have it wait one frame before accessing it.

I’d still most likely go with what @Suddoha suggested. The only issue I see with it is attempting to access the property in an Awake method would fail in an unrecoverable way (and corrupt the list data).

I just tried this:

public List<GameObject> CurrentGameObjects
    {
        get
        {
            if (CurrentGameObjects == null)
            {
                foreach (GameObject Obj in GameObject.FindObjectsOfType<GameObject>())
                {
                    OnObjectCreated(Obj);
                }
            }
            return CurrentGameObjects;
        }
        set
        {
            CurrentGameObjects = value;
        }
    }

and I got myself a stack overflow error. I’m assuming that I am not using the getter properly

What does OnObjectCreated do?

for right now this is all it does:

private void Event_OnObjectCreated(GameObject obj)
    {
        CurrentGameObjects.Add(obj);
    }

The setter is probably screwing it up. I’d just do this

private List<GameObject> current;
public List<GameObject> Current
{
    get
    {
        if (current == null)
        {
            current = new List<GameObject>();
            current.AddRange(FindObjectsOfType<GameObject>);
        }
        return current;
    }
}
1 Like

welp, looks like you were right my good sir! Many thanks to you!

Why would it fail? :face_with_spiral_eyes:

If it relies on a list of GameObjects that haven’t initialized yet because you called it in Awake

1 Like

Ah that’s what you meant. Ye, that’s correct. Of course I assumed he’d use Awake, Start and so on properly, so that shouldn’t be an issue. :S

Thats because you’re calling the getter recursively, infinitely, so its always gonna overflow. Not sure how noone caught that…

1 Like

Simplest would be to do every initialization in Awake, and accessing other objects in Start. That way you’ll never have any timing issues.

1 Like

This doesn’t work when your initialization depends on other GameObjects in the scene.

Control your script execution order using the project settings, and then structure your awake and starts so dependencies already exist before being called / referenced.

A good way I do this is to create a startup manager, which calls the start method (called CustomStart in my scripts) based on the defined order I decide.

I also do the same with updates and run everything through an update manager to combat this problem:

I’d leave the order alone whenever you can, instead try to design a system that does not rely on an order or simply resolves this in different ways - one example is this thread, where lazy initialization might be handy.

A growing SEO is one of the worst things to have in a Unity application, it needs to be well documented for serious projects and is just a root for various problems.

This arcticle has never mentioned all the pitfalls you can run into, as you re-invent the wheel. Still something to keep in mind once you are serious about implementing this properly. :stuck_out_tongue:

Because that wasn’t the original issue. @KelsoMRK spotted and fixed it, he just did not elaborate any further. :smile:

Dont worry, I have a very fleshed out start and update manager and the performance gain from it is around 50% increase depending on how script heavy the application is. Further more, controlling my script execution by use of a start manager ensures that everything is where I want it to be, and when I want it to be, similar to the type of initialization logic you would code into a “pure” c# or c++ program. I definitely recommend you giving it a go, and profiling your performance before and after to see what I mean :slight_smile:

Please Note: Also if you look inside of unity decompiled code on github it is easy to see that the way they handle multiple updates are not good and running them through a single update manager reduces this overhead (less in 4.6 experimental but still an increase)

I’ve got a project setup to test this whenever I want since I experimented with it the first time, I know about the benefits. :slight_smile:
My point was that the blog post simplified it alot, but once in a while you find posts that refer to threads or tutorials that miss quite of alot of it so that the “improved” system does behave quite differently and even inconsistenly from what you’re used to in Unity.

It wasn’t my intention to talk negatively about it. :stuck_out_tongue:

1 Like

Dont use start, its buggy and unreliable, use your own Interface method. Do your own initialization discipline.