Help with using default classes in Unity

Hello! Kind of a beginner to Unity :confused:

I am trying to create an Arrow custom object by passing in parameters + a prefab gameobject using a “sentinel” game gameobject

This should create a new Arrow object, and initialize the private variables, including the Arrow gameobject prefab. The prefab is then initialized, then hidden.

Next, because the Arrow gameobject has been instantiated, the code in Start should be run, which will finish the object initialization and set the new arrow in it’s starting position before it moves forward in FixedUpdate (which just calls the Move method.

However, when this code is run, the gameobject is only instantiated, but not hidden. In addition, non of the steps after the Start function are called.

Looking at the debugger, the local values in the object go red, then reset to junk values:

Because of this, I get a constant error message that says that arrow gameobject has not been assigned, even though I literally did

Any way I could fix this?

Code (Apologies, unity forums does not let me send more than one image)

–Thanks

You’re not doing anything with the instantiated arrow.

Instantiate returns the instantiated object. Use that return value to modify the instance.

Ergo:

private void Start()
{
    var arrow = Instantiate(arrowObject);
    arrow.GetComponentInChildren<SpriteRenderer>().enabled = false;
}

Of course you should reference the arrow by a component on it, which should have a serialized reference to its sprite renderer, so you don’t need the GetComponent call.

For firing arrows and stuff like this, I really enjoy this pattern a lot… It makes sure you have “all you need” before you call, while keeping details about the thing you’re making in one central spot.

Factory Pattern in lieu of AddComponent (for timing and dependency correctness):

Also, stuff like arrowObject… use better names, like-a-this:

Instancing and prefabs in Unity and naming your variables:

If you name your public / serialized fields (variables) as simply “thing” (or worse, “thingObject,” which adds no semantic meaning), then you set yourself up for confusion.

If something is a prefab, name it that, such as public GameObject ThingPrefab; and only drag prefabs into it. Prefabs are “dead things (assets on disk) waiting to be Instantiated.”

If something is already in the scene or you Instantiate<T>(); it in code, then store the result in a properly-named variable such as private GameObject ThingInstance;

Naming is hard… name things WELL to reduce your own confusion and wasted time.