Wednesday 28 July 2021

Unity editor scripting (part 4): basic scene management

If you have lot of assets in your project, and multiple scenes in particular, it can be hard to navigate between them.

I've encountered two basic problems while working in Unity:
1) doing something (or checking something) in multiple scenes
2) running a particular scene which is required to run for your game (for instance, it loads all assets), while working on another one.

This is where editor scripts come to the rescue :)

In the following code I'll show how to create a tool for iterating over enabled scenes (and logging their root count object as an example), and another - for simply running some chosen scene.

Create a file ScenesHelper.cs and put it in Assets/Editor folder of your project.

The code is simple:

using UnityEditor;
using System.Linq;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

class ScenesHelper
{
    static EditorBuildSettingsScene[] GetEnabledScenes()
    {
        return  EditorBuildSettings.scenes
          .Where(s => s.enabled).ToArray();
    }

    static string[] GetEnabledSceneNames()
    {
        var scenes = GetEnabledScenes()
            .Select(s => s.path)
            .ToArray();

        return scenes;
    }
    
    [MenuItem("Tools/Iterate over scenes. %#p")]
    static void Iterate()
    {
        foreach (string s in GetEnabledSceneNames())
        {
            Scene scene = EditorSceneManager.OpenScene(s);
            Debug.Log("Root object count in scene" + 
                scene.name 
                + ": " + scene.rootCount);
        }
    }

    [MenuItem("Tools/Play particular scene. %#o")]
    static void PlayScene2()
    {
        EditorSceneManager.OpenScene(
            GetEnabledSceneNames()[2]);
        EditorApplication.isPlaying = true;
    }

}

The method GetEnabledScenes() returns all enabled scenes (by omitting the Where clause you can also include those not enabled), or to be precise - objects of class EditorBuildSettingsScene , which represents scenes "identifiers" in editor build settings. 
The method GetEnabledSceneNames() returns their paths/names (retrieved via Linq Select).

Then we have the method Iterate()  (available from the Tools menu or via Ctrl+Shift+P shortcut) which iterates over all the enabled scenes (using their names) and logs the root objects count for each of them, and  PlayScene2() (Tools menu or Ctrl+Shift+O) which makes the editor play the second scene in our list.

Please note opening a scene in  Iterate() uses Scene class object, returned by EditorSceneManager.OpenScene(s) - it's not the same as EditorBuildSettingsScene. The former represent Unity scenes with objects, which can be inspected or played, the latter is sort of id of a scene in editor build settings.

No comments:

Post a Comment

Python crash course part 10: inheritance and polymorphism

In the last part we've shown how to create and use a class in Python. Today we're going to talk about inheritance: wchich means cre...