Установка уровней в викторине - PullRequest
1 голос
/ 28 мая 2020

Это мой первый пост в Stack Overflow, так что будьте осторожны. Я следил за видеоуроком по адресу https://learn.unity.com/tutorial/live-session-quiz-game-1 и смог успешно изменить его, чтобы изображения отображались в виде вопросов, а не текста. Следующим шагом для меня будет разделение игры на уровни. Я добавил соответствующие дополнительные 'Rounds' в объект DataController, упомянутый в конце видео 3 в начале видео 4, чтобы теперь он выглядел так:

DataController Screenshot

Итак, вот вопрос: если я хочу добавить набор кнопок на страницу уровней, а затем добавить событие OnClick для каждой, как мне указать это событие OnClick конкретно на набор вопросов для каждого уровня? Я думаю, мне нужно указать onClick на скрипт, передающий переменную, которая является номером уровня, но не знаю, как это сделать, и пока поиски StackOverflow и YouTube действительно не помогли?

РЕДАКТИРОВАТЬ

Я сделал следующее и, кажется, намного ближе:

  1. Создал новую сцену под названием LevelSelect и добавил к ней кнопки, которые мне нужны для уровней ;
  2. Я создал сценарий в сцене под названием LevelSelectController и добавил к нему сценарий регистрации кнопок, предоставленный Lothan;
  3. Я зарегистрировал кнопки, как было предложено, с помощью перетаскивания;
  4. Я создал функцию в скрипте LevelSelectController под названием StartGame, у нее была одна строка: Debug.Log("Button pressed is: Level " + (setLevel + 1)); Я запустил скрипт, и кнопки отреагировали, как ожидалось;

Все, с чем я сейчас борюсь, как нажмите кнопку, чтобы передать целое число для номера уровня в переменную allRoundData в DataController. Код для каждого сценария выглядит так:

DataController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class DataController : MonoBehaviour
{
public RoundData[] allRoundData;
public int currentLevel;

// Start is called before the first frame update
void Start()
{
    DontDestroyOnLoad (gameObject);

    SceneManager.LoadScene ("MenuScreen");
}

public RoundData GetCurrentRoundData()
{
    return allRoundData [currentLevel];
}

// Update is called once per frame
void Update()
{

}
}

LevelSelectController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class LevelSelectController : MonoBehaviour
{
    public List<Button> buttonsList = new List<Button>();
    private DataController dataController;

    public void StartGame(int setLevel)
    {
        Debug.Log("Button pressed is: Level " + (setLevel + 1));
    }
}

GameController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameController : MonoBehaviour
{
    public Text questionText;
    public Image questionImage;
    public SimpleObjectPool answerButtonObjectPool;
    public Transform answerButtonParent;
    private DataController dataController;
    private RoundData currentRoundData;
    private QuestionData[] questionPool;

    private bool isRoundactive;
    private float timeRemaining;
    private int questionIndex;
    private int playerScore;
    private List<GameObject> answerButtonGameObjects = new List<GameObject> ();

    // Start is called before the first frame update
    void Start()
    {
        dataController = FindObjectOfType<DataController> ();
        currentRoundData = dataController.GetCurrentRoundData ();
        questionPool = currentRoundData.questions;
        timeRemaining = currentRoundData.timeLimitInSeconds;

        playerScore = 0;
        questionIndex = 0;

        ShowQuestion ();
        isRoundactive = true;
    }

    private void ShowQuestion()
    {
        RemoveAnswerButtons ();
        QuestionData questionData = questionPool[questionIndex];
        questionText.text = questionData.questionText;

        questionImage.transform.gameObject.SetActive(true);
        questionImage.sprite = questionData.questionImage;

        for (int i = 0; i < questionData.answers.Length; i++)
        {
            GameObject answerButtonGameObject = answerButtonObjectPool.GetObject();
            answerButtonGameObjects.Add(answerButtonGameObject);
            answerButtonGameObject.transform.SetParent(answerButtonParent);

            AnswerButton answerButton = answerButtonGameObject.GetComponent<AnswerButton>();
            answerButton.Setup(questionData.answers[i]);
        }

    }

    private void RemoveAnswerButtons()
    {
        while (answerButtonGameObjects.Count > 0)
        {
            answerButtonObjectPool.ReturnObject(answerButtonGameObjects[0]);
            answerButtonGameObjects.RemoveAt(0);
        }
    }

    // Update is called once per frame
    void Update()
    {

    }
}

Как теперь передать значение setLevel в LevelSelectController на currentLevel в скрипте DataController?

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Добро пожаловать в StackOverflow!

Вы можете сделать это разными способами, но один из них может быть:

Сначала зарегистрируйте все кнопки:

List<Button> buttonsList = new List<Button>();

Затем назначьте каждой кнопке поведение при onClick (регистрация слушателя), передавая информацию о соответствующем DataController:

for(int i = 0; i < buttonsList.Count; i++)
{
    buttonsList[i].onClick.AddListener(() => SetLevel(DataController.allRoundData[i])) 
}      

В этом текущем ответе есть некоторые сомнения, потому что я не знаю о вашем коде, но если у вас есть сомнения, прокомментируйте и я обновлю ответ ^^

0 голосов
/ 04 июня 2020

После небольшого дополнительного исследования я смог использовать переменную stati c вместе с предложением Лотана, чтобы найти решение. Вот измененный код:

LevelSelectController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class LevelSelectController : MonoBehaviour
{
    static public int currentLevel
    public List<Button> buttonsList = new List<Button>();

    void Start()
    {
        for(int i = 0; i < buttonsList.Count; i++)
    {
        int levelNum = i;
        buttonsList[i].onClick.AddListener(() => {currentLevel = levelNum;}); 
    }     
}

    public void StartLevel()
    {
        SceneManager.LoadScene ("Game");
    }
}

И требуется только одно изменение в Start () GameController.cs, начиная с

currentRoundData = dataController.GetCurrentRoundData ();

на:

currentRoundData = dataController.GetCurrentRoundData (LevelSelectController.currentLevel);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...