使用C#,Unity游戏引擎在午夜创建循环事件

4
在游戏中,我想在每晚午夜触发一个事件。以下代码无法正常工作:
void Update()
{
    var tomorrow = DateTime.Now.AddDays(1).ToShortDateString();
    var today = DateTime.Now.ToShortDateString();

    if (tomorrow == today)
    {
        THE THING I WANT TO HAPPEN AT MIDNIGHT;
    }
}

在调试过程中,我发现了我想要的操作可以正常工作。然而,事件没有从if语句中触发。

我搜索了存档以寻找答案,找到了一些解决方案,但这些解决方案并没有起作用 - 这很可能是由于我的极低级别的编程知识导致的一个简单错误。

任何帮助都将不胜感激...谢谢!


1
想一想,明天总是比今天晚一天,因为你不断地改变它。 - Retired Ninja
2个回答

2

你的代码实际上在询问"1 == 1 + 1?",而答案总是不对的。

你需要在方法之外保留上一次执行日期,并且你还需要更加小心地进行比较。例如,DateTime.Now == DateTime.Now 可能会返回false(而且很常见),因为 DateTime 存储时间直到刻度,如果它们差一个刻度,就不会被视为相等。

试试这个:

DateTime lastExecutionDate = DateTime.Utc;

void Update()
{
    var tomorrow = DateTime.Now.AddDays(1).ToShortDateString();
    var now = DateTime.Utc;

    if (lastExecutionDate.Day < now.Day)
    {
        lastExecutionDate = now;

        // this code will be called as close to midnight as unity allows.
    }
}

我不确定游戏开始时是否立即被视为午夜。如果是这样,请尝试使用此代码替代lastExecutionDate...

DateTime lastExecutionDate = DateTime.UtcNow + TimeSpan.FromDays(1);

除非这是那些极为罕见的情况之一,您不需要使用UTC。 "Unity"意味着在PC上本地执行exe,并且用户可能有一个与午夜相关的原因。 - Ian Mercer
是的,你说得对。我已经更新了它以反映这个事实。感谢你指出来。我大部分与时间相关的工作都在服务器上进行,而且很久以前我就学会了,如果你使用本地时间一次,那么你可能会永远使用它,即使它是不正确的。所以我默认使用UTC,因为如果需要,你总是可以转换为本地时间。但在这种情况下,你绝对是正确的。 :) - cwharris
谢谢你发布帖子!请看看我的上面的帖子。也要感谢你们先生们的热情款待。 - Andy

0

if (tomorrow == today)这将永远不会成立。如果是正好午夜(Jan 01 2000 12:00:00.0000),那么这行代码:tomorrow = DateTime.Now.AddDays(1)将等于明天的午夜...每次都是(Jan 02 2000 12:00:00.0000)。其他日期和时间也是同样适用。

您最好检查当前时间是否为午夜,然后将当前日期存储在某个地方,只有在当前时间为午夜且存储的日期不是今天的日期时才执行DoTheThing()

当然,这也忽略了“如果应用程序在午夜时没有被积极运行,您是否希望触发事件”的问题。在这种情况下,TimeSpanLast_run_date可能会有所帮助。


正如我所料,这是一个愚蠢的错误。不过,这个网站(以及所有回答问题的人)都很棒,对我来说有很大的帮助——这是我唯一学习编程的地方。非常感谢,虽然我还不算是初学者。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接