Scenes loading multiple times when passing the portal

Hi folks,
if I passing the portal, the scene will loading multiple times until it load the right scene, and without stuff in the inventory.
If I run through the portal trigger and don`t stop in the trigger range, after the transition i am back in the scene before, but the saving file has the save data from the other scene.
If I use the portals without saving it work fine.
I checked that I have only once the Fader, SavingWrapper und Savingsystem. And the link is correct.
I use a gamepad direct movement, thats why I don’t need the navmeshAgent. I tried out with the NavmeshAgent but there is the same issue.
Here the Portal code:

public class Portal : MonoBehaviour
    {
        enum DestinationIdentifier
        {
            A, B, C, D, BurgSchauenberg, BurgFideliegg, HausAlteFrau
        }

        [SerializeField] string sceneToLoad = null;
        [SerializeField] Transform spawnPoint;
        [SerializeField] DestinationIdentifier destination;
        [SerializeField] float fadeOutTime = 3f;
        [SerializeField] float fadeInTime = 3f;
        [SerializeField] float fadeWaitTime = 0.5f;


        private void OnTriggerEnter(Collider other)
        {
            if (other.CompareTag("Player"))
            {
                print("Player has entered portal " + gameObject.name + gameObject.GetInstanceID());
                StartCoroutine(Transition());
            }
        }

        private IEnumerator Transition()
        {
            if (sceneToLoad == null)
            {
                Debug.Log("Scene to load not set!");
                yield break;
            }
           

            // We take the portal object into the next scene
            DontDestroyOnLoad(gameObject);

            // We fade out the Scene
            Fader fader = FindObjectOfType<Fader>();
            yield return fader.FadeOut(fadeOutTime);

            // We save the current level
            SavingWrapper savingWrapper = FindObjectOfType<SavingWrapper>();
            savingWrapper.Save();

            yield return SceneManager.LoadSceneAsync(sceneToLoad);

            // Load current level
            savingWrapper.Load();
          
            Portal otherPortal = GetOtherPortal();
            UpdatePlayer(otherPortal);

            savingWrapper.Save();

            // Time between the Scenes
            yield return new WaitForSeconds(fadeWaitTime);
           
            // fade in
            yield return fader.FadeIn(fadeInTime);

            Destroy(gameObject);
        }

        private void UpdatePlayer(Portal otherPortal)
        {
            GameObject player = GameObject.FindWithTag("Player");
           
            player.GetComponent<CharacterController>().enabled = false;
            player.transform.position = otherPortal.spawnPoint.position;            
            player.transform.rotation = otherPortal.spawnPoint.rotation;
            player.GetComponent<CharacterController>().enabled = true;
        }

        private Portal GetOtherPortal()
        {
            foreach (Portal portal in FindObjectsOfType<Portal>())
            {
                if (portal == this) continue;
                if (portal.destination != destination) continue;
                return portal;
            }
            return null;
        }

image

Thanks in advanced :hugs:

Paste in your copy of the SavingWrapper.cs

I suspect your character is running when the new scene is loaded and triggers the portal again before the fade is done. You may want to disable controls when the portal is triggered

The SavingWrapper.cs

public class SavingWrapper : MonoBehaviour
    {
        const string defaultSaveFile = "save";
        [SerializeField] private float fadeInTime = 4f;

        
        IEnumerator Start() 
        {
            Fader fader = FindObjectOfType<Fader>();
            fader.FadeOutImmediate();
            yield return GetComponent<JsonSavingSystem>().LoadLastScene(defaultSaveFile);
            yield return fader.FadeIn(fadeInTime);
        }
        
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.L))
            {
                Load();                
            }

            if (Input.GetKeyDown(KeyCode.J))
            {
                Save();
            }

            if (Input.GetKeyDown(KeyCode.Delete))
            {
                Delete();
            }
        }

        public void Delete()
        {
            GetComponent<JsonSavingSystem>().Delete(defaultSaveFile);
        }

        public void Save()
        {
            GetComponent<JsonSavingSystem>().Save(defaultSaveFile);
        }

        public void Load()
        {
            StartCoroutine(GetComponent<JsonSavingSystem>().LoadLastScene(defaultSaveFile));   
        }
    
    }    

I creat a short video (Portal problem) you can download from WeTransfer (35MB).
This show the problem:
Portal problem
And I don’t think the player is still running at the portal because the movements are done directly by keyboard or gamepad. But I will tri out to disable the controlls when entering the portal.
Also I’ve put the spawn points really far away. This shouldn’t be the problem.

I looked at the video. Are your portals correct? On the map scene, when you go to Schauenberg it immediately loads map again. This doesn’t look right to me.

It also looks like the character is spawning right inside the trigger


This is from the video. You can see he’s standing inside the portal


Edit
How the portals should be set up
In the Fidelgiegg scene, the portal should have
sceneToLoad = build index of the Map scene
destination = something, let’s say A

In the Map scene, the Fideliegg portal should have
sceneToLoad = build index of the Fideliegg scene
destination = the same value that was set in the Fideliegg scene - A

In the Schauenberg scene, the portal should have
sceneToLoad = build index of the Map scene
destination = something other than what’s in Fideliegg, let’s say B

In the Map scene, the Schauenberg portal should have
sceneToLoad = build index of the Schauenberg scene
destination = the same value that was set in the Schauenberg scene - B


Another Edit
I believe there is a bug (search the forums, you may find mention) when the character’s position in the source scene happens to match a portal trigger in the target scene. The scene is loaded before the character is moved to the spawn point, so it may trigger that portal.

Hi bixarrio
Thank you very mutch taking time for my problem!!!
So I resetup my portals and yes the player was not more in the portal inside. Maybe he don’t like if SceneToLoad and Destination has the same Name.
But still I have the problem. So I tried out; I setup the portals directly from scene “Fideliegg” to scene “Schauenberg”, because the Map scene is very smal and I thought can be the problem.
I find out the source Portal don’t destroy. And I have still the Problem.
Portal from source scene “Fideliegg”:


Portal scene “Schauenberg”

The Spawn point from portal “Schauenberg”
Spawn point Schauenberg
greeting

Can you show the fader code? I don’t know what your fade code looks like but it looks like the FadeIn didn’t complete.

Fader.cs

namespace BS.SceneManagement
{
    public class Fader : MonoBehaviour
    {

        CanvasGroup canvasGroup;

        // bei Problemen Awake ausprobieren!!
        private void Awake() 
        {
            canvasGroup = GetComponent<CanvasGroup>();

            //StartCoroutine(FadeOutIn()); Beispiel für Nestet coroutine siehe unten.
        }

        public void FadeOutImmediate()
        {
            canvasGroup.alpha = 1;
        }        

        public IEnumerator FadeOut(float time)
        {
            while (canvasGroup.alpha < 1) // alpha is not 1
            {
                // moving alpha toward 1
                canvasGroup.alpha += Time.deltaTime / time;
                yield return null;
            }
        }

        public IEnumerator FadeIn(float time)
        {
            while (canvasGroup.alpha > 0) // alpha is not 0
            {
                // moving alpha toward 0
                canvasGroup.alpha -= Time.deltaTime / time;
                yield return null;
            }
        }



        /* Das ist nur ein Beispiel für "Nested Coroutines"

        IEnumerator FadeOutIn()
        {
            yield return FadeOut(3f);
            print("faded out");
            yield return FadeIn(2f);
            print("faded in");
        }*/
    }
}

Again, if I use the portals without saving (see picture) they works perfect.

Here is the console log if I use the Portals without the Savingwrapper in the portal code.
I put a log for FadeIn and FadeOut and when I enter the portal.
Consol log without savingwrapper

I asked because I saw this
image
without corresponding ones for ‘Fade in’. But I also don’t see those in the script so I don’t know where they come from.

BUT… @Brian_Trotter had the right idea all along and I should’ve let the master take this one…

In the SavingWrapper's Load() you are calling LoadLastScene(). You should not. This is loading the scene you just came from. You should just be calling the Load().

Hi bixarrio, Hi Brian
This Coroutines comes from some objects who gets transparent if they have a specific range to the camera. It’s my code.
So I’ve done the change. And it woooorks!!! :hugs: :hugs:
I will send you a Steamkey when my game is released/early access.

Thanks thousand times.

Sorry it took so long to get back to you on this one.
So this particular version of the script contains a slight bug, related to the L)oad key… At some point, Sam changed the code in Load() to reload the last scene, instead of the original code that loaded the variables in the scene. (This was actually the first attempt to fix a different bug, LOL).

In SavingWrapper.Update(), change the contents of the if(Input.GetKeyDown(L)) block with

StartCoroutine(GetComponent<JSonSavingsystem>().LoadLastScene(defaultSaveFile));

Now in the public void Load(), change the contents of the method to read

GetComponent<JsonSavingSystem>().Load(defaultSaveFile);

What’s happening is that Fader calls Load() which starts a LoadLastScene() which reloads everything, but we haven’t saved the scene we’ve transitioned to yet, so the scene is loaded that we just left effectively ending the coroutine, which has the character standing on the portal’s collider, which loads the new scene, starting the chain all over again.

I understand.
So it looks now like this: SavingWrapper

void Update()
        {
            if (Input.GetKeyDown(KeyCode.L))
            {
                StartCoroutine(GetComponent<JsonSavingSystem>().LoadLastScene(defaultSaveFile));
            }

            if (Input.GetKeyDown(KeyCode.J))
            {
                Save();
            }

            if (Input.GetKeyDown(KeyCode.Delete))
            {
                Delete();
            }
        }

        public void Delete()
        {
            GetComponent<JsonSavingSystem>().Delete(defaultSaveFile);
        }

        public void Save()
        {
            GetComponent<JsonSavingSystem>().Save(defaultSaveFile);
        }

        public void Load()
        {
            GetComponent<JsonSavingSystem>().Load(defaultSaveFile);   
        }

Now it works perfect !!!
Thanks very much taking time for me.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms