0
\$\begingroup\$

I want to deactivate a list of game objects in about 10 different scenes each time before the build process. I don't want them to be deactivated in the editor since these game objects are significant parts of the level. Currently, this deactivation process is done on awake, but this is too demanding for some CPUs and leads to stutters when reloading the scene.

So I was looking into "IPreprocessBuild" to do this just before I run the build process but I could not make it work.

How would you approach this?

\$\endgroup\$
6
  • \$\begingroup\$ Have you tried using the EditorOnly tag on these objects? \$\endgroup\$
    – DMGregory
    Dec 8, 2022 at 14:15
  • \$\begingroup\$ @DMGregory The EditorOnly tag actually has a functional effect? They don't cover that in the documentation. I always thought MainCamera was the only functional tag and the rest were just for the sake of example. \$\endgroup\$
    – Kevin
    Dec 9, 2022 at 18:55
  • \$\begingroup\$ @onemanonmars If you only need the objects in the Editor, it sounds like you can use DMGregory's solution. If you want the GameObjects to start inactive but then activate later, you should give more information. How many objects are there? What did you try with the IPreprocessBuild script? \$\endgroup\$
    – Kevin
    Dec 9, 2022 at 18:57
  • \$\begingroup\$ @Kevin one easy way to answer that question is to test: make a visible object in your start-up scene, add this tag, and build. If it's no longer visible in the build, you know this tag did something. I've just done this test and confirmed the tag works, so I've posted an answer about this - though I'm still not sure whether "remove these objects" is a valid solution to OP's use case, or if they'd prefer the objects to remain present-but-inactive. \$\endgroup\$
    – DMGregory
    Dec 9, 2022 at 19:27
  • 1
    \$\begingroup\$ @OneManOnMars What did you try with the IPreprocessBuild script and why didn't it work? \$\endgroup\$
    – Kevin
    Jan 2, 2023 at 23:38

2 Answers 2

1
\$\begingroup\$

But the EditorOnly Tag does not work for my case since these gameobjects are level parts that I will activate later. Therefore they need to be in the build but they should be deactivated when the scene loads.

The easiest way to do this is with a simple script:

public class HideOnAwake : MonoBehaviour {
    void Awake() {
        gameObject.SetActive(false);
    }
}

but this approach can have performance issues if there are a lot of objects to hide; it sounds like you already tried this and encountered those issues:

Currently, this deactivation process is done on awake, but this is too demanding for some CPUs and leads to stutters when reloading the scene.

One thing you could potentially try to is use the scene hierarchy to reduce how often you need to use this HideOnAwake script. For example, rather than putting HideOnAwake on 100 different objects, you might put the script on one parent object and then make the 100 different objects all children of that one parent. Deactivating the parent will also deactivate all of the children.

If that approach doesn't work, then a build script seems like the best approach to me. However, you haven't given us any information on what you tried with the build script or why it didn't work, so it's difficult to give you guidance in this area. Here's a rough outline of how you might approach it:

  1. Create a component script called HideForBuilds with no functionality: public class HideForBuilds : MonoBehaviour {}
  2. Attach HideForBuilds to each GameObject that should be hidden.
  3. Create a build script roughly along these lines:
public class BuildPreprocessor : IPreprocessBuildWithReport {
    private string[] scenePaths = { "Assets/Scene1.unity", "Assets/Scene2.unity" };
    public int callbackOrder { get { return 0; } }
    public void OnPreprocessBuild(BuildReport report) {
        //open each scene and hide the objects we want to hide
        foreach (var scenePath in scenePaths) {
            EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
            var objects = GameObject.FindObjectsOfType<HideForBuilds>();
            foreach (var obj in objects) {
                obj.gameObject.SetActive(false);
            }
            //save changes to scene
            EditorSceneManager.MarkAllScenesDirty();
            EditorSceneManager.SaveOpenScenes();
        }
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ Thank you very much for your reply. This seems to be the perfect solution. I was researching exactly along these lines but haven't worked out a final solution. So your script is very welcome! \$\endgroup\$ Jan 4, 2023 at 7:43
  • \$\begingroup\$ @OneManOnMars Great! If this answers your question, please mark it as the answer when you have a chance. \$\endgroup\$
    – Kevin
    Jan 5, 2023 at 23:21
0
\$\begingroup\$

One easy and efficient way to exclude objects from a built game is to tag them with the EditorOnly tag:

Inspector screenshot selecting EditorOnly from the tag list

Objects with this tag will be present when editing the game or previewing it in Play Mode, but will be stripped from the game during the build process so they are not present in the version of the game you distribute to players.

Because these objects are completely stripped out, there's no runtime cost to load them and then deactivate them at scene start-up.

However, it also means these objects are completely erased from the build, not just deactivated. So if you wanted the objects to be present but inactive (and possibly later activated), then a build pre-process is the way to go. If you need help with that, you should edit your question to show how you've tried to write your pre-process function and where specifically you've encountered difficulty making it work the way you want.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your reply and the idea. But the editorOnly tag will not work for me since I need these game objects in the game but they should be deactivated. Currently I do this by simply deactivate them on awake, but this leads to performance problems when reloading the scene. \$\endgroup\$ Dec 12, 2022 at 14:34
  • \$\begingroup\$ As I mentioned at the bottom of the answer then, can you edit your question to show us how you've tried using IPreprocessBuild for this and where you've gotten stuck? \$\endgroup\$
    – DMGregory
    Dec 12, 2022 at 16:48

You must log in to answer this question.

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