Установить выбор времени в Unity - PullRequest
0 голосов
/ 04 октября 2019

Я делаю проект Unity. У меня есть две сцены в моем проекте.

В первой сцене. Я установил три кнопки с надписью «1 минута», «2 минуты» и «3 минуты». И я хочу иметь соответствующую продолжительность игры на моей второй сцене (игровой сцене). У меня есть функция обратного отсчета в моем сценарии.

Теперь я использую шаблон синглтона, следуя инструкциям этого урока. https://www.youtube.com/watch?v=CPKAgyp8cno

Проблема в том, что когда я запускаю игру, три текста времени начинаются одновременно. А моими кнопками в Scene можно было управлять сценами загрузки, но не выбирать время.

Ниже приведены коды. В скрипте PersistentManager, который прикреплен к игровому объекту PersistentManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PersistentManagerScript : MonoBehaviour
{public static PersistentManagerScript Instance { get; private set; }

public int Value;
// Start is called before the first frame update

private void Awake()
{
    if (Instance == null)
    {
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }
    else
    {
        Destroy(gameObject);
    }
}

}

В скрипте SceneManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SceneManagerScript : MonoBehaviour
{
 public GameObject CountDownIn1;
public GameObject CountDownIn2;
public GameObject CountDownIn3;
public Text ValueText;
public Text ValueText1;
public Text ValueText2;
private void Start()
{
    switch (this.gameObject.name)
    {
        case "Button1min":
            SetGameTimeEqualOne();
            break;
        case "Button2mins":
            SetGameTimeEqualTwo();
            break;
        case "Button3mins":
            SetGameTimeEqualThree();
            break;
    }
}  


public void SetGameTimeEqualOne()
{
    CountDownIn1.SetActive(true);
    ValueText.text = PersistentManagerScript.Instance.Value.ToString();
    Debug.Log("COUNTDOWN1 active");
    //DontDestroyOnLoad(this.CountDownIn1);
}
public void SetGameTimeEqualTwo()
{
    CountDownIn2.SetActive(true);
    Debug.Log("COUNTDOWN2 active");
    ValueText1.text = PersistentManagerScript.Instance.Value.ToString();
    DontDestroyOnLoad(this.gameObject);
}
public void SetGameTimeEqualThree()
{
    CountDownIn3.SetActive(true);
    Debug.Log("COUNTDOWN3 active");
    ValueText2.text = PersistentManagerScript.Instance.Value.ToString();
    DontDestroyOnLoad(this.gameObject);
}

Будут оценены любые предложения.

1 Ответ

1 голос
/ 04 октября 2019

Существует несколько способов передачи данных между сценами. Наиболее распространенная рекомендация - использовать шаблон Singleton , который используется другими сценариями в каждой сцене. Однако это может быть слишком сложно.

Интересно, что более новые ScriptableObjects Unity можно использовать для аналогичной стратегии. Поскольку объекты ScriptableObject сохраняются в большем объеме, чем сцены, вы можете использовать их для хранения данных между сценами без использования статики и синглетонов. Unity даже позиционирует их как нечто большее, чем просто контейнеры данных! Я предпочитаю передавать данные между объектами и сценами, создавая общий объект сценариев и ссылаясь на этот ресурс в каждом сценарии, который должен обмениваться данными (независимо от сцены).

Вот пример использования вашего требования:

GameData.cs

[CreateAssetMenu(fileName = "GameData", menuName = "Game Data")]
public class GameData: ScriptableObject
{
    float gameDuration; //This is where you will store and read your selected game duration
}

GameSelection.cs Этот сценарий существует в сцене 1

public class GameSelection : Monobehaviour
{
    public GameData gameData; 

    public void SetDuration(float time) //Call this method from each button with a different parameter
    {
        gameData.gameDuration = time;
    }
}

Countdown.cs Этот сценарий существует в Scene 2

public class Countdown: Monobehaviour
{
    public GameData gameData; 
    float countdownTimer;

    public void Start()
    {
        countdownTimer = gameData.gameDuration;
    }

    //... rest of your countdown script
}

Теперь вы можете создать актив GameData в папке вашего проекта и перетащить его в инспектор в Scene1,и инспектор в сцене 2. Если Scene1 изменит значение таймера, Scene2 узнает об этом. Кроме того, вы можете установить значение по умолчанию для gameDuration в активе GameData и запускать / тестировать Scene2 без необходимости сначала запускать Scene1!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...