"GameObject is already being activated or deactivated"

Hey, I am getting the title’s error when trying to change the parenting of an object OnDisable. Basically I save the parent object, OnEnable I set the parent to null, and when the object is about to be disabled I change the parenting back to its original parent, and I get this error. The original parent is not deactivated. Code is basically as follows:

    void OnEnable()
    {
        _transform.parent = null;
    }

    void OnDisable()
    {
        _transform.parent = _transformParent;
    }

Any ideas why?

Thanks in advance,
Best regards,
Allan

Anybody got any idea on this? This is the exact same problem i’m having …

As far as I know, you can’t change the parent of an object in the same frame as you set it active or inactive due to the way the system works (all children also are affected).

I guess what you can do is maybe start a coroutine (on a separate object) and change the parent on the next frame? I know it’s a bit of a hack…

2 Likes

Thanks @Oana , but it’s not the same frame, i set the code to parent to unparent it only when i press a key, the unparenting and parenting works fine, but i get the message “gameobject is already being activated or deactivated” when i set the parent and “null reference exception” error when i unparent it…

1 Like

Are you saying this happens if you have

void Update(){
    if (Input.GetKeyDown(KeyCode.X){
         _transform.parent= _transformParent;
    }
}

then it also gives you “gameobject is already being activated or deactivated”? Because if that’s the case, the problem may be somewhere else in your code.

The code you showed has the parent being changed in OnEnable and OnDisable, which means it definitely is happening in the same frame, and in fact during the enable/disable operation.

I’d suggest making a public method on your component that does the changes together but one after the other, instead of relying on it happening in OnEnable/OnDisable. Eg:

public void SetEnabledAndParent(bool newEnabled, bool newParent) {
    transform.SetParent(newParent);
    enabled = newEnabled;
}
1 Like

Could you please clearly mention when you want to enable and disable the parent?

Exactly, i have done the same thing twice already … i believe that’s what is happening…

Basically here’s the thing …

I am making a prototype for 2d side scrolling shooter, the Gun gameobject has to “look at” the mouse cursor, but the gameobject can not be Player’s child because i use localscale.x = -1 on Player method to Flip it, and the rotation for child does not work properly in that case …

Now on top of this, i want to have the weapons as the child of Player, for various reasons, one of the benefit is that i can make prefab of player, and won’t have to worry about instantiating the weapons back and forth among others…

So what i do is:

  1. parent the Gun to Player in the project, during the start of the game, i cache the Player’s transform, and un-parent it
  2. when i have to change the weapon, say player presses “g”, then i make i deactivate it, the code in OnDisable has the un-parent code, and THEN activate another weapon + un-parent another weapon and every frame, adjust it’s position and scale, rotation etc…

I deleted the code, because of that error but it goes something like:
weapon[index].SetActive(false);

Here, the weapon script has:

void OnEnable() {
    transfrom.parent = null;
}

void OnDisable (){
     transform.parent = parent_transform;
}

I hope you understand what i mean …

Wow, Thanks … i just tried what you said and it didn’t give any error…

I still have the OnEnable () code intact, to set the parent to null, but i did the parent-and-disable code in a separate function, and there’s no error…

I will re-do the proper inventory manager code and report back if there’s any error, i guess there won’t be any now…

Also, i wanted to know something … the Awake () of the child gameobjects are ALWAYS guaranteed to be AFTER that of the Parent, am i right?
I’m sorry if it’s obvious, but i just wanted to confirm …

No.

1 Like

Why not? Is there any documentation/facts from Unity?
This is my Player GameObject Hierarchy structure:
Player (Root)
… - weapon slot (child of Player)
… - Gun (child of Weapon slot)

In my Player GameObject, the Awake() in “Gun” always debug Logged After that of the weapon slot, except under exceptional condition like Gun being active while “weapon slot” being inactive…

So are there any other situations or any documented statements from Unity?

You asked if it’s guaranteed - which it isn’t. For one, script execution order can affect this. If you need to hook objects together then do it in Start so that you are ensured that everything is initialized fully. Or expose the fields and do it in the Inspector.

1 Like

This. My rule of thumb is to do internal initialisation (ie: everything with no references to other GameObjects) in Awake(), and all external initialisation (finding and hooking up any external references) in Start(). This way on startup you can be relatively confident that everything has itself set up before anything else calls into it.

1 Like

Necro, but a quick hack is to Invoke the method that sets the Parent with a timing of 0. That pushes it into the next frame and allows you to set the Parent, even if the object is already deactivated. In that case a coroutine isn’t possible, so Invoke can do the trick.

1 Like

I know that this is an old thread, but I solved the issue by using doing the below.

void OnEnable () {
transform.SetParent (null);
}

void OnDisable(){
Invoke (“ReAttach”,.1f);
}

void ReAttach(){
transform.SetParent (oldParent);
}

2 Likes

Hello,

Having this problem right now, is there no way to check if the gameObject is being activated or deactivated?

You can use gameObject.activeSelf or gameObject.activeInHierarchy

Sorry for the necro-posting, but still I don’t get it.
The situation is simple and kind of wide-spread: pooling.
And when I take some game object out of the pool I may want to parent it to some “user’s” (other script’s) transform for convenient manipulations with the localPosition. And vice versa when I don’t need that object anymore and put it back into the pool, I definitely want not only disable this gameObject, but also set it as a child of the pool’s transform so the pooled object won’t be occasionally destroyed along with it’s last “user’s” gameObject.

Why I can’t afford this kind of behaviour? I don’t understand the reason why this 2 at the first glance totally independent operations in reality are tied?

Delayed change of parent is not a solution, because user’s gameObject may be destroyed in the same frame with all it’s children (including the pooled one).

1 Like

You can I do it a fair bit. You just can’t do the re-parenting in OnEnable or OnDisable.