原文链接

项目里面一直在用Time.timeScale来做游戏的 1倍 2倍整体加速,今天我仔细看了一下Time.timeScale才发现之前我理解错了一些东西。

Time.timeScale可以控制Update 和LateUpdate 的执行速度,举个例子说明一下。

Time.timeScale=1时,Update、LateUpdate、FixedUpdate 都按正常的时间来执行。

Time.timeScale=2时,Update和 LateUpdate的执行速度是之前的2倍,而FixedUpdate还是按正常时间来执行。

Sorry上面红色这部分确实是写错了,感谢网友在留言处给我的指正,谢谢。

正确的应该是timeScale不会影响Update和LateUpdate的执行速度。因为FixedUpdate是根据时间来的,所以timeScale只会影响FixedUpdate的速度。 再次抱歉。。 谢谢热心网友给我的指正。。 因为我的项目里在处理战斗部分的时候 大量使用 iTween 所以  2  3 倍加速 或者暂停 的功能直接修改timeScale 。

Time.timeScale也误导了我很久,为什么这么说呢?我原先一直以为Time.timeScale = 0 的话所有的Update都不执行了。今天测试了一下发现原来不是这样的,无论Time.timeScale 等于多说Update和LateUpdate都会去执行,不信你可以自己做个实验看看。

Time.timeScale还会影响Time.time的时间,比如Time.timeScale = 2的话,那么Time.time的增长速度也会变成2倍速度。如果你想取到游戏的实际时间,那么使用Time.timeSinceLevelLoad就可以,前提是必须在Awake()方法以后再取,如果在Awake()方法里面取Time.realtimeSinceStartup会取出一个错误的值,在Start方法里面取的话就正常了。

总之一句话Time.timeScale影响的是Unity的游戏时间缩放比例。Unity里面所有跟时间有关系的东西都是根据timeScale来演算的。仔细想想现在的手游就是个 动画 和 粒子技能特效 还有UI位移特效,所以改他们的速度直接用Time.timeScale就可以完成。还有一个重要的东西就是人物移动 或者 技能移动的速度了, 根据时间的公式,时间 = 路程\速度 ,比如角色从起点跑到中间的一个预期时间, 或者一个技能的火球从攻击到打中目标的预期时间。 凡是处理时间的东东全用Time.time 这样就可以完美让Time.timeScale控制你的游戏了。

下面说说两个大家伙比较关心的话题。

1.游戏暂停

设置 Time.timeScale = 0;即可让游戏暂停。 其实我们暂停的主要是 人物动画,还有技能特效,比如一个火球打了一半。UI方面往往我们不希望暂停,比如暂停界面 有一些UI位移动画或者帧动画, 或者最起码要有个“取消暂停的按钮” 吧。 总不能游戏暂停了我点击按钮 按钮的点击动画 或者特效也暂停了吧。

所有的动画都是基于时间来的,因为Time.timeScale = 0了,所以Time.time也就不会在变化了。换句话来说如果游戏暂停以后想在暂停界面上继续播放一些不受Time.timeScale 影响的动画,那么我们就需要用到Time.realtimeSinceStartup

如果你的项目NGUI的版本还算比较新的话,你会发现在UITweener.cs处理UI动画的基类里面已经增加了一个属性叫public bool ignoreTimeScale = true; 它就是控制控制NGUI 的UI动画是否受到ignoreTimeScale影响。如下图所示,你可以看看NGUI在Update里面的实现,它也是根据时间来判断的。忽略timescale的话就用真实时间,不忽略的话就用Time.time 和Time.deltaTime。

2.如何让游戏中某个游戏对象不受Time.timeScale影响。

动画不受timeScale影响:

http://answers.unity3d.com/questions/217351/animations-ignore-timescale.html

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
static IEnumerator Play( Animation animation, string clipName, bool useTimeScale,System.Action onComplete )
{
if(!useTimeScale)
{
AnimationState _currState = animation[clipName];
bool isPlaying = true;
float _startTime = 0F;
float _progressTime = 0F;
float _timeAtLastFrame = 0F;
float _timeAtCurrentFrame = 0F;
float deltaTime = 0F;
animation.Play(clipName);
_timeAtLastFrame = Time.realtimeSinceStartup;
while (isPlaying)
{
_timeAtCurrentFrame = Time.realtimeSinceStartup;
deltaTime = _timeAtCurrentFrame - _timeAtLastFrame;
_timeAtLastFrame = _timeAtCurrentFrame;
 
_progressTime += deltaTime;
_currState.normalizedTime = _progressTime / _currState.length;
animation.Sample ();
if (_progressTime >= _currState.length)
{
if(_currState.wrapMode != WrapMode.Loop)
{
isPlaying = false;
}
else
{
_progressTime = 0.0f;
}
}
yield return new WaitForEndOfFrame();
}
yield return null;
if(onComplete != null)
{
onComplete();
}
}
else
{
animation.Play(clipName);
}
}

