Unity Editor’s Stages and Scenes

Share on facebook
Facebook
Share on google
Google+
Share on twitter
Twitter
Share on linkedin
LinkedIn

Introduction

Recently I’ve been optimizing my Unity workflow and creating editor extensions to provide a consistent structure across my game. I’ve been working mainly to eliminate the opportunity for errors to arise from mistakes in the project’s structure. I was writing a script to reposition my SceneView camera using, 

SceneView.lastActiveSceneView.camera.transform

Which returns the transform of the scene view’s camera and that can be repositioned, lerped, rotated, pretty much anything. But while doing that I stumbled across the SceneView window that Unity has and upon this variable, SceneView.customScene. It’s hidden but when you look at the metadata for the class you can see protected values, these can only be changed from the SceneView itself and anything inheriting from it. 

Luckily Unity has some of their source code up on Github and you can view the entire SceneView.cs file. So what does this mean exactly? I was hoping it would be exactly what I thought it was, the ability to set the scene that the camera should be rendering for. This would allow me to create multiple Scene View windows for a particular scene, and even as a way to preview assets in real-time in an example scene. Imagine a prefab open previewing multiple different materials all running in simulating in real-time. Well, I managed to get some progress on it but am going to have to put this in the back burner because I’m not even sure what I want to do it possible given how Unity is engineered.

Here’s a screenshot of multiple prefabs each being previewed in their own Scene View. 

Preview Scenes and Stages 

So Unity’s been working in the background scenes, on literally background scenes, known as Preview Scenes. These scenes are rendered separately from the ‘Main’ scenes which are shown in your Hierarchy and in the Scene view. This is the type of scene that is used to load Prefabs. 

When you Edit a prefab you simply ‘Open’ the Asset. Literally, AssetDatabase.OpenAsset, is called when you double click an asset. By opening the prefab you enter the Prefab Stage, and a new stage is created, according to a developer on the Unity Prefabs team on the forum.

A view of the Prefab Stage.

Unity is working towards making this more modifiable and extendable and provides a Preview Scene Stage class that the Prefab Stage inherits from. This Preview Scene Stage is used to create a new Scene that is rendered and loaded separately from the game and managed by the EditorSceneManager. It also modifies the Scene View to expose a breadcrumb header (Similar but not the same breadcrumb header seen in the Project Window in ‘Two Column’ layout. 

Getting to the Code

First we’ll create a class that overrides the SceneView in order to add our own custom window logic in the future, and manage the Stage. 

Using the Menu Item attribute we’ll create a menu item to appear in the Context menu of the project window. We can achieve that using the Assets/ prefix which will restrict to appearing when right clicking asset files. 

We’ll restrict this to only appear when one ‘GameObject’ is selected. Then we’ll create a brand new window just for this game object preview, and set it up. We’ll disable drawing Gizmos in this view (but the window will display the regular scene view UI allowing for instant access). 

This is how the code is looking so far,

Next we’ll configure the window and create a Scriptable Object instance of our CustomPreviewStage that we’ll go over next. We’ll configure the stage than using the Stage Utility we’ll tell it to go to that stage. 

You can also hook onto the EditorWindow functions, OnFocus and OnLostFocus which do exactly what they say. We can stage/unstage accordingly so that we can have the hierarchy change depending on which window is active.

Here’s a video of the concept in action, 

 

Now we have our CustomPreview Stage that inherits from PreviewSceneStage just like the PrefabStage class does. To set it up we spawn in some lighting and the object we’re supposed to be previewing and use the stageUtility to place them into the active stage. 

To modify the Header and crumb title, simply override the function to create the GUI content for the header in your custom stage class, 

There’s also the ability to set the current scene for a PreviewSceneStage but it is only accessible inside the class so you have to make your own public setter to expose this variable to be modifiable outside the class.

Conclusion

I hope that I explained things correctly. This is what I believe is the correct way of doing things after looking through Unity’s internal c-sharp source code, available here, and forum posts. I’m surprised to not see more people working with tools that expand this area of the engine and hopefully this can serve as a guide for people looking to do that exact thing. Unfortunately for me the idea I had in mind, I’m not sure if it’d be feasible given the limitations of the ability to customize this feature but I can see it being useful in the future and will definitely try to incorporate these features somehow in the near future. 

More to explore