Jak zachować odniesienie czasowe podczas przełączania okien mobilnych? (Jedność) [duplikat]
Mam grę, w której mam system rozgrywek kolejkowych. Chciałbym pokazać graczowi, jak długo był w obecnej kolejce. Działa dobrze, dopóki gracz nie naciśnie przycisku menu / przeglądu aplikacji na swoim telefonie, co zasadniczo zawiesza licznik czasu i liczy tylko wtedy, gdy gracz przełączy się z powrotem do trybu pełnoekranowego na swoim telefonie.
Próbowałem znaleźć metodę cyklu życia aplikacji (trochę jak onApplicationPause, ale to nie zadziałało) .Próbowałem
również zsynchronizować czas, zapisując go w bazie danych, a następnie ładując z bazy danych, ale Firebase wprowadza pewne opóźnienie, więc to nie będzie dokładne. Jak mogę rozwiązać ten problem, żeby liczył się, gdy użytkownik naciśnie przycisk przeglądu aplikacji / menu na telefonie?
Na razie mam taki kod, który zlicza czas oczekiwania użytkownika w kolejce:
private void Update() {
if(startedCounting) {
timer += Time.deltaTime;
int seconds = Mathf.FloorToInt(timer % 60);
int minutes = Mathf.FloorToInt(timer / 60);
queueStatusText.text = "You are in the queue\n"
+ string.Format("{0:00}:{1:00}", minutes, seconds);
}
}
Odpowiedzi
Istnieją różne podejścia, niektóre wykorzystujące klasę statyczną lub wzorzec singleton. Lepiej nie aktualizować tej zmiennej czasowej za każdym razem, Update()
ponieważ każda aktualizacja zajmuje czas obliczeniowy (jeśli nie potrzebujesz tego czasu na nic innego). Ponadto użytkownik nie musi mieć dokładnego czasu według ramek, dzięki czemu można uniknąć takich rzeczy, jak dodawanie Time.deltaTime
.
Pokażę ci przykład z klasą statyczną, może pomieścić te informacje. Zwróć również uwagę, że ten skrypt jest dodawany tylko jako plik C #, ale nie dołączasz go do żadnego GameObject
:
public static class QueueTimerInformation //It is not inheriting from MonoBehavior!
{
private static DateTime dt;
private static bool isRunning = false;
//Save current DateTime when user did the action
public static void Start()
{
if(!isRunning)
{
dt = DateTime.Now;
isRunning = true;
}
}
public static void Reset()
{
isRunning = false;
}
// This gets the actual time in String value
// Usually it is better to return just `elapsedTime` and format it later
public static string GetTimeElapsed()
{
if(!isRunning) return "00:00"; //Not running, return some default
var elapsedTime = (DateTime.Now - dt);
return $"{elapsedTime:mm\\:ss}";
}
}
Stosowanie
//On 1st time enter lobby
QueueTimerInformation.Start();
//In update method
var result = QueueTimerInformation.GetTimeElapsed();