I’m having trouble where code that is supposed to pick up a small number (4-8) of child objects with a specific tag actually creates phantom duplicates. The reason I notice this is that I collect them in a list and at the end of the code that list has twice as many entries as it should and the first half of the list is all “None”.
Tracing my code I come to a point where a “transform.SetParent()” call causes an Awake() on the kid objects to trigger. The only explanation I have and I’d like to check if this is true, is that SetParent() actually clones the object, and immediately deletes the original, and somehow my code picks it all up in the exact moment (frame?) that both objects exist.
No, cloning a hierarchy just to set a parent would be an exercise in madness. That would make iy really costly in lots of cases. It’s only assigning a reference to the parent. Behind the scenes there’s the TransformDispatch which is a mechanism to allow systems to poll for changes such as Transform change and there is a mechanism to get a callback on parent change.
Maybe you’re seeing something that a particular system is doing but I’ve never seen the MonoBehaviour “Awake” called because of a parent change which, in my opinion, would be a serious bug if so.
I have attached a trivial Monobehaviour to the object that calls Debug.Log() in Awake() and the stack trace in that tells me that the SetParent() call is the one right before the Awake(). I was surprised as well, but I find no other explanation.
Yeah, maybe that is some odd behaviour I’m not aware of but that does surprise me. You’re sure the Awake isn’t before the SetParent? Not that this is my area of expertise but would you mind posting the stack as I’m super curious now!
I’m looking through the C++ source because it’s my start of day and I have a strong cup of coffee and curiosity has got me.
The child is originally attached to a parent that was deactivated, but the child itself is activated. As a result the child would not get its Awake method called, because it’s deactivated in hierarchy
When you use SetParent on that object and move the child to a parent that is active (or unparent by passing null), the child would become active at that moment and Awake should be called.
Without seeing some relevant code we can’t really tell what’s going on.
Here’s what the code around BuildingVisualsNew.cs line 117:
foreach (Transform t in allTransforms) {
if (t != null && t.tag == "Workspot") {
Debug.Log("workspot found: "+t.name+" - will be renamed to #"+count.ToString());
t.SetParent(ws.transform);
t.gameObject.SetActive(true);
t.name = "Workspot "+count.ToString();
count++;
}
}
It might be what you describe. I do deactivate the parent GO in code, that’s why I fetch out the child objects (because I need them). So this might be unrelated to the objects becoming duplicated, interesting.
I’ll do more debugging, at least I now know that my problem isn’t some one-frame copy issue within the engine.
Note that Awake of an object is only called once in the lifetime of the object. I highly recommend to add a context reference to your Debug.Log call so you can identify the object by clicking on the log message in the console.
Debug.Log("Workspot Awake", gameObject);
You should never see Awake called twice for the same object.
You just showed us that one single log message. What exactly made you think that the object somehow got cloned / copied? Do you actually see two Awake messages for the same object?
Because I instantiate a known number of these objects, and I end up with exactly twice that number, half of which have “(Clone)” appended. My count variable also goes up to exactly twice the known number.
After some more debugging, I believe this is an artifact of the procedural generation somehow. I’ll dig through that asset’s code to verify.