Child detach and save itself when parent is destroyed

Is there a way in the OnDisable or OnDestroy event for a child to detach itself from it’s parent and stop itself from being destroyed?

I’m trying to increase framerate and it would be handy if certain objects could child themselves to other objects then detach again when the parent is destroyed.

I’m pretty sure that once destruction has been ordered, you cannot “catch” it and stop it.
So you can’t do it “at the child level.”
But it’s very easy to do what you say at the “parent” level.
Make a empty game object AAA, and then name some children of it BBB, CCC etc.

#pragma strict
function Start()
{
    Destroy(gameObject, 5.0);
    Debug.Log("I will self-destruct soon ...");
}
function OnDestroy()
{
    Debug.Log("I am now self-destructing ...");
    Debug.Log("However I will 'save' the children ...");
    for (var cc : Transform in transform) cc.parent = null;
}

It’s that easy. Now, more in terms of what you were thinking, put this on the parent(s) in question

#pragma strict
function Start()
{
    Destroy(gameObject, 5.0);
    Debug.Log("I will self-destruct soon ...");
}
function OnDestroy()
{
    for (var cc : Transform in transform)
        cc.GetComponent(Saver).OnParentAboutToBeDestroyed();
}

That will send the message OnParentAboutToBeDestroyed() to all children.

Now, make a script called "Saver.js"

// this is Saver.js
#pragma strict
function OnParentAboutToBeDestroyed()
{
    Debug.Log("My parent was about to be destroyed, so I moved out.");
    transform.parent = null;
}

Simply attach Saver.js to each child. (Note that you can and likely should choose to attach it just to the first level below AAA - not below.)

So that’s it. Now, note that you could also use GetComponentsInChildren here but it’s a bit tricky, since it also annoyingly finds “Saver” components on itself. Further, you could use SendMessage here for a clean effect, but, my feeling is the best engineering here is that you should “manually” and carefully decide which scripts do or don’t have a Saver.js component.

Again the bottom line is unfortunately there is no “On my parent is about to be destroyed” or indeed nor is there something like “don’t destroy me even though someone asked for me to be destroyed”

So, simply use this line of code in the parent

for (var cc : Transform in transform)
    cc.GetComponent(Saver).OnParentAboutToBeDestroyed();

and then in the children, simply set parent=null … and that will avoid the destruction.

Of course, parent = null will leave the child in the top level of your hierarchy … you can of course move them anywhere you want for convenience. Hope it helps.

This method goes on the parent, a slight variation of:

void OnDestroy()
{
    transform.DetachChildren();
}

Object.transform.parent would be the property I’d look at - you can leaf through all of the children using a FOR loop…

for( int x=0 ; x<transform.GetChildCount() ; x++ )
{
    transform.GetChild(x).parent = NewObject.transform;
}

Of course, I’m not sure how this can really be used to improve framerate? You could disable the renderer on the parent object, but unless you have a LOT of redundant parents I’m not clear on the benefits.

The ideas above are great. But I recommend using void OnDisable() on the parent object. Because it is called before void OnDestroy() and you can avoid calling OnDisable() on children.