Can an object be set to only appear when a scene is launched directly in the editor?

A bit of background:

I’m currently creating a 2D game, and I’m making heavy use of additive scene loading. I have a primary scene containing most of my UI and generic manager objects. This then loads a ‘location’ scene, which can be unloaded and reloaded when the player changes screens. On top of this I can have a ‘utility’ screen for things like pop-up tutorial boxes or stand-alone mini games.

I hate messing around with ‘don’t destroy on load’ because I feel it breaks the hierarchy of my game.

However, this raises the following annoyance. I would like to be able to test my sub-scenes independently of the main one, and to use a UI canvas set to ‘Screen Space - Camera’, but I can’t have two EventSystem objects or Cameras at a time. This means if I want to test one of these sub-scenes in isolation, I have to manually add or activate these elements. Frankly, I don’t want the game to compile with any unwanted objects in the scene at all.

Is there a way I can mark objects so that they are only part of the scene if I’m running it directly from the editor, and are ignored by the compiler?

I do a lot of multi-scene additive tricks. The most sane thing seems to locate all of the “onesies” like a Main Camera and EventSystem only in one scene, and keep it consistent.

Just put a DestroyInProduction or somesuch Component on things you want to go away in a build. That will work and if it ultimately bugs you so much you can’t abide by those things going out the door, then write a pre-build script to iterate each scene and remove items flagged that way.

You really can also set up all kinds of crazy editor tooling to speed up your partial-scene iteration.

Just don’t make too much of a mess of things because it gets ticklish timing-wise.

As one silly example, you don’t even NEED scenes at all, with a construct like this:

using UnityEngine;

// @kurtdekker - for the purists who don't want ANY scenes in project
//
// All other Unity asset inclusion rules are still in effect, so no
// assets will make it into your project unless they are:
//
//	- correctly in a Resources/ folder
//	- referenced by something in the above
//	- correctly in the Streaming Assets folder / system.
//	- correctly bundled in Asset Bundles or Addressables

public class RunmeJohnny : MonoBehaviour
{
	// This is where it all begins. You will be called here the
	// moment the Unity Engine is up and running and ready for you.
	[RuntimeInitializeOnLoadMethod]
	static void StartWithNoScenes()
	{
		Camera cam = new GameObject("Camera").AddComponent<Camera>();
		cam.transform.position = new Vector3(0, 3, -10);
		cam.orthographic = false;
		cam.fieldOfView = 60.0f;

		// NOTE: the material on this cube will NOT be included
		// in the build because... you didn't reference it anywhere.
		//
		// You will need to get a material on this cube or
		// else it will be hot pink. See comment at top.
		GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
		// inject an instance of this script to get things started
		var runme = cube.AddComponent<RunmeJohnny>();
		runme.cube = cube;
	}

	// injected by the above (superfluous here, since it is ourselves,
	// but provided as a way to inject other scripts with with stuff)
	GameObject cube;

	private void Update()
	{
		float angle = Time.time * 100.0f;

		cube.transform.rotation = Quaternion.Euler(0, angle, 0);
	}
}
2 Likes

Cool, DestroyInProduction, that’s very likely what I’ve been looking for. Thanks, I will give it a try in the morning!