Скрипт обратного отсчета Unity с использованием триггеров для начала и окончания - PullRequest
0 голосов
/ 07 ноября 2018

Я использую 3D Game Kit внутри Unity и пытаюсь отобразить таймер, когда игрок входит в триггер, а затем останавливаю таймер, как только он достигает конечного триггера. В наборе используется диалоговое полотно, с которым я не знаком и пытаюсь разобраться.


Обновление

У меня теперь есть таймер в моем пользовательском интерфейсе, и я могу остановить его при входе в триггер, но я не уверен, как запустить его, когда игрок вводит триггер. Сейчас он только начинается, когда начинается игра.

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 голосов
/ 14 ноября 2018

Прежде всего: в вашем методе Start вы объявляете новую локальную переменную float startTimer, но никогда ничего с ней не делаете, поэтому переменная классов "global" 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();
    } 
}

Вы также можете добавить дополнительные обратные вызовы для OnCountdownStarted, OnCountdownPaused и т. Д.

Теперь вы можете вызывать эти методы с помощью триггеров

// 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();
}

если вы предпочитаете паузу и продолжить, вы можете сделать два флага runTimer и isPaused общедоступными и сделать

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


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

    _timer.PauseCountdown();
}

Надеюсь, это поможет.

...