Search code examples
c#unity-game-engine

Move/Transfer GameObject to another scene


We tryed different ways to move UI-object to another scene, but we failed. Over object is in Canvas.

Method 1: we used LoadLevelAdditive, but there moved all objects from first scene without over Canvas with it's elements.

Method 2: we used DontDestroyOnLoad. We need to change our element on Canvas. DDOL save last position on the scene, but we can't change object at all.


Solution

  • Don't use Application.LoadLevelXXX. These are deprecated functions. If you are using old version of Unity, please update it otherwise, you may not be able to use the solution below.

    First, load scene with SceneManager.LoadSceneAsync. Set allowSceneActivation to false so that the scene won't activate automatically after loading.

    The main solution to your problem is the SceneManager.MoveGameObjectToScene function which is used to transfer GameObject from one scene to another. Call that after loading the scene then call SceneManager.SetActiveScene to activate the scene. Below is an example of that.

    public GameObject UIRootObject;
    private AsyncOperation sceneAsync;
    
    void Start()
    {
        StartCoroutine(loadScene(2));
    }
    
    IEnumerator loadScene(int index)
    {
        AsyncOperation scene = SceneManager.LoadSceneAsync(index, LoadSceneMode.Additive);
        scene.allowSceneActivation = false;
        sceneAsync = scene;
    
        //Wait until we are done loading the scene
        while (scene.progress < 0.9f)
        {
            Debug.Log("Loading scene " + " [][] Progress: " + scene.progress);
            yield return null;
        }
        OnFinishedLoadingAllScene();
    }
    
    void enableScene(int index)
    {
        //Activate the Scene
        sceneAsync.allowSceneActivation = true;
    
    
        Scene sceneToLoad = SceneManager.GetSceneByBuildIndex(index);
        if (sceneToLoad.IsValid())
        {
            Debug.Log("Scene is Valid");
            SceneManager.MoveGameObjectToScene(UIRootObject, sceneToLoad);
            SceneManager.SetActiveScene(sceneToLoad);
        }
    }
    
    void OnFinishedLoadingAllScene()
    {
        Debug.Log("Done Loading Scene");
        enableScene(2);
        Debug.Log("Scene Activated!");
    }