暂停是游戏中经常出现的功能,而Unity3D中对于暂停的处理并不是很理想。一般的做法是将Time.timeScale设置为0。Unity的文档中对于这种情况有以下描述;

The scale at which the time is passing. This can be used for slow motion effects….When timeScale is set to zero the game is basically paused …

timeScale表示游戏中时间流逝快慢的尺度。文档中明确表示,这个参数是用来做慢动作效果的。对于将timeScale设置为0的情况,仅只有一个补充说明。在实际使用中,通过设置timeScale来实现慢动作特效,是一种相当简洁且不带任何毒副作用的方法,但是当将timeScale设置为0来实现暂停时,由于时间不再流逝,所有和时间有关的功能痘将停止,有些时候这正是我们想要的,因为毕竟是暂停。但是副作用也随之而来,在暂停时各种动画和粒子效果都将无法播放(因为是时间相关的),FixedUpdate也将不再被调用。

换句话说,最大的影响是,在timeScale=0的暂停情况下,你将无法实现暂停菜单的动画以及各种漂亮的点击效果。

但是并非真的没办法,关于timeScale的文档下就有提示:

Except for realtimeSinceStartup, timeScale affects all the time and delta time measuring variables of the Time class.

因为 realtimeSinceStartuptimeScale 无关,因此也就成了解决在暂停下的动画和粒子效果的救命稻草。对于Unity动画,在每一帧,根据实际时间寻找相应帧并采样显示的方法来模拟动画:

AnimationState _currState = animation[clipName];

bool isPlaying = true;
float _progressTime = 0F;
float _timeAtLastFrame = 0F;
float _timeAtCurrentFrame = 0F;
bool _inReversePlaying = false;
float _deltaTime = 0F; animation.Play(clipName);
_timeAtLastFrame = Time.realtimeSinceStartup; while (isPlaying) {
_timeAtCurrentFrame = Time.realtimeSinceStartup;
_deltaTime = _timeAtCurrentFrame - _timeAtLastFrame;
_timeAtLastFrame = _timeAtCurrentFrame;
_progressTime += _deltaTime;
_currState.normalizedTime = _inReversePlaying ? 1.0f - (_progressTime / _currState.length) : _progressTime / _currState.length;
animation.Sample();
//…repeat or over by wrap mode
}

对于粒子效果,同样进行计时,并通过粒子系统的Simulate方法来模拟对应时间的粒子状态来完成效果,比如对于Legacy粒子,使Emitter在timeScale=0暂停时继续有效发射并显示效果:

_deltaTime = Time.realtimeSinceStartup - _timeAtLastFrame;
_timeAtLastFrame = Time.realtimeSinceStartup;
if (Time.timeScale == 0 ){
_emitter.Simulate(_deltaTime);
_emitter.emit = true;
}

核心的代码基本都在上面了,可以根据这个思路完成实现。完整的代码和示例工程我放到了github上,有需要的朋友可以去查看,也欢迎大家指正。

https://onevcat.com/2013/01/do_not_pause_me/

Unity3D中暂停时的动画及粒子效果实现的更多相关文章

  1. Unity3d中使用自带动画系统制作下雨效果(一)

    之前看了以前版本的unity3d demo AngryBots ,觉得里面的下雨效果不错,刚好前段时间学习了,写出来跟大家分享下,直接开始. 使用自带动画系统制作下雨效果. 先制作下雨的雨滴涟漪. 步 ...

  2. Unity3d中使用自带动画系统制作下雨效果(二)

    接着昨天的(一),今天上下雨效果的后半部分.在最后附上网盘链接,有使用的素材及本次的工程源文件,想看看的童鞋可以下载~~ 下雨效果分两部分:地上的涟漪和空中的雨滴.那么现在就开始,是使用unity3d ...

  3. Unity3D中UGUI不使用DOTween制作渐隐渐现效果

    在做UI后期设计时,我们可能要对UI做一些特效,这篇文章我们来学习下如何在Unity3d中对实现渐隐渐现的效果, 首先我们看下Unity New UI即UGUI中渐隐渐现的做法. 观察我们会发现Uni ...

  4. swift 实现漂亮的粒子效果CAEmitterLayer

    一些粒子效果 我们经常会在一些游戏或者应用中看到一些炫酷的粒子效果,我们在iOS中也能很轻松的搞一些粒子效果 我们本次做得是一个下雪的效果,看下效果图 源码地址: https://github.com ...

  5. 转 [教程] Unity3D中角色的动画脚本的编写(二)

              在上一篇,我们介绍了有关Animation这个类中的部分方法,我后来想了想,这么介绍也不是个办法(其实有些方法我自己也没用过),该介绍点实际的东西了,毕竟我们是要做东西出来的.那好 ...

  6. Unity3D 中 Generic 动画导入设置和 Root Motion 之间的关系

    2条评论 Unity3D 的 Mecanim 动画系统可以直接复用 3DS MAX 中制作的动画文件中的位移,这个就是通过 applyRootMotion 来达成的,我们只需要在使用 Animator ...

  7. (转) [教程] Unity3D中角色的动画脚本的编写(一)

    ps: 这两天研究unity3d,对动画处理特别迷糊,不知FBX导入以后,接下来应该怎么操作,看到这篇文章,感觉非常好,讲解的很详细. 已有好些天没写什么了,今天想起来该写点东西了.这次我所介绍的内容 ...

  8. (转)在Unity3D中控制动画播放

    用Unity3D也算是好久了,但是每次做项目总还是能学到新的东西.这次做一个TPS的项目就遇到了这样一个问题,如何同时在上下半身播放不同的动画?解决方法其实是很简单,但由于对于动画资源的了解不足导致问 ...

  9. Unity3D中关于场景销毁时事件调用顺序的一点记录

    先说一下我遇到的问题,我弄了一个对象池管理多个对象,对象池绑定在一个GameObject上,每个对象在OnBecameInvisible时会进行回收(即移出屏幕就回收),但是当场景切换或停止运行程序时 ...

随机推荐

  1. SpringBoot RestFul集成Swagger2

    一.依赖: <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swa ...

  2. bower.json 的版本范围

    bower.json 的版本范围 有小伙伴问 ~2.2.0 什么意思. 而且在git 的tags 中没有了 2.2.0 版本,怎么样? 实际上 ~2.2.0 的意思是 >=2.2.0 <2 ...

  3. (四)、Fiddler打断点

    一.打断点是Fiddler一个比较好用的功能,它可以做一些手工操作很难做的事情. 那为什么要打断点? 看下图,Fiddler打开后,Client(客户端)发送的请求会先经过Fiddler,然后Fidd ...

  4. jdk1.8新特性之接口default方法

    众所周知,default是java的关键字之一,使用场景是配合switch关键字用于条件分支的默认项.但自从java的jdk1.8横空出世以后,它就被赋予了另一项很酷的能力——在接口中定义非抽象方法. ...

  5. Java 父类、静态、子类执行顺序

    顺序: 父类的静态,子类静态,父类非静态,父类构造方法,子类非静态,子类构造方法. public class A { static String name = "cjj"; int ...

  6. ubuntu16.04让内核编译一次过的方法

    问题: 进入内核后,发现make menuconfig 出错,而且在在网上找到的一些安装包,安装结束后,发现make menuconfig后的图形界面虽然出来了,但是图形界面里的内容没有出来! 解决方 ...

  7. 使用Ajax异步上传文件

    之前上传文件都是用表单form设置post请求和enctype类型: <form id="upload_form"action="" method=&qu ...

  8. Angular2快速入门-4.创建一个服务(创建NewsService提供数据)

    上篇我们使用的数据是通过mock-news.ts中的const News[] 数组直接赋给Component 组件的,这篇我们把提供数据的部分单独封装成服务 第一.创建news.service.ts ...

  9. cinder-backup详细介绍

    首先介绍Snapshot snapshot可以为volume创建快照,快照中保存了volume当前的状态,此后可以通过snapshot回溯 主要采用了Copy On Write算法.进行快照时,不牵涉 ...

  10. 深入浅出 Java Concurrency (8): 加锁的原理 (Lock.lock)

    接上篇,这篇从Lock.lock/unlock开始.特别说明在没有特殊情况下所有程序.API.文档都是基于JDK 6.0的. public void java.util.concurrent.lock ...