我是靠谱客的博主 欢呼红牛,最近开发中收集的这篇文章主要介绍Unity中获取离线时间,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一: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中获取离线时间所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部