如何使时钟逻辑在Unity3D更好?



我编写了一段代码,用于计算从第1天开始的日期经过的时间,而不依赖于实际时间。然而,发现了两个缺点,没有找到解决方案。

第一个是Time.deltaTime。Time.deltaTime被不断地添加到timeCount参数中,以确定如果它大于或等于1,则已经过了1秒。这并不完全是1,因此会比实际的时间间隔有一些小数误差。

第二,我觉得我用了太多的if语句。有没有一种方法可以在不影响可读性的情况下更有效地编写代码?

我想听听你对这两个问题的看法。

函数UpdateTime将在其他代码更新语句中定期调用。这是我在下面写的代码。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayTime
{
public int Day { get; private set; }
public int Hour { get; private set; }
public int Minute { get; private set; }
public float Second { get; private set; }
private float timeCount;
public PlayTime()
{
Day = 0;
Hour = 0;
Minute = 0;
Second = 0;
timeCount = 0;
}
public void UpdateTime()
{
timeCount += Time.deltaTime;
if (timeCount >= 1)
{
timeCount = 0;
Second++;
}
if (Second >= 60)
{
Second = 0;
Minute++;
}
if (Minute >= 60)
{
Minute = 0;
Hour++;
}
if (Hour >= 24)
{
Hour = 0;
Day++;
}
}
}

代替

timeCount = 0;

你可以用

timeCount -= 1f;

已经补偿了第一个错误。


您还可以根本不使用连续调用,而是使用绝对时间值,并且仅在实际访问值

时进行计算。
private float initTime;
public PlayTime()
{
initTime = Time.time;
}

,而不是像

这样做。
public readonly struct TimeData 
{
private const int SecondsPerMinute = 60;
private const int SecondsPerHour = 60 * SecondsPerMinute;
private const int SecondsPerDay = 24 * SecondsPerHour;
public int Day {get;}
public int Hour {get;}
public int Minute {get;}
public int Second {get;}
public TimeData (float time)
{
// first round the delta to int -> no floating point inaccuracies 
// according to your needs you could also use Floor or Ceil here
var seconds = Mathf.RoundToInt(time);
// Now we can use the reminder free integer divisions to get the target values 
Day = seconds / SecondsPerDay;
seconds -= Day * SecondsPerDay;
Hour = time / SecondsPerHour;
seconds -= Hour * SecondsPerHour;
Minute = seconds / SecondsPerMinute;
seconds -= Minute * SecondsPerMinute;
Second = seconds;
}
}
public TimeData GetTime()
{
return new TimeData (Time.time - initTime);
}

Time.time是自启动应用程序以来的绝对时间(按比例)秒。


你基本上可以用同样的方法来做,例如DateTime,它的工作原理基本相同,但使用精确的系统tick,这使得它也相当昂贵。

用于初始存储

private DateTime initTime;
public PlayTime()
{
initTime = DateTime.Now;
}

,然后返回

public TimeSpan GetTime()
{
return DateTime.Now - initTime;
}

返回一个基于系统时间和刻度的TimeSpan

最新更新