Coroutine stops for my friends

My 2D platformer has a coroutine that returns the player to the menu, it works fine for me, but when I send the game to my friends, some of them just get stuck on a black endless loading screen in the middle of the coroutine.
Coroutine:

IEnumerator ChapterExitCoroutine() {
            Time.timeScale = 0f;
            chM.chapterCurrent = -1;
            LeanTween.alpha(blackScreen, 1, 0.3f).setIgnoreTimeScale(true);
            LeanTween.alpha(loadingIcon, 1, 0.3f).setIgnoreTimeScale(true);
            mainMenu.ShowTip(0);
            if(chM.isChapterEnding) {
                chM.UpdateBestTime(0);
            }
            LeanTween.rotateAround(loadingIcon, new Vector3(0, 0, -360), 360, 2f).setEase(LeanTweenType.easeInOutQuart).setLoopClamp().setIgnoreTimeScale(true);
            yield return new WaitForSecondsRealtime(1.5f);
            StopCoroutine("SkipCutsceneCoroutine0");
            StopCoroutine("Ch0CutsceneCoroutine");
            StopCoroutine("Frame1ExtraCo");
            StopCoroutine("Frame3ExtraCo");
            StopCoroutine("Frame4ExtraCo");
            StopCoroutine("Frame6ExtraCo");
            StopCoroutine("Frame7ExtraCo");
            StopCoroutine("Frame7ExtraCheckpointCo");
            StopCoroutine("DogBarkCo");
            StopCoroutine("MoveBlackCatToCo");
            StopCoroutine("MoveOrangeCatToCo");
            Time.timeScale = 1f;
            mainMenu.gameObject.SetActive(true);
            mainMenu.canUseMenu = true;
            mainMenu.level0ButtonHB.SetActive(true);
            dogChase = false;
            angryDog.GetComponent<FakePlayerController>()._moveInput.x = 0;
            angryDog.SetActive(false);
            camM.FollowMode(false);
            for(int i = 0; i < chM.goldenFishes.Length; i ++) {
                chM.goldenFishes[i].ResetFishy();
                if(!chM.goldenFishes[i].isCollected) {
                    chM.goldenFishes[i].gameObject.SetActive(true);
                }
            }
            boxesWall.SetActive(false);
            if(player.transform.localScale.x == -1) {
                player.transform.localScale = new Vector3(1, player.transform.localScale.y, player.transform.localScale.z);
                playerControl.IsFacingRight = true;
            }
            chM.canUseCursor = true;
            Cursor.visible = chM.canUseCursor;
            LeanTween.cancel(player);
            player.GetComponent<PlayerController>().enabled = true;
            player.GetComponent<FakePlayerController>().enabled = false;
            player.GetComponent<Animator>().speed = 1;
            LeanTween.cancel(vCam.gameObject);
            LeanTween.cancel(mainCamera);
            LeanTween.cancel(girl);
            if(skipCut.gameObject.activeSelf) {
                skipCut.Reset();
            }
            zZZ.SetActive(false);
            pMenu.musicPause = false;
            chaseEndTrigger.SetActive(true);
            boxes[0].transform.localPosition = new Vector3(132.5f, 53.5f, 0);
            boxes[1].transform.localPosition = new Vector3(133.5f, 53.5f, 0);
            boxes[2].transform.localPosition = new Vector3(130.5f, 54.5f, 0);
            boxes[3].transform.localPosition = new Vector3(131.5f, 54.5f, 0);
            boxes[4].transform.localPosition = new Vector3(132.5f, 54.5f, 0);
            boxes[5].transform.localPosition = new Vector3(133.5f, 54.5f, 0);
            boxes[6].transform.localPosition = new Vector3(134.5f, 54.5f, 0);
            boxes[7].transform.localPosition = new Vector3(130.5f, 55.5f, 0);
            boxes[8].transform.localPosition = new Vector3(131.5f, 55.5f, 0);
            boxes[9].transform.localPosition = new Vector3(132.5f, 55.5f, 0);
            boxes[10].transform.localPosition = new Vector3(133.5f, 55.5f, 0);
            boxes[11].transform.localPosition = new Vector3(137.5f, 52.5f, 0);
            playerAnim.SetBool("ch0WakeUp", false);
            playerAnim.SetBool("isFalling", false);
            playerAnim.SetBool("isRunning", false);
            playerAnim.SetBool("isSleeping", false);
            playerControl.IsJumping = false;
            playerAnim.SetBool("isJumping", false);
            playerAnim.SetBool("ch0Windowfall", false);
            player.GetComponent<Rigidbody2D>().simulated = false;
            girl.GetComponent<Animator>().SetBool("armsOn", true);
            girl.GetComponent<Animator>().SetBool("armsUpOn", false);
            girl.GetComponent<Animator>().SetBool("armsPetOn", false);
            mainCamera.transform.localScale = new Vector3(1.18f, 1.18f, 1);
            vCam.gameObject.transform.position = new Vector3(0, 0, -200);
            vCam.GetComponent<CinemachineVirtualCamera>().GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>().m_AmplitudeGain = 0f;
            closet.SetBool("isClosed", false);
            window.SetBool("isOpened", false);
            door.SetBool("isOpened", false);
            girl.transform.localPosition = new Vector3(-1.5f, -1.793f, 0);
            pigeon.GetComponent<PigeonFlyAway>().PigeonReset();
            girl.transform.localScale = new Vector3(-1, 1, 1);
            windParticles.SetActive(false);
            aM.musicSource.time = 0;
            TutorialMoveStop();
            TutorialJumpStop();
            chM.canSave = true;
            chM.isPlaying = false;
            playerControl.canJump = false;
            playerControl.canRun = false;
            playerControl.canTurn = false;
            chM.menuIndex = 4;
            aM.musicSource.clip = aM.mainMenu;
            aM.SFXLoop1Source.mute = false;
            aM.ambientSource.mute = false;
            aM.SFXLoop1Source.clip = null;
            aM.ambientSource.clip = null;
            chM.currentCheckpoint = 0;
            aM.musicSource.Play();
            if(fishyCounter.gameObject.activeSelf) {
                fishyCounter.StopCounter();
            }
            if(camBor.gameObject.activeSelf) {
                camBor.Reset();
            }
            whiteCat.SetActive(true);
            blackCat.SetActive(true);
            orangeCat.SetActive(true);
            postPM.SetProfile(0);
            townBG.SetActive(true);
            whiteCat.GetComponent<FakePlayerController>()._moveInput.x = 0;
            orangeCat.GetComponent<FakePlayerController>()._moveInput.x = 0;
            blackCat.GetComponent<FakePlayerController>()._moveInput.x = 0;
            whiteCat.GetComponent<FakePlayerController>().autoJump = false;
            orangeCat.GetComponent<FakePlayerController>().autoJump = false;
            blackCat.GetComponent<FakePlayerController>().autoJump = false;
            whiteCat.GetComponent<FakePlayerController>().IsJumping = false;
            orangeCat.GetComponent<FakePlayerController>().IsJumping = false;
            blackCat.GetComponent<FakePlayerController>().IsJumping = false;
            angryDog.GetComponent<FakePlayerController>().IsJumping = false;
            whiteCat.transform.position = new Vector3(-63, 55.9f, 0);
            whiteCat.transform.localScale = new Vector3(1, 1, 1);
            blackCat.transform.position = new Vector3(3.5f, 52.5f, 0);
            orangeCat.transform.position = new Vector3(5.5f, 53.5f, 0);
            blackCat.transform.localScale = new Vector3(-1, 1, 1);
            orangeCat.transform.localScale = new Vector3(-1, 1, 1);
            blackCat.GetComponent<FakePlayerController>()._moveInput.x = 0;
            orangeCat.GetComponent<FakePlayerController>()._moveInput.x = 0;
            whiteCat.GetComponent<FakePlayerController>()._moveInput.x = 0;
            whiteCat.GetComponent<Rigidbody2D>().velocity = Vector2.zero;
            orangeCat.GetComponent<Rigidbody2D>().velocity = Vector2.zero;
            blackCat.GetComponent<Rigidbody2D>().velocity = Vector2.zero;
            blackCat.GetComponent<Animator>().SetBool("isSleeping", true);
            orangeCat.GetComponent<Animator>().SetBool("isSleeping", true);
            isCH0Extra1 = false;
            isCH0Extra3 = false;
            isCH0Extra4 = false;
            isCH0Extra6 = false;
            isCH0Extra7 = false;
            LeanTween.alpha(gameFade, 0, 0);
            dBox.Reset();
            aM.SFXSource.volume = 0.5f;
            aM.musicSource.volume = 0.5f;
            aM.defaultCutoffVal = 1f;
            aM.SetMusicCutOff(aM.defaultCutoffVal);
            player.GetComponent<FakePlayerController>().enabled = false;
            player.GetComponent<PlayerController>().enabled = true;
            LeanTween.alpha(loadingIcon, 0, 0.3f);
            mainMenu.HideTip();
            chM.HideTime();
            chM.Load();
            yield return new WaitForSeconds(0.5f);
            EpicGlowAppear(1, 0, 0);
            EpicGlowOutsideAppear(1, 0, 0);
            player.transform.position = new Vector3(-100.622f, 51.06f, 0);
            if(!playerControl.IsFacingRight) {
                playerControl.Turn();
            }
            LeanTween.alpha(blackScreen, 0, 0.3f);
            LeanTween.cancel(loadingIcon);
            loadingIcon.transform.rotation = new Quaternion(0, 0, 0, 0);
            if(chM.isChapterEnding && chM.chapterUnlocked == 0) {
                mainMenu.UnlockNextChapter();
            }
        }

It looks like you are trying to manually reset all of the game state. Would it be easier to simply reload the scene?

–

2 Answers

2

@dstears maybe this will work, but I need to go back to the level select page in the main menu instead of just starting the game (my game only uses one scene btw)

You could save some information in an object that is set to DontDestroyOnLoad and use that information to switch to the menu after the scene has reloaded. This object would also need to save any game state that you don’t want to lose when the scene reloads.

I typed up a quick example of what that might look like below, but I didn’t have time to test it:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManage : MonoBehaviour
{

    public static GameManage instance;
    private bool menu = false;

    private void Awake()
    {
        if(instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);

            //This tells the SceneManager to call our AfterSceneLoaded function after
            //the SceneManager has finished loading any scene.
            SceneManager.sceneLoaded += AfterSceneLoaded;
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void GoBackToMenu()
    {
        menu = true;

        //This will reload whatever scene is currently active
        string currentScene = SceneManager.GetActiveScene().name;
        SceneManager.LoadScene(currentScene);
    }

    public void AfterSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if(menu)
        {
            //Do whatever you need to do to bring up the level select
        }
    }
}