Access Single Instance of Serialized Prefab Before Instantiation

I have a “global” object (call it “A”) that contains a serialized list of prefabs (call these "obj"s) I need to instantiate later, choosing them randomly. On the last obj (call it lastObj), I need to mark it as the last by changing a serialized property (call this “isLast”).
Seems simple, but because I can have multiple of the same obj, and each of these has the marked property rather than just the last one. On a trigger collision with the player, an obj checks its isLast and stops the player if true. My player gets stopped at each of these objs which were instantiated from the same prefab.
Below is some pseudocode to get the point across simply (and be generalized enough to help others with similar problems). In reality, I put the randomly selected objs into a queue and pop them off as needed. It’s here while I’m populating the queue that I would like to edit isLast on the lastObj before it goes into the queue.

I would like some help in understanding both why this is and how I can modify just one instance before it’s instantiated without affecting duplicates.

In A:

[SerializeField] public GameObject[] objs;
private void Awake()
{
    GameObject lastObj = getLastObjFrom(objs);
    lastObj.isLast = true;
}

In obj (or rather, a script attached to obj):

[SerializeField] public bool isLast = false;  // Default; set to true by A on the actual last
private void OnTriggerEnter(Collider other)
{
    if (this.isLast)
    {
        stopPlayer();
    }
}
  1. Welcome to the unity forum and thank you for using code tags :slight_smile:
  2. I am not sure I understood your problem. Why not set isLast immediately after calling Instantiate() for the last time on your prefab (and remove your Awake code entirely)? Instantiate() returns an object which you can call GetComponent() on to access your script. But maybe I am missing the point.

Here is why this happens:

  1. You Instantiate your Object
  2. Once the object is activated for the very first time in the scene Awake() is called on it. This is where your code sets isLast to true. This happens for every object.

You have some options to solve this:
A) Change your code in Awake() to do some logic to determine if this object really is the last one (Am I the last in the queue, …).
B) Have your Instantiate() code detect which one is the last object and then set the flag (possibly reset the flag on all others).
C) Add a lastObj var to a parent of the objects and store your lastObj there. Then you can easily check if the hit object is equal to lastObj. It seems like you already have something like that, why not use it.
D) Don’t use any flags etc. and add some logic to your collider code which determines if the current object is the last on demand.

Thanks for your reply!
As I have it now, isLast is being set as I add it to the queue to pop off and instantiate later. Otherwise, I have to keep track of however many are left/have been popped. It’s certainly an option to just set it after it’s instantiated; I was just wondering if there was another way.

Edit: I started replying before I saw your edits. Thank you for the further clarifications and options. I had been considering something like D as an alternative and I think I’ll go that route.

1 Like

Sorry, my bad. I tend to press the post button too quickly. And then realise that there is much more to say :smile: