Unity3D之游戏暂停制作方法记录
2015-12-07 18:51 阿诚de窝 阅读(10561) 评论(0) 编辑 收藏 举报在游戏开发中我们一般都需要涉及到一个功能:游戏暂停,但是这里指的暂停仅仅是核心模块的暂停,并不是整个游戏都暂停,比如一些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对应的事件,这里需要对游戏进行一下“强制暂停”,另外如果“强制暂停”时间过长,网络游戏有时得重新登录等事件。