zoukankan      html  css  js  c++  java
  • 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对应的事件,这里需要对游戏进行一下“强制暂停”,另外如果“强制暂停”时间过长,网络游戏有时得重新登录等事件。

  • 相关阅读:
    sqlmap注入分类
    sqlmap简单中文说明
    【Python Learning第一篇】Linux命令学习及Vim命令的使用
    模拟退火算法从原理到实战【基础篇】
    平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。
    使用VMWareWorkstation10搭建学习环境笔记
    洛谷P1313 计算系数【快速幂+dp】
    浅析Numpy.genfromtxt及File I/O讲解
    持续交付中高效率与高质量
    持续集成CI与自动化测试
  • 原文地址:https://www.cnblogs.com/hammerc/p/4869209.html
Copyright © 2011-2022 走看看