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

Many GameObjects and GameObject deactivate Performance

Discussion in 'Editor & General Support' started by Zielscheibe, May 6, 2015.

  1. Zielscheibe

    Zielscheibe

    Joined:
    May 7, 2014
    Posts:
    4
    Hi,

    The Situation

    I´m currently working on a simple agent based simulation based on the well known Hawk-Dove Game.
    This simulation involves a lot of adding and removing operations on agents. To avoid the memory allocations I instantiate all 40k Agents(Gameobjects with just behaviours attached to, no renderers involved) at the beginning. So Adding and Removing operations are just calls to gameobject.SetActive().

    The Problem

    The performance at this point was acceptable. The real problem appears when I add an operation which leads to the death of many agents in the same update step. For example 5k gameobject.SetActive(false) can occur in one update. I was suprised when the performance dropped from 30fps to 2.5 seconds for one update at worst.



    I thought I understood the CBES concept of Unity very well. So in my understanding, gameobjects are relatively light-weighted. Deactivating and Activating should always be preffered to deleting or instantiating, if possible.

    The Question

    There are two questions which follows this situation.
    1. Is gameobject.setactive() really that expensive?
    2. Is it in general a bad idea to have a lot of gameobjects? (non-rendered)
    Regarding the second question, what is the actual range of gameobjects, Unity performes best with? I already searched the web for such limitations but never found a clear answer or at least a suggestion.
    I would be also interested to know, what actually happens on deactivate/activate? Are there memory allocations or other expensive operations involved?

    My own conclusions so far

    I think i should drop the concept of using Unitys CBES to simulate that many agents and write my own loop in co-routines instead.



    I would be very happy about some suggestions to this two questions and get a deeper insight of these basic operations in Unity. :)
     

    Attached Files:

  2. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Not sure how much better/worse it might be, but instead of SetActive, you might try just enabling/disabling certain scripts, and leaving everything else enabled and move them off screen. Like just disable the scripts that move them/logic and leave the overall game object enabled.

    Good luck!
     
  3. noXur

    noXur

    Joined:
    Mar 27, 2014
    Posts:
    1
    I encountered a very similar problem with GameObject.SetActive(). I believe that this method indeed seems to do quite more under the hood as we think. Especially, this was noticeable when I once debugged data members of a MonoBehaviour of an activated/deactivated GameObject. I'm not sure but this method may do something memory-related with a deactivated GameObject, too.

    But for now, we can only guess and try to avoid a massive number of calls to this method. Would be really nice to know exactly what is going on in the internals of this method.
     
    Dr-Seuss likes this.
  4. Zielscheibe

    Zielscheibe

    Joined:
    May 7, 2014
    Posts:
    4
    Thanks for your suggestions so far :)

    I reimplemented my whole simulation based on a simple coroutine loop. So basicly instead of understanding the actual source of my problems with gameobjects, i now simply avoid them.

    The results so far are very satisfying for me.
    The gameobject approach was capable of simulating 40k Agents with a very unstable framerates mostly at 500ms (Everthing tested in the editor not the build version)
    Now i can run 100k Agents at 200ms. Which is of course a really nice improvement :)

    How did I do this?
    Simply by avoiding any memory allocations at runtime. Like the picture shows most of the workload goes into the actual scripts, nothing is wasted for garbage collectiion or other stuff.



    This seems to confirm Noxurs assumption. Because avoiding memory allocations by using gameobject.setactive was my plan from the beginning...


    It would be very nice to have some feedback on this whole gameobject performance topic.
    • How expensive is gameobject.setactive() ?
    • Are there memory allocations involved?
    • If yes, why is this not stated in the documentation?
    • Are there dependencies on the number of gameObjects? Does such behaviour just happen on large numbers?

    Regarding the second questions.
    Methods like Start, Update, FixedUpdate and so on are obviously messages not overriden methods. But sending messages seems to be not that fast as one might expect.

    So my assumption: Because of using messages the performance used for gameobjects does not increase in a linear way one might expect.

    -> Conclusion. If a lot of stuff is happening in your scene for example more then 20k things need to updated somehow. Consider not to use gameobjects and construct a more lightweighted approach on your own. And dont use 20k + gameobjects. (Of course i´m talking about non-rendered stuff).
     
    jjbish and io-games like this.