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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月25日 18时19分49秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Java 8新特性之--lambda表达式的使用和应用
2019-04-30
Java Lambda表达式的应用--Stream API操作集合框架
2019-04-30
省市区三级联动插件Distpicker--前端实现地区三级联动
2019-04-30
solr的使用详解
2019-04-30
Myslq连接(JDBC)url属性的参数的设置
2019-04-30
关于Java继承,重载及运行的顺序的总结
2019-04-30
关于Spring MVC与前端的交互
2019-04-30
Mybatis逆向工程的使用
2019-04-30
关于Hibernate的优缺点
2019-04-30
常用的 Maven 命令
2019-04-30
常用的20个正则表达式
2019-04-30
数据结构之顺序表的实现
2019-04-30
数据结构之线性链表
2019-04-30
JQuery使用validate插件完成校验
2019-04-30
关于java的继承
2019-04-30
关于java的内部类
2019-04-30
关于java的枚举
2019-04-30
一个简单的layui登陆界面
2019-04-30
SQL考试常见题目
2019-04-30