Bill's
Spills

Bilal Akil

Unity Editor Hack 1: Change All Game Objects in All Scenes

This is an editor script which adds a menu button to execute the below function. It was a one-off use thing, to help me clean up my scenes.

Here I'm ensuring the Z position of all game objects are 0 (except for two hard-coded exceptions). The fix action is recursive, and is what actually does the change to all of the objects. That's where you'll want to change things to suit your own needs - just keep that loop in at the end so the recursion can work.

The code will:

  • Find all scenes
  • Open scenes in the editor
  • Loop through all scene root game objects
  • Recurse through all child objects
  • Save a scene
using System;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;

public static class DataHacks
{
    [MenuItem("Kubblammo/Advanced/Do Data Hacks")]
    static void Do()
    {
        var changes = 0;

        var originalScene = EditorSceneManager.GetActiveScene().path;

        foreach (var sceneGUID in AssetDatabase.FindAssets("t:Scene", new string[] { "Assets" }))
        {
            var scenePath = AssetDatabase.GUIDToAssetPath(sceneGUID);

            EditorSceneManager.OpenScene(scenePath);
            var scene = EditorSceneManager.GetActiveScene();

            var hasChanges = false;

            Action fix = null;
            fix = (obj) => {
                var tfm = obj.transform;
                var pos = tfm.localPosition;
                var correct = new Vector3(pos.x, pos.y, 0f);

                if (correct != pos)
                {
                    tfm.localPosition = correct;

                    EditorUtility.SetDirty(obj);
                    ++changes;
                    hasChanges = true;

                    Debug.Log(scenePath + " ... " + obj);
                }
                
                for (var i = tfm.childCount - 1; i != -1; --i)
                    fix(tfm.GetChild(i).gameObject);
            };

            foreach (var obj in scene.GetRootGameObjects())
            {
                if (obj.name == "MainCamera" || obj.name == "GameplayUI") continue;

                fix(obj);
            }

            if (hasChanges) EditorSceneManager.SaveScene(scene);
        }

        if (originalScene != "") EditorSceneManager.OpenScene(originalScene);

        Debug.Log(String.Format("{0} changes made", changes));
    }
}

Questions? Please discuss on Twitter or Reddit.