概述
一: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的类库导入到项目中:https://download.csdn.net/download/LLLLL__/12238509)
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;
/// <summary>
/// 防作弊时间
/// </summary>
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<UnbiasedTime>();
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();
}
/// <summary>
/// 获取当前时间
/// </summary>
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
}
/// <summary>
/// Platform specific code
/// </summary>
#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<AndroidJavaObject>("currentActivity");
if (playerActivityContext != null && unbiasedTimeClass != null) {
timeOffset = unbiasedTimeClass.CallStatic <long> ("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<AndroidJavaObject>("currentActivity");
if (playerActivityContext != null && unbiasedTimeClass != null) {
unbiasedTimeClass.CallStatic ("vtcOnSessionStart", playerActivityContext);
timeOffset = unbiasedTimeClass.CallStatic <long> ("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<AndroidJavaObject>("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<AndroidJavaObject>("currentActivity");
if (playerActivityContext != null && unbiasedTimeClass != null) {
return unbiasedTimeClass.CallStatic <bool> ("vtcUsingDeviceTime");
}
}
return true;
}
#endif
}
最后
以上就是欢呼红牛为你收集整理的Unity中获取离线时间的全部内容,希望文章能够帮你解决Unity中获取离线时间所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复