2
\$\begingroup\$

Obviously there are a Scene hierarchy, but the problem is that the scene hierarchy was not meant for organizing GameObjects because parent GameObjects affect the transformation of their children.

For example what can one do to select all the decoration GameObjects? Some might be children of non-decoration GameObjects and buried very deep in the scene hierarchy while others might be root GameObjects.

One solution could be to add a Tag, but since Unity restrict you to only one tag per GameObject, that makes the usage of tags pointless as I have different overlapping categories.

Another solution would be to name objects but that is very error prone as a typing mistake will loose my GameObject. Also the team need to memorize possible tokens in the name which allow even more room for human errors.

Another solution would be to add an identifying Component, similar to how tags work in most other applications. But will there be a penalty in build time/runtime in a large project because of the additional Scripts (Components)?

Any other ideas how I can organize my Scene so that I can easily select a logical group of GameObjects from different unrelated parents in the editor Scene or Hierarchical view?

\$\endgroup\$
1
  • \$\begingroup\$ @Philipp I was referring to the editor. There is a magnifying glass icon which gives the option of Name or Type. But any other method will also do. \$\endgroup\$ Feb 17, 2021 at 13:13

2 Answers 2

2
\$\begingroup\$

Use marker-components.

The penalty of having a marker-component with no fields and no methods on a lot of objects will in most cases be negligible. But when you are in a situation where every byte matters (and still don't want to use Entities), then you could make that marker component commit suicide on awake:

class Decorative : MonoBehaviour { 
    private void Awake() {
        Destroy(this);
    }
}

This removes just the component, not the object it is on.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Yes, that is also what I am currently considering. I'm just trying to avoid instantiating unnecessary MonoBehaviors especially if a lot of new GameObjects are instantiated on the fly at different times, but then one might argue to use an object pool instead. \$\endgroup\$ Feb 17, 2021 at 13:28
  • \$\begingroup\$ BTW How will using Entities help for organizing the Scene? \$\endgroup\$ Feb 17, 2021 at 13:30
  • \$\begingroup\$ @JasperCiti It won't. The lack of editor support makes managing entities much harder than managing Game Objects. But Entities are what you would use to optimize performance and memory consumption when you need a very large number of very simple objects in your scene. \$\endgroup\$
    – Philipp
    Feb 17, 2021 at 13:33
  • 1
    \$\begingroup\$ I wonder if wrapping the whole file in an #IF UNITY_EDITOR directive would work. When compiling a build, the type should disappear entirely and (hopefully) the engine should strip it out and never instantiate it in the first place. You'd probably get a lot of warning spam about missing scripts at build time though. 😉 \$\endgroup\$
    – DMGregory
    Feb 17, 2021 at 14:16
  • \$\begingroup\$ That is an interesting idea. Will definitely try it out. However I have bad experience in the past with #IF UNITY_EDITOR directives because if you manually strip the wrong things you end up with very weird explainable bugs in the runtime. \$\endgroup\$ Feb 17, 2021 at 14:23
1
\$\begingroup\$

Based on Phillip and DMGregory's answer and comment, I found this solution works very well:

Create an Tag Component such as:

#if UNITY_EDITOR
using UnityEngine;

namespace AwSim.Tags
{
    [AddComponentMenu("Tags/Decorative")]
    [DisallowMultipleComponent]
    public class Decorative : MonoBehaviour {}
}
#endif

Attach it to the Prefabs or GameObjects. You can even add multiple ones like tags.

Because these Components do not implement any of the MonoBehaviour methods, it won't try to do anything at startup except instantiating a useless Component in the editor. However because of the wrapped directive, the Component is removed from the build and won't exist in the production version.

I have tested this in the Editor, Development build and non-development build. All seems to behave as expected with no side effects as far as I can tell. (I have only tested in Windows so far.)

If you need to identify GameObjects at runtime for whatever reason, simply remove the wrapped directive.

When you search for these Components, click on the magnifier icon or press Ctrl+K and type t:Decorative and only the Decorative GameObjects will be selected in the Scene. You do not even have to type the full name. Unity will try to match the GameObjects as you type.

As a bonus:

I also added it to the Component Menu in the Unity Editor so that all my Tag Components are nicely grouped together and easy to find in the Unity editor.

I added the [DisallowMultipleComponent] to avoid accidental duplicate "tags".

I also added it to a separate namespace to avoid polluting my existing namespace with useless classes. This keeps the intelli-sense clean as well.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .