Unity3D之游戲暫停制作方法記錄


在游戲開發中我們一般都需要涉及到一個功能:游戲暫停,但是這里指的暫停僅僅是核心模塊的暫停,並不是整個游戲都暫停,比如一些UI和UI上的動畫與特效是不能被暫停的,整個游戲都暫停了玩家該如何繼續游戲呢。

這里我們主要討論Unity的游戲暫停實現。

使用timeScale

我們通過設定Time.timeScale的值可以影響到整個游戲的播放速率。

但是請注意,無論timeScale是多少都不會影響到Update、LateUpdate這2個方法的執行速度,而是會影響到Time.time和Time.deltaTime的值。

比如將timeScale設定為0、1、2等等時,Update和LateUpdate的調用頻率是不會變的,但是Time.time及Time.deltaTime會受其影響。

  • 當timeScale為0時,time為不繼續累加時間,deltaTime為0;
  • 當timeScale為1時,time為正常累計時間,deltaTime為正常時間;
  • 當timeScale為2時,time為加倍累計時間,deltaTime為正常時間的兩倍;

而對於物理方面的FixedUpdate則會由於timeScale的變換而影響到其調用的頻率。

  • 當timeScale為0時,FixedUpdate將不會再被調用;
  • 當timeScale為1時,FixedUpdate正常按時間間隔調用;
  • 當timeScale為2時,FixedUpdate按兩倍速度調用;

Time.realtimeSinceStartup

Time.realtimeSinceStartup可以不受timeScale的影響,其記錄着程序啟動到目前經過的時間。我們可以使用該屬性來獲得不受timeScale影響的時間。

不推薦使用timeScale來實現暫停

timeScale控制者整個游戲的時間縮放,修改它除了會影響到Time.time和Time.deltaTime外,還會影響到游戲的物理模擬,雖然諸如NGUI等支持ingoreTimeScale的屬性,但是最好不使用timeScale = 0的方式來實現暫停。

同時timeScale還會影響到音樂播放及粒子效果,可以參考:http://www.xuanyusong.com/archives/2956

要實現慢動作播放等效果可以考慮使用timeScale,如果可以,最好自己實現一個timeScale,其只會影響到特定的模塊,畢竟影響到全局的timeScale可能會造成一些難以察覺的坑。

 

我使用的暫停方法

由於我只需要暫停,不需要加速或慢速播放的效果,所以自己實現是最好的,如下:

 1 using UnityEngine;
 2 
 3 /// <summary>
 4 /// 支持暫停的 MonoBehaviour 基類.
 5 /// 游戲中需要暫停功能的邏輯都應該繼承該類並將邏輯寫到 OnUpdate 及 OnLateUpdate 方法中, 這兩個方法在設置為暫停時不會被調用.
 6 /// </summary>
 7 public class PausingBehaviour : MonoBehaviour
 8 {
 9     /// <summary>
10     /// 是否暫停邏輯處理.
11     /// </summary>
12     public static bool pause { get; set; }
13 
14     static PausingBehaviour()
15     {
16         pause = false;
17     }
18 
19     private bool _isPaused;
20 
21     protected virtual void OnEnable()
22     {
23         _isPaused = pause;
24     }
25 
26     protected virtual void Update()
27     {
28         if(!pause)
29         {
30             if(_isPaused)
31             {
32                 _isPaused = false;
33                 this.OnPauseExit();
34             }
35 
36             this.OnUpdate();
37         }
38         else
39         {
40             if(!_isPaused)
41             {
42                 _isPaused = true;
43                 this.OnPauseEnter();
44             }
45         }
46     }
47 
48     /// <summary>
49     /// 可暫停的邏輯更新方法.
50     /// </summary>
51     protected virtual void OnUpdate()
52     {
53     }
54 
55     protected virtual void LateUpdate()
56     {
57         if(!pause)
58         {
59             this.OnLateUpdate();
60         }
61     }
62 
63     /// <summary>
64     /// 可暫停的邏輯更新方法.
65     /// </summary>
66     protected virtual void OnLateUpdate()
67     {
68     }
69 
70     /// <summary>
71     /// 暫停開始時會調用該方法.
72     /// </summary>
73     protected virtual void OnPauseEnter()
74     {
75     }
76 
77     /// <summary>
78     /// 暫停結束時會調用該方法.
79     /// </summary>
80     protected virtual void OnPauseExit()
81     {
82     }
83 }

所有需要暫停功能的腳本都繼承自該類,幀邏輯寫在OnUpdate及OnLateUpdate里,同時還有OnPauseEnter和OnPauseExit方法來表示是否進入和離開暫停狀態。

當設定PausingBehaviour.pause = false時,OnUpdate及OnLateUpdate將不會被調用,而OnPauseEnter會被調用一次,這里可以對粒子效果等進行暫停,反之設定PausingBehaviour.pause = true時也一樣。

手游強制暫停

這里額外提一下,手機游戲中來電話或鎖屏或退出到桌面時,可以接受到Unity對應的事件,這里需要對游戲進行一下“強制暫停”,另外如果“強制暫停”時間過長,網絡游戲有時得重新登錄等事件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM