Unity中获取离线时间
发布日期:2021-06-30 19:57:15 浏览次数:2 分类:技术文章

本文共 8023 字,大约阅读时间需要 26 分钟。

一:C#中与时间相关的两个类:DateTime和TimeSpan

TimeSpan是C#中的一个类,常用以下几种方法

using System;using UnityEngine;public class Test : MonoBehaviour{    private void Awake()    {        //将TimeSpan结构的新实例初始化为指定的刻度数        TimeSpan t1 = new TimeSpan(36); //00:00:00.0000036        //将TimeSpan结构的新实例初始化为指定的小时数、分钟数和秒数        TimeSpan t2 = new TimeSpan(20, 35, 21); //20:35:21        //将TimeSpan结构的新实例初始化为指定的天数、小时数、分钟数和秒数        TimeSpan t3 = new TimeSpan(4, 20, 35, 21); //4:20:35:21        TimeSpan t4 = new TimeSpan(4, 24, 35, 21); //*****自动进位5:00:35:21        //将TimeSpan结构的新实例初始化为指定的天数、小时数、分钟数、秒数和毫秒数(1秒=1000毫秒)        TimeSpan t5 = new TimeSpan(4, 20, 35, 21, 60); //4:20:35:21:0600000        //直接取出TimeSpan结构所表示的时间间隔的天数、小时数、分钟数、秒数和毫秒数        TimeSpan t6 = new TimeSpan(4, 20, 35, 21, 60);        Debug.Log(String.Format("天数:{0}\n小时数:{1}\n分钟数:{2}\n秒数:{3}\n毫秒数:{4}", t6.Days, t6.Hours, t6.Minutes, t6.Seconds,            t6.Milliseconds)); //天数:4    小时数:20    分钟数:35    秒数:21    毫秒数:60        //将TimeSpan结构所表示的时间间隔换算成等效天数、小时数、分钟数、秒数和毫秒数        TimeSpan t7 = new TimeSpan(4, 20, 35, 21, 60);        Debug.Log(String.Format("等效天数:{0}\n等效小时数:{1}\n等效分钟数:{2}\n等效秒数:{3}\n等效毫秒数:{4}", t7.TotalDays, t7.TotalHours, t7.TotalMinutes, t7.TotalSeconds,            t7.TotalMilliseconds)); //等效天数:4.857...    等效小时数:116.58...    等效分钟数:6995.3...    等效秒数:419721...    等效毫秒数:419721060    }}

二:实现离线计时器

要获取离线时间,需要得到两个数据,离线时的时间和再次启动的时间,再次启动的时间通过这个防作弊的类去获取(修改系统时间或修改系统时区都无效,直接将IOS和Android的类库导入到项目中:)

using System;using UnityEngine;public class OfflineMgr : MonoBehaviour{    private void OnApplicationPause(bool pause)    {        if (pause)        {            PlayerPrefs.SetString("lastOffline", UnbiasedTime.Ins.Now().ToBinary().ToString());        }        else        {            //TODO:获得离线收益        }    }    private void OnApplicationQuit()    {    }    public double GetOfflineTime()    {        string lastOfflineTime = PlayerPrefs.GetString("lastOffline", "0");        DateTime last = DateTime.FromBinary(long.Parse(lastOfflineTime));        DateTime now = UnbiasedTime.Ins.Now();        double restTime = (now - last).TotalSeconds;        return restTime;    }}
using UnityEngine;using System;using System.Collections;using System.Runtime.InteropServices;using System.Threading;/// /// 防作弊时间/// public class UnbiasedTime : MonoBehaviour{    const bool UseTimeZone_CN = true;//是否为中国时区+8    const int TimeZone_CN = 8;//中国时区    private static UnbiasedTime _instance;    public static UnbiasedTime Ins    {        get        {            if (_instance != null) return _instance;            var go = new GameObject("UnbiasedTime");            _instance = go.AddComponent
(); DontDestroyOnLoad(go); return _instance; } } // Estimated difference in seconds between device time and real world time // timeOffset = deviceTime - worldTime; [HideInInspector] public long timeOffset = 0; void Awake() { SessionStart(); } void OnApplicationPause(bool pause) { if (pause) { SessionEnd(); } else { SessionStart(); } } void OnApplicationQuit() { SessionEnd(); } ///
/// 获取当前时间 /// public DateTime Now() { if (UseTimeZone_CN) { return getNow().ToUniversalTime().AddHours(TimeZone_CN); } else { return getNow(); } } private DateTime getNow() { return DateTime.Now.AddSeconds(-1.0f * timeOffset); } // timeOffset value is cached for performance reasons (calls to native plugins can be expensive). // This method is used to update offset value in cases if you think device time was changed by user. // // However, time offset is updated automatically when app gets backgrounded or foregrounded. // public void UpdateTimeOffset() {#if UNITY_ANDROID UpdateTimeOffsetAndroid();#elif UNITY_IPHONE UpdateTimeOffsetIOS();#endif } // Returns true if native plugin was unable to calculate unbiased time and had fallen back to device DateTime. // This can happen after device reboot. Player can cheat by closing the game, changing time and rebooting device. // This method can help tracking this situation. public bool IsUsingSystemTime() {#if UNITY_ANDROID return UsingSystemTimeAndroid();#elif UNITY_IPHONE return UsingSystemTimeIOS();#else return true;#endif } private void SessionStart() {#if UNITY_ANDROID StartAndroid();#elif UNITY_IPHONE StartIOS();#endif } private void SessionEnd() {#if UNITY_ANDROID EndAndroid();#elif UNITY_IPHONE EndIOS();#endif } ///
/// Platform specific code /// #if UNITY_IPHONE [DllImport("__Internal")] private static extern void _vtcOnSessionStart(); [DllImport("__Internal")] private static extern void _vtcOnSessionEnd(); [DllImport("__Internal")] private static extern int _vtcTimestampOffset(); [DllImport("__Internal")] private static extern int _vtcUsingSystemTime(); private void UpdateTimeOffsetIOS() { if (Application.platform != RuntimePlatform.IPhonePlayer) { return; } timeOffset = _vtcTimestampOffset(); } private void StartIOS() { if (Application.platform != RuntimePlatform.IPhonePlayer) { return; } _vtcOnSessionStart(); timeOffset = _vtcTimestampOffset(); } private void EndIOS() { if (Application.platform != RuntimePlatform.IPhonePlayer) { return; } _vtcOnSessionEnd(); } private bool UsingSystemTimeIOS() { if (Application.platform != RuntimePlatform.IPhonePlayer) { return true; } return _vtcUsingSystemTime() != 0; }#endif#if UNITY_ANDROID private void UpdateTimeOffsetAndroid() { if (Application.platform != RuntimePlatform.Android) { return; } using (var activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using (var unbiasedTimeClass = new AndroidJavaClass("com.vasilij.unbiasedtime.UnbiasedTime")) { var playerActivityContext = activityClass.GetStatic
("currentActivity"); if (playerActivityContext != null && unbiasedTimeClass != null) { timeOffset = unbiasedTimeClass.CallStatic
("vtcTimestampOffset", playerActivityContext); } } } private void StartAndroid() { if (Application.platform != RuntimePlatform.Android) { return; } using (var activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using (var unbiasedTimeClass = new AndroidJavaClass("com.vasilij.unbiasedtime.UnbiasedTime")) { var playerActivityContext = activityClass.GetStatic
("currentActivity"); if (playerActivityContext != null && unbiasedTimeClass != null) { unbiasedTimeClass.CallStatic ("vtcOnSessionStart", playerActivityContext); timeOffset = unbiasedTimeClass.CallStatic
("vtcTimestampOffset"); } } } private void EndAndroid() { if (Application.platform != RuntimePlatform.Android) { return; } using (var activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using (var unbiasedTimeClass = new AndroidJavaClass("com.vasilij.unbiasedtime.UnbiasedTime")) { var playerActivityContext = activityClass.GetStatic
("currentActivity"); if (playerActivityContext != null && unbiasedTimeClass != null) { unbiasedTimeClass.CallStatic ("vtcOnSessionEnd", playerActivityContext); } } } private bool UsingSystemTimeAndroid() { if (Application.platform != RuntimePlatform.Android) { return true; } using (var activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using (var unbiasedTimeClass = new AndroidJavaClass("com.vasilij.unbiasedtime.UnbiasedTime")) { var playerActivityContext = activityClass.GetStatic
("currentActivity"); if (playerActivityContext != null && unbiasedTimeClass != null) { return unbiasedTimeClass.CallStatic
("vtcUsingDeviceTime"); } } return true; }#endif}

 

转载地址:https://liuhaowen.blog.csdn.net/article/details/104315929 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Unity中实现接入ShareSDK的微信登陆和分享功能
下一篇:Unity中获取整个项目的代码行数总和

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月25日 18时19分49秒