Unity-передача данных между сценами

Как я могу передать значение из одной сцены в другую?

Я пробовал следующие:

сцена первая:

void Start () {
    score = 0;
    updateScoreView ();
    StartCoroutine (DelayLoadlevel(20));
}

public void updateScoreView(){
    score_text.text = "The Score: "+ score;
}

public void AddNewScore(int NewscoreValue){
    score = score + NewscoreValue;
    updateScoreView ();
}

IEnumerator DelayLoadlevel(float seconds){        
    yield return new WaitForSeconds(10);
    secondsLeft = seconds;
    loadingStart = true;
    do {        
        yield return new WaitForSeconds(1);
    } while(--secondsLeft >0);

    // here I should store my last score before move to level two
    PlayerPrefs.SetInt ("player_score", score);
    Application.LoadLevel (2);
}

Сцена вторая:

public Text score_text;
private int old_score;

// Use this for initialization
void Start () {    
    old_score = PlayerPrefs.GetInt ("player_score");
    score_text.text = "new score" + old_score.ToString ();      
}

но ничего не отображается на экране, и нет никакой ошибки.

это правильный способ передачи данных ?

Я использую Unity 5 free edition, разрабатываю игру для Gear VR (то есть игра будет работать на устройствах android).

любой предложение?

2 ответов


кроме playerPrefs еще один грязный способ-сохранить объект во время загрузки уровня, вызвав DontDestroyOnLoad на нем.

DontDestroyOnLoad (transform.gameObject);

любой скрипт, прикрепленный к игровому объекту, выживет, а также переменные в скрипте. Функция DontDestroyOnLoad обычно используется для сохранения всего GameObject, включая компоненты, прикрепленные к нему, и любые дочерние объекты в иерархии.

вы можете создать пустой GameObject и разместить только скрипт, содержащий переменные, которые вы хотите сохранить на нем.


здесь 3 способы сделать это, но решение этого зависит от типа данных, которые вы хотите передать между сценами. Компоненты / скрипты и GameObjects уничтожаются при загрузке новой сцены и даже если они помечены как static.

1. Используйте static ключевое слово.

используйте этот метод, если переменная для перехода к следующей сцене не является компонентом, делает не наследовать от MonoBehaviour и не GameObject затем сделайте переменную static.

встроенные примитивные типы данных, такие как int, bool, string, float, double. Все эти переменные можно сделать static переменной.

пример встроенных примитивных типов данных, которые can отметить как static:

static int counter = 0;
static bool enableAudio = 0;
static float timer = 100;

они должны работать без проблем.


пример объектов, которые can будет помечен как static:

public class MyTestScriptNoMonoBehaviour
{

}

затем

static MyTestScriptNoMonoBehaviour testScriptNoMono;

void Start()
{
    testScriptNoMono = new MyTestScriptNoMonoBehaviour();
}

обратите внимание, что класс не наследует от MonoBehaviour. Это должно сработать.


пример объектов, которые не может отметить как static:

все, что наследуется от Object, Component или GameObject будет не работа.

1A.Все, что наследуется от MonoBehaviour

public class MyTestScript : MonoBehaviour 
{

}

затем

static MyTestScript testScript;

void Start()
{
    testScript = gameObject.AddComponent<MyTestScript>();
} 

это не работа, потому что она наследуется от MonoBehaviour.

1B.Все!--102-->GameObject:

static GameObject obj;

void Start()
{
    obj = new GameObject("My Object");
}  

это не работает, потому что это GameObject и GameObject наследовать от Object.

единство всегда будет разрушать его Object даже если они объявлены с static ключевое слово.

посмотреть #2 для решения проблемы.


2.Используйте DontDestroyOnLoad функции.

вам нужно использовать это только в том случае, если данные для сохранения или передачи в следующую сцену наследуются от Object, Component или GameObject. Это решает проблему, описанную в 1A и 1B.

вы можете использовать его, чтобы сделать этот объект не уничтожать при выгрузке:

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

вы даже можете использовать его с static ключевое слово решить проблему из 1A и 1B:

public class MyTestScript : MonoBehaviour 
{

}

затем

static MyTestScript testScript;

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

void Start()
{
    testScript = gameObject.AddComponent<MyTestScript>();
} 

на testScript переменной теперь будет сохраняется при загрузке новой сцены.

3.Сохранить в локальное хранилище, а затем загрузить во время следующей сцены.

этот метод следует использовать, когда это данные игры, которые должны быть сохранены при закрытии и повторном открытии игры. Примером этого является высокий балл игрока, настройки игры, такие как громкость музыки, местоположения объектов, данные профиля джойстика и так далее.

Thare два способа сохранить это:

3A.Используйте PlayerPrefs API-интерфейс.

используйте, если у вас есть только несколько переменных для сохранения. Скажем, оценка игрока:

int playerScore = 80;

и мы хотим сохранить playerScore:

сохранить счет в OnDisable функции

void OnDisable()
{
    PlayerPrefs.SetInt("score", playerScore);
}

загрузите его в OnEnable функции

void OnEnable()
{
    playerScore  =  PlayerPrefs.GetInt("score");
}

3B.Сериализуйте данные в форму json, xml или binaray, а затем сохраните их с помощью одного из API файлов C#, например File.WriteAllBytes и File.ReadAllBytes для сохранения и загрузки файлов.

используйте этот метод, если есть много переменных, чтобы сохранить.

General, вам нужно создать класс, который не наследуется от MonoBehaviour. Этот класс вы должны использовать для хранения игровых данных, чтобы их можно было легко сериализовать или де-сериализовать.

пример данных для сохранения:

[Serializable]
public class PlayerInfo
{
    public List<int> ID = new List<int>();
    public List<int> Amounts = new List<int>();
    public int life = 0;
    public float highScore = 0;
}

возьмите DataSaver класс, который является оберткой над File.WriteAllBytes и File.ReadAllBytes это упрощает сохранение данных из этой пост.

создать новый экземпляр:

PlayerInfo saveData = new PlayerInfo();
saveData.life = 99;
saveData.highScore = 40;

сохранить данные из PlayerInfo в файл с именем "игроки":

DataSaver.saveData(saveData, "players");

загрузить данные из файла с именем "players":

PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players");