Copy one scene asset to the another by editor?

Hi,

I want to know if it possible to write an editor script to move an asset from one scene to the another one?
like

  • open scene
  • copy the current asset to memory
  • close scene
  • open another scene
  • paste asset
  • save scene
    by editor?

Thank you,

Yes, you can do that. At least I have some system to help me with this, though it is so entirely based on another system we have, so it won’t be able to work alone. But here are some key elements for you, at least as I have used them. Note that this could contain errors, as this hasn’t been tested on its own, but only as part of this bigger system. And you need to have the hierarchy window focused, before running this. Only use this to get some ideas!

EditorApplication.OpenScene("Whatever scene");

GameObject[] selection = new GameObject[1];
selection[0] = WhateverObject;
Selection.objects = selection;
EditorWindow.focusedWindow.SendEvent(EditorGUIUtility.CommandEvent("Copy"));
//Select
EditorApplication.OpenScene("Whatever other scene");

GameObject[] selection2 = new GameObject[1];
selection2[0] = WhateverObject2; //note, the pasted object won't be pasted UNDER this, but alongside this.
Selection.objects = selection2;

EditorWindow.focusedWindow.SendEvent(EditorGUIUtility.CommandEvent("Paste"));

EditorApplication.SaveScene();

Make a prefab of your object, place it in the other scene, then simply use the GameObject>Break Prefab Instance button to make it not a prefab

I spent today beating my head against this, but got it working! Code is below. In essence, mark objects you want to move to a new scene with Room/Mark Exportable from the menus. Once you have things marked, choose Room/Export to New Scene from the menu and you should in short order be looking at a fresh scene containing only the things you picked from the previous one.

public class Exportable : MonoBehaviour {
    void OnDrawGizmosSelected ()
    {
        var b = CalculateBounds (gameObject);
        Gizmos.DrawWireCube (b.center, b.size);
    }

    static Bounds CalculateBounds (GameObject obj) {
        var mrs = obj.GetComponentsInChildren<MeshRenderer> ();
        if (mrs.Length == 0) {
            // TODO(dichro): pass in a Bounds to operate on by reference.
            return new Bounds();
        }

        var b = new Bounds (mrs [0].bounds.center, mrs [0].bounds.size);
        foreach (var mr in mrs) {
            b.Encapsulate (mr.bounds.min);
            b.Encapsulate (mr.bounds.max);
        }
        return b;
    }

    [MenuItem ("Room/Mark Exportable #%r")]
    static void MarkExportable() {
        foreach (var obj in Selection.transforms) {
            if (obj.gameObject.GetComponent<Exportable> () == null) {
                obj.gameObject.AddComponent<Exportable> ();
                EditorSceneManager.MarkSceneDirty (EditorSceneManager.GetActiveScene ());
            }
        }
    }

    [MenuItem ("Room/Export to New Scene")]
    static void ExportToNewScene() {
        if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo ()) {
            return;
        }

        var exportScene = EditorSceneManager.GetActiveScene ();
        var exportRoot = new GameObject ("Imported");
        int exported = 0;
        foreach (var root in exportScene.GetRootGameObjects ()) {
            foreach (var exportable in root.GetComponentsInChildren<Exportable> ()) {
                var obj = Instantiate (exportable.gameObject);
                obj.transform.SetParent (exportRoot.transform);
                DestroyImmediate (obj.GetComponent<Exportable> ());
                exported++;
            }
        }

        if (exported == 0) {
            Debug.Log ("no exportable objects found?");
            DestroyImmediate (exportRoot);
            return;
        }

        var b = CalculateBounds (exportRoot);
        var prefab = PrefabUtility.CreatePrefab ("Assets/export.prefab", exportRoot);
        var importScene = EditorSceneManager.NewScene (NewSceneSetup.DefaultGameObjects);
        var importRoot = PrefabUtility.InstantiatePrefab (prefab, importScene) as GameObject;
        importRoot.transform.position = new Vector3 (-b.center.x, -b.min.y, -b.center.z);
    }
}