One of the changes from 3.5 to version 4.0 is the question about activating deactivating game objects and their children.
In my project I have a group of enemies that are children of the same object “skeletonenemies”. I want them to be all active in a particular moment of the story and not active in other moments. I previously achieved this using SetActiveRecursively. Now with version 4.0 this code is deprecated and I am trying to use SetActive. I followed the "Upgrade guide from 3.5 to 4) but it seems not to work.
When I use SetActive (false) to the object that contains all my enemies as children, it correctly becomes inactive, the skeletons all disappeared but they are still active and other AI characters I have in the scene attack them as if they were active.
In the inspector the parent object is not active, while the children yes.
What am I doing wrong?![]()
Thanks
I found that Setactive dosen’t do children like it says, so I have to still use the old way while getting a warning.
I am happy I am not the only one …
tried just changing .active instead?
I followed the upgrade guide and setactive seems to have no effects on children!
That’s obsolete in Unity 4 and should no longer be used.
As for SetActive(false), it sets .activeSelf and .activeInHierarchy for that object to false, and sets .activeInHierarchy for all that object’s children to false. .activeSelf for the children is not touched. So yes, it does work as documented. If you want .activeSelf for all children to be false as well, then you’d need to write a SetActiveRecursively replacement function.
–Eric
Good thing no one forces us to upgrade , I have a project that would probably completely break with the new GameObject active system .
Why did unity have to mess with a good thing , SetActiveReclusive wasn’t so hard to use .
I know SetActiveReclusive was a performance killer in certain cases … but it solved so many situations to me and many others.
Why do I have to write a replacement of SetActiveReclusive? I think it would be better if Unity people do it!
With the new version 4 it is also difficult to activate and deactivate objects in the inspector if they have children. In previous version, Unity asked if you wanted to affect children or not. It appears to be a wrong decision by Unity development team, in my opinion. I would be happy to change my opinion if someone could explain me.
Just imagine when you want to deactivate a character with all its chilldren (mesh parts, biped, weapons,…). Do I have to open all the structure of this game object and deactivate each children?
It was necessary to switch over to hierarchical activation for some of the upcoming features, since now you can activate/deactivate hierarchies without losing the state in the children of what was active/inactive previously. In other words, let’s say you have an object with two children, “Child1” and “Child2”. Child1 is inactive to start with and Child2 is active. You can toggle the root on and off, and Child1 will stay inactive always, while Child2 toggles on and off along with its parent. This was impossible with SetActiveRecursively. Unity should have worked this way from the beginning really, but better late than never…it’s much better and easier to use than it was before. No more annoying “do you want to deactivate children” dialog and so on.
In general you shouldn’t actually need to write a SetActiveRecursively replacement, since just using SetActive(false) on the root object deactivates children as well. It won’t turn their .activeSelf to false, but do you really need that? It does turn their .activeInHierarchy to false, which is what you actually want to happen. Once you have done SetActive(false) on the root object, then children are deactivated so that their scripts won’t run and they can’t be found with GameObject.Find. So basically the same behavior as using SetActiveRecursively, except with the benefits as described above.
The only time you should encounter any confusion is if you imported a 3.x project with inactive hierarchies, in which case all the children are explicitly set as inactive during the conversion, so they won’t respond if SetActive(false) is used on the root. In this case you should reset the hierarchy’s active state manually: toggle everything on, then set the root to inactive. Now everything will work with SetActive as expected.
–Eric
I try to explain: it is true that with setactive =false the parent is deactivated, the children are not visible, but the otherAI I have in the scene attack them as if they were visible and active. In this situation I see the AI attack but enemies are not visible. I need to have the children totally deactivated. I chose to put them under the same object because it was easier to deactivate a single object rather than 30 enemies. I understand your purpose but sometimes it is useful to deactivate a gameobject and all of its children.
Don’t forget also the problem in the inspector. Thanks
That’s what SetActive does now. If you’re upgrading a 3.x project, see what I said about resetting the hierarchy so it will work with SetActive.
–Eric
It doesn’t work for me, but what it seems really bad in the new logic is that if you want to deactivate in the inspector a parent object with many children you have to deactivate all of them manually, otherwise, if they have scripts attached, they still influence the game. I think that it would be better to chose, as before, if I want to activate/deactivate the children or not.
Back to 3.5.6 …
That’s not how it works. If you deactivate the parent, then the children are deactivated as well and any scripts they have attached are also deactivated. There is no need to manually deactivate anything.
Projects from Unity 3 may need to be fiddled with after upgrading them. But only once, and after that it does work.
–Eric
I have an editor script that applies SetActive to a hierarchy:
http://www.fugutalk.com/?p=5887
It’s useful for adjusting scenes just once in upgrading to Unity 4 by making everything initially active and then you can toggle the root nodes (i.e. call SetActive) to disable/enable entire hierarchies. Replace any references to .active with .activeSelf or .activeInHierarchy (probably you want the latter, which is “really” active)
That is very nice to know
Havnt tried v4 yet, but i like it better already…
Unfortunately my english is not good enough to explain what happens to me. In my scene I have:
- the player
- some AI’s friends of the player with AI scripts to find and fight enemies
- some AI’s enemies all in a game object as children and reay to attach my player and his friends
At start enemies must be deactivated and activated later (when it is night). In the inspector, before to press play, the parent object and all the children (enemies) are active, when I press play there is a script that use setactive (false). After that the parent object is deactivated but the children aren’t! Their scripts still works so the AI friends of the player find the enemies as if they were active and fight against them (I see the characters fighting with invisible enemies).
I hope now it is more clear. Thanks Eric
Interesting I will try it. Thanks so much technicat!
I have over 999 instances of .active and .SetActiveReursively in my APP. Changing all of them is going to be a right pain in the posterior.
Is there any way (e.g. a script) that I can do a bulk change to all scripts somehow, replacing all instances of .active and SetActiveRecursively?
What if I didn’t change them… yes i guess those minor yellow warnings, but the App still runs… Is there a performance loss?
Thanks