Я разрабатываю свою первую 2D-игру в Unity, и я столкнулся с тем, что кажется важным вопросом.
Как мне обрабатывать данные между сценами?
Там, кажется, разные ответы на это:
Кто-то упоминал об использовании PlayerPrefs , в то время как другие говорили мне, что это следует использовать для хранения других вещей, таких как яркость экрана и так далее.
Кто-то сказал мне, что лучший способ - записывать все в сохраненную игру каждый раз, когда я меняю сцены, и чтобы при загрузке новой сцены снова получать информацию из сохраненной игры. Это показалось мне расточительным в исполнении. Был ли я не прав?
Другое решение, которое я реализовал до сих пор, заключается в создании глобального игрового объекта, который не разрушается между сценами и обрабатывает все данные между сценами. Поэтому, когда игра начинается, я загружаю стартовую сцену, куда загружается этот объект. После этого он загружает первую настоящую игровую сцену, обычно главное меню.
Это моя реализация:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class GameController : MonoBehaviour {
// Make global
public static GameController Instance {
get;
set;
}
void Awake () {
DontDestroyOnLoad (transform.gameObject);
Instance = this;
}
void Start() {
//Load first game scene (probably main menu)
Application.LoadLevel(2);
}
// Data persisted between scenes
public int exp = 0;
public int armor = 0;
public int weapon = 0;
//...
}
Этот объект может быть обработан на других моих классах следующим образом:
private GameController gameController = GameController.Instance;
Хотя до сих пор это работало, у меня возникает одна большая проблема: если я хочу загрузить непосредственно сцену, скажем, например, финальный уровень игры, я не могу загрузить ее напрямую, так как эта сцена не содержит этого глобальный игровой объект .
Я справляюсь с этой проблемой неправильно? Есть ли лучшие практики для такого рода задач? Я хотел бы услышать ваше мнение, мысли и предложения по этому вопросу.
Спасибо
Идеальный способ хранения переменных между сценами - через класс синглтон-менеджера. Создав класс для хранения постоянных данных и установив для него класс
DoNotDestroyOnLoad()
, вы можете обеспечить его немедленный доступ и его сохранение между сценами.Другой вариант - использовать
PlayerPrefs
класс.PlayerPrefs
предназначен для сохранения данных между сеансами воспроизведения , но все равно будет служить средством сохранения данных между сценами .Используя одноэлементный класс и
DoNotDestroyOnLoad()
Следующий скрипт создает постоянный одноэлементный класс. Класс Singleton - это класс, предназначенный для одновременного запуска только одного экземпляра. Предоставляя такие функциональные возможности, мы можем безопасно создавать статические ссылки на себя, чтобы получить доступ к классу из любого места. Это означает, что вы можете напрямую обращаться к классу
DataManager.instance
, включая любые открытые переменные внутри класса.Вы можете увидеть синглтон в действии, ниже. Обратите внимание, что как только я запускаю начальную сцену, объект DataManager перемещается из заголовка, относящегося к сцене, в заголовок «DontDestroyOnLoad» в представлении иерархии.
Используя
PlayerPrefs
классUnity имеет встроенный класс для управления основными постоянными данными
PlayerPrefs
. Любые данные, сохраненные вPlayerPrefs
файле, будут сохраняться в течение игровых сеансов , поэтому, естественно, они способны сохранять данные в разных сценах.PlayerPrefs
Файл может хранить переменные типовstring
,int
иfloat
. Когда мы вставляем значения вPlayerPrefs
файл, мы предоставляем дополнительныйstring
ключ. Мы используем тот же ключ для последующего извлечения наших значений изPlayerPref
файла.Обратите внимание, что я принимаю дополнительные меры предосторожности при работе с
PlayerPrefs
файлом:private static string
. Это позволяет мне гарантировать, что я всегда использую правильный ключ, и это означает, что если мне по какой-либо причине придется менять ключ, мне не нужно обязательно менять все ссылки на него.PlayerPrefs
файл на диск после записи на него. Это, вероятно, не будет иметь значения, если вы не реализуете постоянство данных во время сеансов воспроизведения.PlayerPrefs
будет сохранить на диск во время обычного приложения близко, но он не может естественно назвать , если ваша игра вылетает.PlayerPrefs
, прежде чем пытаться получить значение, связанное с ним. Это может показаться бессмысленной двойной проверкой, но это хорошая практика.Delete
метод, который сразу стираетPlayerPrefs
файл. Если вы не намерены включать постоянство данных в сеансы воспроизведения, вы можете включить этот методAwake
. СнявPlayerPrefs
файл в начале каждой игры, вы убедитесь , что все данные , которые так упорствуют из предыдущей сессии не ошибочно обрабатывается как данные из текущей сессии.Вы можете увидеть
PlayerPrefs
в действии, ниже. Обратите внимание, что когда я нажимаю «Сохранить данные», я напрямую вызываюSave
метод, а когда я нажимаю «Загрузить данные», я напрямую вызываюLoad
метод. Ваша собственная реализация, вероятно, будет отличаться, но она демонстрирует основы.В заключение, я должен отметить, что вы можете расширить базовые возможности
PlayerPrefs
для хранения более полезных типов. JPTheK9 дает хороший ответ на аналогичный вопрос , в котором они предоставляют сценарий для сериализации массивов в строковую форму, которая будет храниться вPlayerPrefs
файле. Они также указывают нам на вики-сайт Unify Community , где пользователь загрузил более обширныйPlayerPrefsX
скрипт для поддержки большего разнообразия типов, таких как векторы и массивы.источник