В Иерархии у меня есть 3 объекта, которые я хочу сохранить и не уничтожить при запуске новой игры. Но я хочу уничтожить их при переключении обратно в главное меню.
Объекты: игрок, менеджер игр, загрузчик сцен
![Hierarchy](https://i.stack.imgur.com/3PI76.jpg)
На 3-х объектах Player, Game Manager, Scene Loader я добавил к каждому из них имя сценария PersistentManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PersistentManager : MonoBehaviour
{
public static PersistentManager Instance { get; private set; }
private void Awake()
{
if(Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
Сценарий Scene Loader, прикрепленный к Scene Loader:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class SceneLoader : MonoBehaviour
{
private bool loadScene = false;
[SerializeField]
private int scene;
[SerializeField]
private Text loadingText;
// Updates once per frame
void Update()
{
// If the player has pressed the space bar and a new scene is not loading yet...
if (Input.GetKeyUp(KeyCode.Space) && loadScene == false)
{
LoadScene(scene);
}
// If the new scene has started loading...
if (loadScene == true)
{
// ...then pulse the transparency of the loading text to let the player know that the computer is still working.
loadingText.color = new Color(loadingText.color.r, loadingText.color.g, loadingText.color.b, Mathf.PingPong(Time.time, 1));
}
}
// The coroutine runs on its own at the same time as Update() and takes an integer indicating which scene to load.
IEnumerator LoadNewScene()
{
// This line waits for 3 seconds before executing the next line in the coroutine.
// This line is only necessary for this demo. The scenes are so simple that they load too fast to read the "Loading..." text.
//yield return new WaitForSeconds(3);
// Start an asynchronous operation to load the scene that was passed to the LoadNewScene coroutine.
AsyncOperation async = SceneManager.LoadSceneAsync(scene);
// While the asynchronous operation to load the new scene is not yet complete, continue waiting until it's done.
while (!async.isDone)
{
yield return null;
}
}
public void LoadScene(int scene)
{
// ...set the loadScene boolean to true to prevent loading a new scene more than once...
loadScene = true;
// ...change the instruction text to read "Loading..."
loadingText.text = "Loading...";
this.scene = scene;
// ...and start a coroutine that will load the desired scene.
StartCoroutine(LoadNewScene());
}
}
И скрипт Game Manager, который прикреплен к Game Manager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public SceneLoader sceneLoader;
public PlayerController playerController;
public CamMouseLook camMouseLook;
public static bool backToMainMenu = false;
public static bool togglePauseGame;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.P))
{
PauseGame();
}
if (Input.GetKeyDown(KeyCode.Escape))
{
BackToMainMenu();
}
}
public void PauseGame()
{
togglePauseGame = !togglePauseGame;
if (togglePauseGame == true)
{
playerController.enabled = false;
camMouseLook.enabled = false;
Time.timeScale = 0f;
}
else
{
playerController.enabled = true;
camMouseLook.enabled = true;
Time.timeScale = 1f;
}
}
private void BackToMainMenu()
{
sceneLoader.LoadScene(0);
playerController.enabled = false;
camMouseLook.enabled = false;
Cursor.lockState = CursorLockMode.None;
Time.timeScale = 0f;
backToMainMenu = true;
}
}
Теперь, когда я запускаю игру, а затем нажимаю пробел для запуска новой игры, сцена главного меню удаляется, не зная, почему.
Перед использованием сценария PersistentManager я использовал для каждого из 3 объектов по одному сценарию:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DontDestroy : MonoBehaviour
{
private void Awake()
{
if (GameManager.backToMainMenu == false)
{
DontDestroyOnLoad(transform);
}
}
}
, который поддерживает 3 объекта при запуске новой игры и при переключении обратно в главное меню. проблема заключалась в том, что 3 объекта также были в главном меню при переключении обратно в главное меню.
Итак, у меня было 6 копий объектов. 3 в сцене главного меню и 3 в сцене DontDestroyOnLoad. Вот почему я пытаюсь использовать синглтон.
Я хочу, чтобы при переключении обратно в главное меню объект 3 не находился в сцене главного меню в иерархии только на DontDestroyOnLoad.