Unity3D中暂停时的动画及粒子效果实现

简介: 暂停是游戏中经常出现的功能,而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表示游戏中时间流逝快慢的尺度。

暂停是游戏中经常出现的功能,而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/

相关文章
|
前端开发 JavaScript
😲完了完了,forEach异步执行,怎么后面的先完成了!?
代码review,业务里的代码千奇百怪,到底还能遇到什么呢?oh no,真的有人在forEach里用异步调用!
691 0
|
存储 Java Linux
Linux下Maven编译工具的安装配置与打包
Linux下Maven编译工具的安装配置与打包
370 0
|
4月前
|
前端开发 JavaScript 关系型数据库
终于找到它了,别再等客户提需求才开始找,开发者必备!这个开源HR工具竟然能替代市面上90%的人事系统,还能免费商用!
Frappe HR 是一款开源、现代化的人力资源与薪资管理软件,基于 Frappe 框架构建,提供员工全生命周期管理、请假考勤、费用报销、绩效管理和薪资税务处理等功能。支持移动应用和多种部署方式(托管或本地),技术架构稳定且可扩展。相比同类项目,Frappe HR 具备高度自定义能力与成本效益,适合各规模企业。项目地址:https://github.com/frappe/hrms。
202 2
|
编解码 前端开发 图形学
【技术深度解析】多平台适配下的UI适配难题:U3D游戏UI错乱的终极解决方案
【7月更文第12天】随着移动设备市场的多元化,Unity游戏开发者面临的一大挑战是如何在不同分辨率和屏幕尺寸的设备上保持UI的一致性和美观性。游戏在高分辨率平板与低分辨率手机上呈现出的UI布局混乱、按钮错位等问题,严重影响玩家体验。本文旨在探讨Unity UI(UGUI)在多平台适配中的最佳实践,通过优化Canvas Scaler设置、灵活运用RectTransform和Anchor Points,以及高效利用设计工具,确保UI的完美适配。
1752 1
|
人工智能 定位技术 图形学
【unity实战】制作敌人的AI,使用有限状态机、继承和抽象类多态 定义不同状态的敌人行为
【unity实战】制作敌人的AI,使用有限状态机、继承和抽象类多态 定义不同状态的敌人行为
606 1
|
JavaScript API 数据库
ant design vue + jeecgboot 实现本地上传视频及播放视频功能
ant design vue + jeecgboot 实现本地上传视频及播放视频功能
678 2
|
图形学
【推荐100个unity插件之19】武器拖尾特效插件——Pocket RPG Weapon Trails(2d 3d通用)
【推荐100个unity插件之19】武器拖尾特效插件——Pocket RPG Weapon Trails(2d 3d通用)
432 0
|
移动开发 前端开发 Java
ruoyi-nbcio-plus后端里mapstruct-plus和lombok的使用
ruoyi-nbcio-plus后端里mapstruct-plus和lombok的使用
378 0
|
监控 NoSQL 测试技术
python使用Flask,Redis和Celery的异步任务
python使用Flask,Redis和Celery的异步任务
|
存储 监控 安全
DP读书:鲲鹏处理器 架构与编程(七)ARMv8-A 体系结构
DP读书:鲲鹏处理器 架构与编程(七)ARMv8-A 体系结构
681 0