简体   繁体   中英

In Unity, I want to change the scene and then change the text displayed, but the scene change always happens last

I'm a beginner and this is my first post here so please let me know if I could do anything better.

Using PUN 2 in Unity, I'm trying to return a connection error message when the user attempts to connect to a Photon server but fails.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //Library that provides utilities for scene management
using Photon.Pun; //Library for Photon, provides networking utilities 
using Photon.Realtime; //Helps solve problems relating to matchmaking and fast communication
using UnityEngine.UI; // 

public class MenuMan : MonoBehaviourPunCallbacks
{

    public override void OnDisconnected(DisconnectCause cause) //Callback for when device fails to connect to server. Parameter 'cause' is the cause of this failure
    {
        Debug.Log("failed :("); // FOR DEBUGGING 
        Debug.Log(cause); //Prints in the console the cause of this connection failure
        DisplayErrorMessage();
    }

    public Text Message;
    public string MessageValue = " ";



    public void DisplayErrorMessage() //Method that displays a connection error message to the user
    {
        SceneManager.LoadScene("Character Select Menu"); //Ensures user is on the Character Select menu

        MessageValue = "AAAAAAA";
        //Message.text = MessageValue;
        Debug.Log(Message.text);
        Debug.Log(MessageValue);

    }

}

When I run this code, the text "AAAAA" flashes for a second, then disappears. Through testing I found out this is because the message displays first for some reason, and only after does the scene change thus resetting the text.

I tried using coroutines to delay MessageValue from being altered until the scene changed:

   public override void OnDisconnected(DisconnectCause cause) //Callback for when device fails to connect to server. Parameter 'cause' is the cause of this failure
   {

       StartCoroutine(GoToCSM());
       DisplayErrorMessage();

   }


   IEnumerator GoToCSM()
   {
       Debug.Log("cor started");
       SceneManager.LoadScene("Character Select Menu")
       yield return new WaitForSeconds(3);
       DisplayErrorMessage();
       Debug.Log("Done");

   }


   public Text Message; //Initialises a 'Text' type object, which will be set to the Connection fail message
   static string MessageValue = " "; //Initialises a string which will be written to the 'text' component of the above object

   public void DisplayErrorMessage() //Method that displays a connection error message to the user
   {
       MessageValue = "AAAAAAA"; //Writes the string to be displayed to MessageValue 
       Message.text = MessageValue; //Sets the above text to the 'text' component of the Message object, thus displaying it on the screen
   }

However the coroutine never goes past the yield statement. It just stops at the yield statement and doesn't continue (even the Debug.Log("Done") doesn't get logged).

But when I tried switching some things round and put SceneManager.LoadScene("Character Select Menu") beneath the yield statement, that was executed just fine, as well as the debug statement below. I have no idea why this could be, and am very confused.

This was meant to be an extremely simple 10 minute task and I've wasted days trying to figure out what to do now. Any help would be extremely greatly appreciated. Thank you!

When switching scenes the object running the coroutines gets destroyed. Which results in it never executing the delayed code in the coroutines, this also applies when loading the same scene as you have currently loaded. Unity reloads the whole scene, it resets everything. This is also the reason why you see the text flashing for a few seconds, You set the text of some component in your scene. then unity reloads it and its reset. SceneManager.LoadScene is not instant it just tells unity to start loading the Scene and then switching to it when ready. Which by the way is not a very performant thing to do and should only be done when you need to really reset it.

If you want to pass values such as cause of disconnection from one scene to another you should use static variables. These are not stored in objects(that get deleted on scene load). They are static and get saved when switching scenes.

It would help if you shared some more details about the structure of your project. That can help us find a solution that suits your needs.

I hope this helps. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM