In Unity 5, what is a βcleanβ way to control dynamically created game objects?
I wrote a component ( MonoBehavior ) that creates / destroys several GameObjects . Objects are downloaded as part of a customization system that selects parts of the character - hair / clothes, etc. This means that they are visible to the player, visible in the editor, but should not be edited in the editor. Downloadable objects are skeletal grids.
The script behaves as follows:
- Loads GameObjects from resources (the exact object is defined in the script, they are not prefabs)
- Attaches them to some part of the scene (not necessarily to its own node)
- It is deleted upon destruction.
Removal:
protected void unloadLastResource(){ if (lastResourceInstance){ if (Application.isEditor){ GameObject.DestroyImmediate(lastResourceInstance); } else GameObject.Destroy(lastResourceInstance); Resources.UnloadUnusedAssets(); lastResourceInstance = null; } }
Creature:
GameObject target = getEffectiveTargetNode(); Object resource = Resources.Load(newResourceName); instance = Instantiate(resource) as GameObject; instance.hideFlags = HideFlags.HideAndDontSave; instance.transform.parent = target.transform; instance.transform.localPosition = Vector3.zero; instance.transform.localRotation = Quaternion.identity; instance.transform.localScale = Vector3.one;
Destruction Handler:
void OnDestroy(){ unloadLastResource(); }
It seems to work fine in the editor, but when I switch from game mode back to edit mode, I get a lot of warnings:
Destroying object multiple times. Don't use DestroyImmediate on the same object in OnDisable or OnDestroy. UnityEngine.Object:DestroyImmediate(Object)
And I get a bunch of new object trees (those that need to be deleted - the trees come from the object that was loaded with the original "resources" and was attached) at the top level of the scene hierarchy.
So, how can I handle dynamically created game objects?
I need to know what flags I need to set, and what steps I must take to ensure that the object does not "flow" into the scene and is correctly destroyed when the component that created it is deleted.
Tip
Full base class used by "ResourceLoader"
public class BaseResourceLoader : MonoBehaviour { public GameObject targetNode = null; protected GameObject lastTargetNode{ get{return lastTargetNodeInternal;} } private GameObject lastTargetNodeInternal = null; protected bool targetNodeChanged(){ return targetNode != lastTargetNode; } protected string lastResourceName{ get{return lastResourceNameInternal;} } private string lastResourceNameInternal = "";