For some reason it's destroying the portal

I pass the creating and transporting between scene with no problem, i at some point even manage to spawn correctly on the spawn point, when i went to try to apply the NavMeshAgent solution #2, to see it in action, one of the portals broke but the other not, so i through it was just a problem of that one, so i re-put it on the scene, set up everything as it was and now both are broken.
The console is throwing me the following warning

DontDestroyOnLoad only works for root GameObjects or components on root GameObjects.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
RPG.SceneManagement.Portal/<Transition>d__3:MoveNext () (at Assets/Scripts/SceneManagement/Portal.cs:20)
UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
RPG.SceneManagement.Portal:OnTriggerEnter (UnityEngine.Collider) (at Assets/Scripts/SceneManagement/Portal.cs:15)

I don’t get why im having a problem with the DontDestroyOnLoad and StartCoroutine. Here is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.AI;//For problems with NavMeshAgent.
using RPG.Core;

namespace RPG.SceneManagement{
    public class Portal : MonoBehaviour{
        [SerializeField] int sceneToLoad = -1;
        [SerializeField] Transform spawnPoint;

        private void OnTriggerEnter(Collider other) {
            if(other.tag == "Player"){
                StartCoroutine(Transition());
            }
        }

        private IEnumerator Transition(){
            DontDestroyOnLoad(gameObject);
            yield return SceneManager.LoadSceneAsync(sceneToLoad);

            Portal otherPortal = GetOtherPortal();
            UpdatePlayer(otherPortal);

            Destroy(gameObject);
        }

        private Portal GetOtherPortal(){

            foreach(Portal portal in FindObjectsOfType<Portal>()){
                
                if(portal == this) continue;

                return portal;
            }

            return null;
        }

        private void UpdatePlayer(Portal otherPortal){
            GameObject player = GameObject.FindWithTag("Player");

            //Solution if you don't have problems with NavMeshAgent
            player.transform.position = otherPortal.spawnPoint.position;
            player.transform.rotation = otherPortal.spawnPoint.rotation;

            //Solution #1 through NavMeshAgent
            // player.GetComponent<NavMeshAgent>().enabled = false;
            // player.transform.position = otherPortal.spawnPoint.position;
            // player.transform.rotation = otherPortal.spawnPoint.rotation;
            // player.GetComponent<NavMeshAgent>().enabled = true;

            //Solution #2 for NavMeshAgent simplest solution
            // player.GetComponent<NavMeshAgent>().Warp(otherPortal.spawnPoint.position);
            // player.transform.rotation = otherPortal.spawnPoint.rotation;
        }
    }
}

I like to keep comments in this kind of tutorial courses to come back to remember sub-optimal, and optimal set ups, in case i may need then. But in this case none are working, and i don’t get the root of the problem, a warning shouldn’t be creating this much of a problem.

Check your hierarchy. Did you put the portals as a child of an empty game object? Portals need to be in the root of the scene hierarchy to have DontDestroyOnLoad work correctly.

1 Like

Yeah, apparently i did… The only place where i try to be organize (Programming in general), and it bites me in the butt. Thanks for the help

This first line in the warning stack says it all (it realy should turn up as an Error, but my attempts to convince Unity of that in the past have failed).

Your Portal cannot be the child of any other GameObject within the scene, or when we DontDestroyOnLoad() it throws that annoying warning and then proceeds to ignore the instruction. This means that once the new scene loads, the Portal is destroyed, taking the Coroutine with it.

@Maxy_Grosman, I found a fix in another post. I could not find the thread again this morning, but here is what I added to the portal.cs script. In Transition() add

transform.parent = null;

right before

DontDestroyOnLoad(gameObject);

Then you can move the portals to a Portals empty game object. It worked well in my project.

Privacy & Terms