1
\$\begingroup\$

My game project involves collecting items that will be displayed in trophy cases of sorts.

There could be several hundred objects as the scale of the project increases, each with their own position, rotation and scripts.

I would find it easier to place the assembled items in their correct location using the editor and set their canvas group alpha to 0 (and set booleans in the script to inactive etc) and 'activate' them when they are 'collected' rather than instantiate them from prefabs as GameObjects.

My main question is about performance, is it costly to have my Gameobjects set in scene & created but set to 0 alpha? I don't need these objects to move or be destroyed etc.

My second question is about best practices for architecture design, is this a horrible way to do things? is a workaround for instantiating prefabs just lazy and counterproductive?

\$\endgroup\$
  • 2
    \$\begingroup\$ Note that an object set to 0 alpha might still take up cycles to update & draw, even for no visible result. Setting the GameObject to inactive (.SetActive(false)) prunes it from most of these update steps so it costs as little as possible while hidden. \$\endgroup\$ – DMGregory Mar 9 '18 at 17:22
  • 1
    \$\begingroup\$ However, when using a canvas it would be better to give each object (or groups of objects) their own Canvas component and disable that canvas component. This prevents the canvas objects higher up in the hierarchy tree from being marked dirty and having to perform an expensive resort. I believe it was this talk from Unity that covers that topic (if not, it's this one). \$\endgroup\$ – Draco18s Mar 9 '18 at 18:55
3
\$\begingroup\$

Hiding inactive game objects off-screen and out of bounds (where collision won't be a factor) and then teleporting them in place on certain triggers is actually a very common technique.

It vastly simplifies lifetime management of those object. It keeps pointers/references alive so you are less likely to crash by using a pointer to a freed object.

It front-loads the time spent allocating the object to the loading time of the level itself. With a specialized allocator you can even allocate all the memory a level needs in one go and then partition it out to the object in the level. "Allocate" here can also mean reuse the chunk of memory the previous level used. How the memory gets partitioned can be precalculated so the level load itself focus just on getting all the assets in place.

And because you are not allocating/freeing in the middle of a level, crashes due to out of memory are less likely in the middle of play and instead only happen as you load the next level (after your autosave makes sure that the player can resume at that point after you patch the mem leak that caused it).

If you have a level that gets revisited but needs different (heavy) prefabs then you could make 2 variants of the level. One for each set of prefabs you need for it.

\$\endgroup\$
2
\$\begingroup\$

In general, frequently instantiating and destroying game objects should be avoided. Expensive build-up and tear-down operations happen behind the scenes whenever you do that. Unity will also constantly allocate and deallocate memory. This fragements the RAM used by your game which in turn harms locality of reference which harms execution performance.

However, in your particular situation, this is unlikely to matter.

It matters, for example, in a bullet hell shooter where you would have to create and destroy several bullets each frame. In that case you would reuse objects in an object pool. The downside of object pooling, besides the added complexity, is that it prevents your game from returning memory it doesn't need anymore.

But in your case you are only going to create and destroy an object every few minutes on average. When something happens so rarely, it is not performance critical. The memory aspect does not apply either, because at one point the player will have collected all items anyway. So the best practice will be to do whatever leads to sourcecode which is easier to understand, debug and maintain.

\$\endgroup\$
  • \$\begingroup\$ my apologies for a meta question, if I mark your answer as having answered my question, does that prevent other people answering and providing additional insight? \$\endgroup\$ – bumble Mar 9 '18 at 16:07
  • \$\begingroup\$ @bumble No, people can still post more answers. However, accepting an answer often discourages people from doing so because by accepting an answer you communicate that your problem is solved. \$\endgroup\$ – Philipp Mar 9 '18 at 16:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.