时间膨胀,

时间膨胀

缘由

最近策划提了一个有意思的需求,就是场景时间膨胀的时候,摄像机不要随时间膨胀变化,当时就懵逼了,游戏中的时间膨胀使用了Time.timeScale,控制了全局都时间膨胀了,不可能在单独处理摄像机啊!

后来,研究了一下 Time.timeScale与Update,FixedUpdate,OnGUI,StartCoroutine之间的关系,终于找到了解决方案。

先说结论:

  • 时间膨胀不会影响Update、OnGUI的执行次数
  • 时间膨胀会影响FixedUpdate的执行次数
  • StartCoroutine函数,如果用WaitForFixedUpdate,那么受时间膨胀影响;如果用WaitForEndOfFrame,那么不受时间膨胀影响。

为啥会影响FixedUpdate的执行次数呢?

其实很简单。如果没有时间膨胀,在Unity中预设值Edit -> Project Settings -> Time -> Fixed Timestep=0.02,那么1秒会执行50次FixedUpdate。时间膨胀之后呢,比如设置TimeScale=0.1,那么需要真实世界的10秒才能达成膨胀世界的1秒,才能跑50次FixedUpdate,对吧,简单吧!
至于StartCoroutine,当选用WaitForFixedUpdate时,跟执行FixedUpdate,是一样的。
数据如下图所示:

相关的API

  1. // 限制帧数为100
  2. Application.targetFrameRate = 100;
  3. // 时间膨胀
  4. Time.timeScale = 0.1f;
  5. // 不受时间膨胀影响的deltaTime
  6. Time.unscaledDeltaTime
  7. // 受时间膨胀影响的deltaTime
  8. Time.deltaTime
  9. // 协成函数相关
  10. yield return new WaitForFixedUpdate()
  11. yield return new WaitForEndOfFrame()

附带代码,欢迎指错

  1. using UnityEngine;
  2. using System.Collections;
  3. public class test : MonoBehaviour {
  4. float UpdateTime = 0;
  5. float FixedUpdateTime = 0;
  6. float GUITime = 0;
  7. float CoroutineTime = 0;
  8. int UpdateCounter = 0;
  9. int FixedUpdateCounter = 0;
  10. int GUICounter = 0;
  11. int CoroutineCounter = 0;
  12. float StartTime = 0;
  13. // Use this for initialization
  14. void Start()
  15. {
  16. QualitySettings.vSyncCount = 0;
  17. Application.targetFrameRate = 100;
  18. Time.timeScale = 0.1f;
  19. StartTime = Time.realtimeSinceStartup;
  20. StartCoroutine(Func());
  21. }
  22. // Update is called once per frame
  23. void Update () {
  24. UpdateTime += Time.unscaledDeltaTime;
  25. UpdateCounter++;
  26. }
  27. void FixedUpdate()
  28. {
  29. FixedUpdateTime += Time.deltaTime;// Time.unscaledDeltaTime;
  30. FixedUpdateCounter++;
  31. }
  32. void OnGUI()
  33. {
  34. GUITime += Time.deltaTime;//Time.unscaledDeltaTime;
  35. GUICounter++;
  36. GUI.Label(new Rect(10, 10, 1000, 30), "update time=" + UpdateTime + ", counter=" + UpdateCounter);
  37. GUI.Label(new Rect(10, 40, 1000, 30), "fixed time=" + FixedUpdateTime + ", counter=" + FixedUpdateCounter);
  38. GUI.Label(new Rect(10, 70, 1000, 30), "gui time=" + GUITime + ", counter=" + GUICounter);
  39. GUI.Label(new Rect(10, 100, 1000, 30), "coroutine time=" + CoroutineTime + ", counter=" + CoroutineCounter);
  40. GUI.Label(new Rect(10, 130, 1000, 30), "real time=" + (Time.realtimeSinceStartup - StartTime));
  41. }
  42. IEnumerator Func()
  43. {
  44. while (true)
  45. {
  46. CoroutineTime += Time.deltaTime;//Time.unscaledDeltaTime;
  47. CoroutineCounter++;
  48. //yield return new WaitForEndOfFrame();
  49. yield return new WaitForFixedUpdate();
  50. }
  51. }
  52. }




posted on 2016-05-16 14:52  三叔的游戏圈  阅读(476)  评论(0编辑  收藏  举报