粒子特效不受timescale影响

https://gist.github.com/AlexTiTanium/5676482

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using UnityEngine;
using System.Collections;
 
public class ParticaleAnimator : MonoBehaviour {
  
private void Awake()
{
particle = GetComponent<ParticleSystem>();
}
 
// Use this for initialization
void Start ()
{
lastTime = Time.realtimeSinceStartup;
}
 
// Update is called once per frame
void Update ()
{
 
float deltaTime = Time.realtimeSinceStartup - (float)lastTime;
 
         particle.Simulate(deltaTime, true, false); //last must be false!!
 
         lastTime = Time.realtimeSinceStartup;
}
 
private double lastTime;
private ParticleSystem particle;
 
}

经过我的测试发现timeScale = 0 时, 播放放粒子特效,效率上有很大问题非常的卡。

举个例子啊,刀塔传奇大家都玩过吧?某个角色放技能的时候,其他所有人物动作全部暂停,并且打出去的技能也暂停。等着角色的技能全部放完,别人才恢复正常。 我觉得向做这类游戏,最好就不要 利用timeScale了,不然写起来太蛋疼了。 不过刀塔传奇也没有 1 倍 2倍  3倍速 的功能吧,呵呵。

3.timeScale变化时的声音。

当声音播放的同时去修改timescale的数值你会发现声音播放的很奇怪。如下代码所示,你可以封装一个方法,把IgnoreTimeScale作为参数传进去, 如果忽略timescale的话那么速度就应该是1否则就应该是Time.timeScale。

 
 
1
2
3
4
5
6
//添加一个声音组件
AudioSource source = gameObject.AddComponent<AudioSource>();
//设置播放声音的速度。 默认速度是1 ,那如果我们加速了,那就应该是 Time.timeScale
source.pitch =IgnoreTimeScale?1:Time.timeScale;
//播放声音
source.Play();

此时如果修改了Time.timeScale的数值的话,那么正在播放中的声音会非常奇怪。所以当每次播放音频的时候我们需要记录一下这个音频的状态,它是否需要忽略timeScale当前的数值。

 
 
1
2
3
4
5
6
7
8
//创建一个音频的字典
private static Dictionary<AudioSource,bool>soundList = new Dictionary<AudioSource, bool>();
 
//播放声音
source.Play();
 
//把音频对象加入字典中,value 就是是否忽略timescale
soundList.Add(source,IgnoreTimeScale);

每当timeScale变化的时候调用一下下面这个方法。就是遍历一下当前保存的所有音频对象,从新设置一下他们的播放频率。

 
 
1
2
3
4
5
6
7
8
9
10
    public static void TimeScaleChanged()
    {
foreach (AudioSource source in soundList.Keys)  
{  
if(source != null)
{
source.pitch = soundList[source]?1:Time.timeScale;
}
}  
    }

