Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

"GameObject is already being activated or deactivated"

Discussion in 'Scripting' started by AllanMSmith, Nov 13, 2014.

  1. AllanMSmith

    AllanMSmith

    Joined:
    Oct 2, 2012
    Posts:
    180
    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:

    Code (CSharp):
    1.     void OnEnable()
    2.     {
    3.         _transform.parent = null;
    4.     }
    5.  
    6.     void OnDisable()
    7.     {
    8.         _transform.parent = _transformParent;
    9.     }
    Any ideas why?

    Thanks in advance,
    Best regards,
    Allan
     
  2. CStunner

    CStunner

    Joined:
    Jul 12, 2013
    Posts:
    39
    Anybody got any idea on this? This is the exact same problem i'm having ..
     
  3. Oana

    Oana

    Joined:
    Sep 28, 2012
    Posts:
    87
    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...
     
    angrypenguin and CStunner like this.
  4. CStunner

    CStunner

    Joined:
    Jul 12, 2013
    Posts:
    39
    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..
     
  5. Oana

    Oana

    Joined:
    Sep 28, 2012
    Posts:
    87
    Are you saying this happens if you have

    Code (csharp):
    1.  
    2. void Update(){
    3.     if (Input.GetKeyDown(KeyCode.X){
    4.          _transform.parent= _transformParent;
    5.     }
    6. }
    7.  
    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.
     
  6. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,617
    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:

    Code (csharp):
    1. public void SetEnabledAndParent(bool newEnabled, bool newParent) {
    2.     transform.SetParent(newParent);
    3.     enabled = newEnabled;
    4. }
     
    CStunner likes this.
  7. harish-g9

    harish-g9

    Joined:
    Jan 29, 2013
    Posts:
    7
    Could you please clearly mention when you want to enable and disable the parent?
     
  8. CStunner

    CStunner

    Joined:
    Jul 12, 2013
    Posts:
    39
    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:
    Code (CSharp):
    1.  
    2. void OnEnable() {
    3.     transfrom.parent = null;
    4. }
    5.  
    6. void OnDisable (){
    7.      transform.parent = parent_transform;
    8. }
    I hope you understand what i mean ...
     
  9. CStunner

    CStunner

    Joined:
    Jul 12, 2013
    Posts:
    39
    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..
     
  10. CStunner

    CStunner

    Joined:
    Jul 12, 2013
    Posts:
    39
    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 ..
     
  11. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    No.
     
    CStunner likes this.
  12. CStunner

    CStunner

    Joined:
    Jul 12, 2013
    Posts:
    39
    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?
     
  13. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    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.
     
    CStunner likes this.
  14. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,617
    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.
     
    CStunner likes this.
  15. Democide

    Democide

    Joined:
    Jan 29, 2013
    Posts:
    315
    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.
     
    KristianBakov likes this.
  16. FiveFingerStudios

    FiveFingerStudios

    Joined:
    Apr 22, 2016
    Posts:
    510
    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);
    }
     
    GhostDeRazgriz and Dhoren like this.
  17. Magnesium

    Magnesium

    Joined:
    Sep 14, 2014
    Posts:
    179
    Hello,

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

    SolarianZ

    Joined:
    Jun 13, 2017
    Posts:
    229
    You can use gameObject.activeSelf or gameObject.activeInHierarchy
     
  19. Samuraisa

    Samuraisa

    Joined:
    Feb 28, 2013
    Posts:
    2
    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).
     
    DerDicke likes this.
  20. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,617
    You can I do it a fair bit. You just can't do the re-parenting in OnEnable or OnDisable.