如果 System.DateTime.Now 大于 PlayerPrefs 值则加载场景

Load Scene if System.DateTime.Now is greater than PlayerPrefs value

我正在尝试进行简单的日期时间检查。我相信我的逻辑是正确的,但不是我这样做的方式。

我想做的是当用户启动应用程序时我想检查它是否是第一次启动。如果这是我第一次要存储系统日期时间,如果应用程序已经 运行 时间将已经存储在 PlayerPrefs 中,如下所示:

    int timecheck;
            void Start()
            {
                 timecheck = PlayerPrefs.GetInt("savedFirstRun"); //Get time check value

                if (timecheck != 1) { 
                    PlayerPrefs.SetString("rewardCountDown", System.DateTime.Now.ToBinary().ToString());
                    timecheck = 1;
                    PlayerPrefs.SetInt("savedFirstRun", timecheck);// set time check value
                }                    
            }

然后我获取存储的系统时间,"rewardCountDown",并将字符串转换为日期时间。然后我将等待时间添加到该日期,在此示例中我添加一分钟。

 DateTime temp = Convert.ToDateTime(PlayerPrefs.GetString("rewardCountDown"));

        //Convert the old time from binary to a DataTime variable
        storedDate = temp;

        storedDate.AddMinutes(1);

    }

然后我轮询更新方法以继续检查 system.time.now 是否大于存储的时间。

    void Update()
    {
        dateNow = System.DateTime.Now;
        if (dateNow > storedDate)
        {
            Canvas2.SetActive(true);            
            SceneManager.LoadScene("Home 4", LoadSceneMode.Single);
        }
    }

我预计等一分钟后 sceneManger 会触发并加载下一个场景。但是场景永远不会加载。

我的问题是我做错了什么?我在想这可能是我如何将日期时间存储为 PlayerPref。

有一个明显的问题:storedDate.AddMinutes(1);不改变 StoredDate 的值...这是一个常见的容易错过的问题

storedDate = storedDate.AddMinutes(1);

虽然我希望立即加载场景,但根本没有这样做。奖励倒计时在哪里设置?您的代码中没有设置。

你应该这样设置定时器:

   System.Windows.Threading.DispatcherTimer Timer = new System.Windows.Threading.DispatcherTimer();

然后在初始化程序中写入

    Timer.Tick += new EventHandler(Timer_Click);
Timer.Interval = new TimeSpan(0, 1, 0);
Timer.Start();

并在 Timer_Click 方法中执行您的操作

    private void Timer_Click(object sender, EventArgs e)
{
// wite your own code
}

以下是我在游戏中处理某些约会的方式。

由于我的统计数据本身是针对 longs 而不是日期的,所以我将日期时间编码为一个整数值,这样它就可以被明确地解析。

long nl = long.Parse(DateTime.Now.ToString("yyMMddHHmm")); //now
long ll = StatisticsTracker.lastDailyLogin.value; //saved value
if(ll > 0) {
    DateTime nowLogin = DateTime.ParseExact(nl.ToString(), "yyMMddHHmm", CultureInfo.InvariantCulture); //is this unnecessary? Probably. But this shows both halves of the encoding / decoding process.
    DateTime lastLogin = DateTime.ParseExact(ll.ToString(), "yyMMddHHmm", CultureInfo.InvariantCulture);
    //do stuff
}

此处生成的长值可以很容易地存储在 PlayerPrefs 中。

将我的代码与您的代码进行比较,您似乎使用 .ToBinary() 将日期编码为二进制字符串,但是当您解析时,您不确保将其解析为二进制字符串 string. 我建议选择一种格式(就像我所做的那样)并使用该格式进行转换和解析。

它可能就像使用 DateTime 对象解析日期时间一样简单。这可能值得一试:

        DateTime temp = DateTime.Parse(PlayerPrefs.GetString("rewardCountDown"));

        //Convert the old time from binary to a DataTime variable
        storedDate = temp;

        storedDate.AddMinutes(1);

因为您正在使用默认的 ToString() 序列化日期,所以将其解析回来应该会导致您的日期通过没有格式的 Parse() 转换回 DateTime 对象。

如果仍然不起作用,请通过将字符串写入控制台来检查 PlayerPrefs 中的字符串 - 然后将格式传递给 ParseExact() 调用以及字符串,例如

    CultureInfo provider = CultureInfo.InvariantCulture;

    var temp = DateTime.ParseExact(PlayerPrefs.GetString("rewardCountDown"),"yyyy-MM-dd HH:mm:ss", provider);

    storedDate = temp;

您需要确保您使用的格式与您的序列化字符串完全匹配,但这应该可以解决问题。

更多信息在这里:

https://msdn.microsoft.com/en-us/library/w2sa9yss(v=vs.110).aspx

这里:

https://msdn.microsoft.com/en-us/library/system.datetime.parse(v=vs.110).aspx