Hi guys,
Several times, I need to procedurally create a GameObject and to put it as a child of my MonoBehaviour GameObject (in both Editor and Playtime). Something like this:
[ExecuteInEditMode]
public class MasterObject: MonoBehaviour
{
GameObject m_Slave; // this field is NOT serialized because procedurally instantiated
void Start()
{
m_Slave = new GameObject("Procedural Slave");
m_Slave.transform.SetParent(transform, false);
m_Slave.hideFlags = HideFlags.NotEditable | HideFlags.DontSave; // the user cannot manually modify the procedural object
}
}
![]()
This works very well, except when I duplicate my MasterObject in the Editor. When I do so, the Slave object is also duplicated, and another one is created from Start:

I tried to change the hideFlags of my slave object, but couldn’t find an option which prevent it from being duplicated with his parent. This slave object is also duplicated if I put it as HideFlags.HideAndDontSave.
To fix this issue, I implemented this workaround:
I attach a special MonoBehaviour to my Slave object and manually call a function on it just after being created to let it know that it is properly procedurally generated and not simply duplicated. After that, in Slave.Start function, I check if the function has been called: if not, this means that the GAO has been duplicated, so I destroy it.
Here is the code:
[ExecuteInEditMode]
public class MasterObject : MonoBehaviour
{
GameObject m_Slave;
void Start()
{
m_Slave = new GameObject("Procedural Slave");
m_Slave.AddComponent<Slave>().OnProceduralInstantiate(); // attach Slave behaviour and manually call a function to let it know that it's properly instantiated
m_Slave.transform.SetParent(transform, false);
m_Slave.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
}
}
[ExecuteInEditMode]
public class Slave : MonoBehaviour
{
bool m_HasBeenInstantiated = false;
public void OnProceduralInstantiate()
{
m_HasBeenInstantiated = true;
}
void Start()
{
if (!m_HasBeenInstantiated)
{
// This means the GAO has been duplicated from Editor, so we delete it
DestroyImmediate(gameObject);
}
}
}
And this works. However, this feels a bit ugly to me, I would like to know if there is a better way to solve this issue.
Thanks