在倒计时期间倒计时文本字段不更新

时间:2017-06-13 21:52:27

标签: c# unity3d timer

我试图为我的游戏创建一个不活动计时器,我似乎除了一部分之外一切都正常。在预先计数之后,我实例化了一个预制定时器对话框,然后在我的协程中我尝试更新文本字段“timerTextField”#39;位于该预制件但它没有更新。

我确实在编辑器和我的debug.log中分配了所有适当的变量,紧跟在' timerTextField.text = s.ToString();'线正在倒计时。我有什么不对?

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

public class GameManager : MonoBehaviour 
{
    // Create Singleton
    public static GameManager gameManagerInstance = null;

    // Set Default Background Color
    public Color defaultColor;

    // Restart variables
    private Vector3 prevMousePosition;

    [SerializeField]
    private Text timerTextField;

    public Object startingScene;
    public GameObject timeOutWarningDialog;  
    public float countdownLength;
    public float countdownDelay;

    private float seconds;
    private Scene currentScene;
    private GameObject gameManager;
    private GameObject canvas;
    private GameObject timerInstance;

    void Awake()
    {
        if (gameManagerInstance == null)
            gameManagerInstance = this;
        else if (gameManagerInstance != null)
            Destroy(gameObject);
        DontDestroyOnLoad(gameObject);
        gameManager = GameObject.FindGameObjectWithTag("GameManager");
    }

    void Start()
    {       
        prevMousePosition = Input.mousePosition;
        currentScene = SceneManager.GetActiveScene();
    }

    void Update()
    {
        if (Input.anyKeyDown || Input.mousePosition != prevMousePosition)
        {
            currentScene = SceneManager.GetActiveScene();

            if (currentScene.name != startingScene.name)
            {
                StartPreCountTimer();
                if (timeOutWarningDialog != null)
                {
                    timeOutWarningDialog.SetActive(false);
                }
            }
        }
        prevMousePosition = Input.mousePosition;
    }

    // GAME TIMER

    public void StartPreCountTimer()
    {
        // Debug.Log("Pre Count Started");
        CancelInvoke();
        if (GameObject.FindGameObjectWithTag("Timer") == null)
            Invoke("ShowRestartWarning", countdownDelay);
    }

    void ShowRestartWarning()
    {
        canvas = GameObject.FindGameObjectWithTag("Canvas");
        timerInstance = Instantiate(timeOutWarningDialog);
        timerInstance.transform.SetParent(canvas.transform, false);
        timerInstance.SetActive(true);

        if (timerInstance.activeSelf == true)
            StartTimer(countdownLength);  
    }

    public void StartTimer(float seconds)
    {
        StartCoroutine("RunTimer", seconds);
    }

    IEnumerator RunTimer(float seconds)
    {
        float s = seconds;
        // Debug.Log("Restart Countdown Started from: " + s);
        while (s > 0)
        {
            if (timerTextField != null)
            {
                timerTextField.text = s.ToString();
                Debug.Log(s);
            }
            yield return new WaitForSeconds(1);
            s -= 1;
        }

        if (s == 0)
        {
            RestartGame();
        }
    }

    void RestartGame()
    {
        SceneManager.LoadScene(startingScene.name);
        // Debug.Log("Game Restarted");
    }
}

1 个答案:

答案 0 :(得分:1)

您的问题来自timerTextField参考。

似乎您将预制件内的文字组件(我认为是timeOutWarningDialog)分配给了Inspector中的timerTextField字段。
因此,在实例化新的预制定时器对话框后,当您想要更改timerTextField.text值时,更改的内容是预制件内的文本组件,而不是实例化的对象之一

您检查了这一点,但在预制件中选择了包含文本组件的对象(在Unity的项目选项卡中):

Prefabs Text component value changing
(这也解释了你开始时的奇怪值:你停止游戏时达到的先前值)

要使您的脚本正常工作,您只需使用以下内容引用实例化预制件的新 Text 组件:

void ShowRestartWarning()
{
    timerInstance = Instantiate(timeOutWarningDialog);
    timerInstance.transform.SetParent(transform, false);
    timerInstance.SetActive(true);
    timerTextField = timerInstance.GetComponentInChildren<Text>(); // NEW LINE

    if(timerInstance.activeSelf == true)
        StartTimer(countdownLength);
}

希望这有帮助,