Создайте класс / метод для времени (запуск, сброс, остановка, получение istant, получение timerun) - PullRequest
0 голосов
/ 16 июня 2019

Я создаю гоночную игру и работаю над временем гонки.

Я пытаюсь создать систему для запуска экземпляра таймера с различными вариантами.

Мой маленькийопыт ставит меня в кризис ... захочет ли какая-нибудь добрая душа помочь мне?

Это была идея:

public class Timer {


    public float counter;
    public bool reset; 
    public string runtime = "--:--:--";
    public string istant = "not istant";

    public void startTimer()
    {

        /* inupdatealternative: counter += Time.deltaTime; */

        if(reset == true)
        {
            counter = 0;
        }
        else
        {
            counter = Time.time;
        }

        var minutes = counter/60;               // divide guitime by sixty (minutes)
        var seconds = counter%60;               // euclidean division (seconds)
        var fraction = (counter * 100) % 100;   // get fraction of seconds
        runtime = string.Format ( "{0:00}:{1:00}:{2:000}", minutes, seconds, fraction);

        Debug.Log("in Start: "+runtime);

    }

    public void resetTimer()
    {
        reset = true;
    }

    public string getTimerRuntime()
    {
        return runtime;
    }

    public string getTimerIstant()
    {
        istant = runtime;
        return istant;
    }

}

в обновлении, например:

var lapTimer = new Timer(); // create a new timer
if(Lap < Pilot.pilotlap )
{
    lapTimer.startTimer();
    Lap++
}
else if(Lap==Pilot.pilotlap)
{
    timerLabel.text = lapTimer.getTimerIstant();
    lapTimer.resetTimer();
    lapTimer.startTimer();
}

в моей голове я уверен, что кто-то уже имел дело с этим ... конечно, будет что-то, что управляет временем и возвращает значения различными способами: существует ли это?или есть в любом случае как сделать или построить такую ​​вещь?

Ответы [ 2 ]

1 голос
/ 16 июня 2019

Существует, он называется Stopwatch, это класс THE, используемый в C # для использования точных таймеров, и он находится в пространстве имен System.Diagnostics.

Используя ваш пример Update(), вы можете использовать егонапример:

// Create a new stopwatch instance
// If the timer is used repeatedly, just instantiate one at start and re-use the same,
// to avoid garbage generation
Stopwatch lapTimer = new Stopwatch();

if(Lap < Pilot.pilotlap )
{
    lapTimer.Start();
    Lap++
}
else if(Lap==Pilot.pilotlap)
{
    lapTimer.Stop();
    // ElapsedMilliseconds returns exactly what it says, so you may need to format the value
    // before passing it to the timerLabel.text
    timerLabel.text = lapTimer.ElapsedMilliseconds.ToString();
    lapTimer.Reset();
    lapTimer.Start();
}

Вы можете прочитать о классе (его методах, полях и свойствах) здесь:

Документация по классу секундомера

0 голосов
/ 17 июня 2019

Вы делаете множество ненужных bool и копирование и настройка локальных полей. Я бы просто использовал что-то вроде

public class Timer 
{
    private float _startTime;
    public bool IsRunning;

    // you don't need an extra reset method
    // simply pass it as a parameter
    public void Start(bool reset = false)
    {
        if(IsRunning && !reset)
        {
            Debug.LogWarning("Timer is already running! If you wanted to restart consider passing true as parameter.");
            return;
        }

        _startTime = Time.time;                                             

        Debug.Log("in Start: " + GetFormattedTime(_startTime));

        IsRunning = true;
    }

    // depending what stop should do
    // since this doesn't use any resources while running you could also simply
    // only stick to the Start method and pass in true .. does basically the same
    public void Stop()
    {
        IsRunning = false;
    }

    // I didn't see any difference between you two methods so I would simply use
    public string GetCurrentTime()
    {
        if(!IsRunning)
        {
            Debug.LogWarning("Trying to get a time from a Timer that isn't running!");
            return "--:--:---";
        }

        var timeDifference = Time.time - _startTime;

        return GetFormattedTime(timeDifference);
    }

    private static string GetFormattedTime(float time)
    {
                                                                  // e.g. time = 74.6753
        var minutes = Mathf.FloorToInt(time / 60f);               // e.g. 1 (rounded down)
        var seconds = Mathf.FloorToInt(time - 60f * minutes);      // e.g.  14 (rounded down)
        var fraction = Mathf.RoundToInt((time - seconds) * 1000f); // e.g. 676 (rounded down or up)

        // Use a string interpolation for better readability
        return $"{minutes:00}:{seconds:00}:{fraction:000}";
    }
}

тогда в вашем Update вы не хотите использовать

var lapTimer = new Timer(); // create a new timer

все время, так как это создаст новый таймер, и вы не получите отслеживаемое время ... вы бы предпочли использовать его только один раз, как

private Timer timer;

// just in case you want to keep track of needed times per lap
public List<string> lapTimes = new List<string>();

private void Awake()
{
    timer = new Timer();
    lapTimes.Clear();
}

private void Update()
{
    ...

    if(Lap < Pilot.pilotlap)
    {
        timer.Start();
        Lap++
    }
    else if(Lap == Pilot.pilotlap)
    {
        var currentTime = timer.GetCurrentTime();
        timerLabel.text = currentTime;
        lapTimes.Add(currentTime);
        timer.Start(true)
    }

    ...
}

Обратите внимание, что я не знаю, является ли это все, что у вас есть в Update или как вы его используете, но вы, вероятно, также не хотите (повторно) запустить таймер и подсчитать Lap каждый кадр ваши условия true ... необходимо провести больше проверок, чтобы убедиться, что это может быть вызвано только один раз на круг ...

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