Unity Countdown脚本,使用触发器进行开始和完成

时间:2018-11-07 05:42:01

标签: unity3d timer triggers countdown

我正在Unity内使用3d游戏套件,并试图在玩家输入触发时显示计时器,然后在到达结束触发时停止计时器。该工具包使用我不熟悉并试图弄清楚的对话画布。


更新

我现在在UI上有了计时器,可以在输入触发器时使其停止,但是我不确定如何在玩家输入触发器时使其启动。现在,它只要游戏开始就开始。

public class Timer : MonoBehaviour 
{ 
    public Text timerText; 
    private float startTime; 
    private bool finished = false; 

    void Start () 
    { 
        float startTimer = Time.time; 
    } 

    void Update () 
    { 
        if (finished) return; 

        float t = Time.time - startTime; 
        string minutes = ((int)t / 60).ToString(); 
        string seconds = (t % 60).ToString("f2"); 
        timerText.text = minutes + ":" + seconds; 
    } 

    public void Finish() 
    { 
        finished = true; 
        timerText.color = Color.yellow; 
    } 
}

1 个答案:

答案 0 :(得分:0)

首先:在您的Start方法中,您声明了一个新的局部变量float startTimer,但从未对其进行任何处理,因此类“全局”变量float startTime始终以该值开头0

比起您的Update总是在每一帧都运行,因此倒数计时从头开始。


阅读Countdown我会理解,您希望计时器随着时间的推移而减少,并在值达到0时执行某些操作(否则,我不会将其称为倒数)。倒计时有多种方法。我认为最接近您已有的东西可能是

public class Timer : MonoBehaviour 
{ 
    public Text timerText;

    // a callback (like onClick for Buttons) for doing stuff when Countdown finished
    public UnityEvent OnCountdownFinished;

    // here the countdown runs later
    private float timer; 

    // for starting, pausing and stopping the countdown
    private bool runTimer;

    // just a control flag to avoid continue without pausing before
    private bool isPaused;

    // start countdown with duration
    public void StartCountdown(float duration) 
    { 
        timer = duration; 
        runTimer = true;
    } 

    // stop and reset the countdown
    public void StopCountdown()
    {
        ResetCountdown();
    }

    // pause the countdown but remember current value
    public void PauseCountdown()
    {
        if(!runTimer)
        {
            Debug.LogWarning("Cannot pause if not runnning");
            return;
        }

        runTimer = false;
        isPaused = true;
    }

    // continue countdown after it was paused
    public void ContinueCountdown()
    {
        if(!isPaused)
        {
            Debug.LogWarning("Countdown was not paused! Cannot continue if not started");
            return;
        }

        runTimer = true;
        isPaused = false;
    }

    private void Update() 
    { 
        if (!runTimer) return;

        if (timer <= 0)
        {
            Finished();
        }

        // reduces the timer value by the time passed since last frame
        timer -= Time.deltaTime;

        string minutes = ((int)timer / 60).ToString(); 
        string seconds = (timer % 60).ToString("f2"); 

        // a bit more readable
        timerText.text = string.Format("{0}:{1}", minutes, seconds); 
    } 


    private void ResetCountdown()
    {
        timerText.text = "0:00";
        runTimer = false;
        isPaused = false;
        timer = 0;
    }

    // called when the countdown exceeds and wasn't stopped before
    private void Finished() 
    { 
        // do what ever should happen when the countdown is finished

        // simpliest way is to call the UnityEvent and set up the rest via inspector
        // (same way as with onClick on Buttons)
        OnCountdownFinished.Invoke();

        // and reset the countdown
        ResetCountdown();
    } 
}

您还可以为OnCountdownStartedOnCountdownPaused等添加更多回调。

现在您可以使用触发器

调用这些方法
// somehow you have to get the reference to the component
// if the trigger callbacks are in the same class you don't need this ofcourse
Timer _timer;

// how long the countdown should take
float countdownDuration;

void OnTriggerEnter(Collider col)
{
    _timer.StartCountdown(countdownDuration)
}


void OnTrigerExit(Collider col)
{
    _timer.StopCountdown();
}

如果您希望暂停并继续,则可以将两个标记runTimerisPaused设为公开,然后执行

void OnTriggerEnter(Collider col)
{
    if(!_timer.runTimer)
    {
        _timer.StartCountdown(countdownDuration)
    }
    else
    {
        _timer.ContinueCountdown();
    }
}


void OnTrigerExit(Collider col)
{
    if(!_timer.runTimer) return;

    _timer.PauseCountdown();
}

我希望有帮助。