Time.timeScale、游戏暂停的更多相关文章

  1. Unity游戏暂停之Update与FixedUpdate区别

    游戏暂停 示例程序 下面这段代码演示游戏暂停 using UnityEngine; using System.Collections; public class GamePauseTest : Mon ...

  2. Unity3D之游戏暂停制作方法记录

    在游戏开发中我们一般都需要涉及到一个功能:游戏暂停,但是这里指的暂停仅仅是核心模块的暂停,并不是整个游戏都暂停,比如一些UI和UI上的动画与特效是不能被暂停的,整个游戏都暂停了玩家该如何继续游戏呢. ...

  3. SurvivalShooter学习笔记(九.游戏暂停、结束)

    这里先补充一个得分管理器: 玩家得分设置成一个静态变量: public class ScoreManager : MonoBehaviour { public static int score; // ...

  4. cocos2d-x 游戏暂停界面,监听home键,返回键,Menu键 解决方案

    游戏暂停界面: cocos2d-x中游戏暂停界面提供的思路是用pushScene()和popScne(),即推进和弹出场景,当游戏暂停时,推进(pushScene())暂停场景,之前运行的场景将会自动 ...

  5. 【Unity3d游戏开发】Unity中的Time.timeScale

    马三最近在做一款游戏的时候涉及到了“加速”和“暂停”这两个功能,我第一时间就想到了应该用 Time.timeScale.当暂停的时候,设置timeScale = 0,当需要加速的时候,将 timeSc ...

  6. 《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇03:暂停游戏》

    3.暂停游戏 暂停游戏概述: 在游戏进行时,玩家有可能会遇到多种突发事件.在跑酷游戏中突发状况的发生对游戏的影响更甚,游戏进行时玩家死亡,游戏只能从头开始,那么如果因为外界因素而影响游戏的进行,显然是 ...

  7. 【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现

    CSDN的markdown编辑器是吃屎了么! !.什么玩意.!写了一半写不了东西还全没了,搞个毛线! 本节课的视频教程地址是:第七课在此 假设本教程有帮助到您,希望您能点击进去观看一下,并且如今注冊成 ...

  8. 自制Unity小游戏TankHero-2D(3)开始玩起来

    自制Unity小游戏TankHero-2D(3)开始玩起来 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的.仅 ...

  9. Unity3D 之暂停和继续的实现

    Time.timeScale 时间缩放 当timeScale传递时间1.0时和实时时间一样快.当timeScale传递时间0.5时比实时时间慢一半. 当timeScale传递时间为0时游戏基本上暂停了 ...

随机推荐

  1. ASP.NET MVC项目里创建一个aspx视图

    先从控制器里添加视图 视图引擎选"ASPX(C#)",使用布局或模板页不要选. 在Views\EAV目录里,生成的aspx是个单独的页面,没有代码文件,所以代码也要写在这个文件里. ...

  2. Jquery CSS 与 Attr

    今天用Jquery想动态更改一张位图的src发现css不好用,查看Jquery文档好像是css是设置样式的属性的,如颜色,字体,背景等,而attr貌似是能操作所有属性,包括Jquery未封装的属性. ...

  3. 对于vijos11.2模拟赛

    特意起了个傻逼标题,只是想提醒一下自己以后不要犯逗(所以应该没有什么神犇点进来吧?) T1,T3 当场写的时候就觉得是不可写的,看了题解之后还是觉得不可写,人弱没办法.到了这个时候也懒得管这么难的东西 ...

  4. Repeater 模板中查找子控件

    前言:对于Repeater控件,相信从事NETWeb开发的同仁们再熟悉不过了.因其呈现方式和Literal一样,并不在前端生成任何表单标签元素,所以属于比较轻量级的控件.不过青睐于Repeater的主 ...

  5. 关于grub的那些事(二)

    上回说到/etc/default/grub文件,我直接抄了人家的文章,感觉那Wiki确实写的很详细,所以就用上拿来主义了. 这次是分析该文件,因为这是grub必读的文件,也记录着控制grub工作的环境 ...

  6. 企业架构研究总结(34)——TOGAF架构内容框架之架构制品(下)

    4.2.31 数据生命周期图(Data Lifecycle Diagram) 数据生命周期图是在业务流程的约束之下对业务数据在其整个生命周期(从概念阶段到最终退出)中对其进行管理的核心部分.数据从本质 ...

  7. iOS单元测试

    参考下面的链接 ,写的还不错 http://gaohaijun.blog.163.com/blog/static/176698271201151052325749/

  8. C Socket初探 - 加入多线程支持,限制最大接入客户端个数

    C Socket初探 - 加入多线程支持,限制最大接入客户端个数 先上一些多线程需要使用的函数定义: DWORD WINAPI ProcessClientRequests(LPVOID lpParam ...

  9. cocos2d-x 3.0 cocos run Couldn't find the gcc toolchain.

    出现这个错误是NDK_ROOT环境变量没有设置好,要么设置错了,要么没有重启终端(也就是环境变量还没有生效).我就是因为没有重启终端坑了一个晚上,我只能帮你到这了,玩cocos2d-x 3.0的朋友, ...

  10. Organic Solar Cells - Theory and Practice

    renewable engergy: Wind solar Tidal Wave Ocean Bio Etc. How much energy we gonna need as following y ...