怎么实现游戏雷神加速器暂停功能能?都用Time.timeScale?

当前位置: >
在Unity中使用暂停的小技巧
时间: 12:09 来源:Unity之家 作者:unity.jb51.net 浏览:
很多人在游戏中写暂停脚本的时候,经常会想到 Time.timeScale = 0;&这种方法,但是 Time.timeScale 只是能暂停部分东西。如果在 update 函数中持续改变一个物体的位置,这种位置改变貌似是不会受到暂停影响的。比如:transform.position&=&transform.position+transform.TransformDirection(Vector3(0,0,throwForce));Time.timeScale = 0 的时候这个东西仍然在动。把使用Time.timeScale = 0; 功能的函数写在 FixedUpdate() , 当使用 Time.timeScale = 0&时项目中所有 FixedUpdate() 将不被调用,以及所有与时间有关的函数。&在 update 通过一个布尔值去控制暂停和恢复。Unity3D教程手册如果您设置 Time.timeScale 为 0,但你仍然需要做一些处理(也就是说动画暂停菜单的飞入),可以使用 Time.realtimeSinceStartup 不受 Time.timeScale 影响。另外您也可以参考一下 Unity Answer 上提到的方法 要暂停游戏时,为所有对象调用 OnPauseGame 函数:Object[]&objects&=&FindObjectsOfType&(typeof(GameObject));
foreach&(GameObject&go&in&objects)&
&&&&&&&&go.SendMessage&(&OnPauseGame&,&SendMessageOptions.DontRequireReceiver);
}从暂停状态恢复时:A basic script with movement in the Update() could have something like this:pvoid&OnPauseGame&()&&&&
&&&&&&&&paused&=&&&&&
void&OnResumeGame&()&&&&
&&&&&&&&paused&=&&&&&
void&Update&()&&&&
&&&&&&&&if&(!paused)&
&&&&&&&&{&&&&
&&&&&&&&&&&&&&&&//&do&movement&&&&
&&&&&&&&}&&&&
(责任编辑:脚印)
免责声明:Unity之家部分内容来源于互联网,如有侵权,请联系我们,本站将立即进行处理。
猜你也喜欢看这些 ??????
其他类型的Unity入门 ??????[Unity基础]对Time.timeScale的一些理解
总结如下:
1.timeScale不影响和,会影响
2.timeScale不影响,会影响和
3.timeScale不影响和,会影响
代码如下:
[csharp]&&
分别对部分代码进行注释,测试结果如下:
当等于时:
1.Update和可以执行,不可以执行
2.Time.realtimeSinceStartup依然在增加,和均不变
3.Time.fixedDeltaTime不变,变为,就像游戏正常速度运行下的
& 当想代码受控制时如暂停、加速,可以把代码放在中,又或者跟或扯上关系;否则,可以用类似正常状态下的和类似正常状态下的
已投稿到:2090人阅读
unity(20)
前提条件:在项目中用过Time.timeScale = 0来实现游戏暂停
问题: 暂停游戏后,暂停界面的按钮可能需要播放一个idle时的动画,Time.timeScale=0 会影响动画播放。
受Time.timeScale影响的因素:
1.物理模拟. FixedUpdate - 当Time.timeScale=0时,FixedUpdate 函数不会被执行,但是Update函数是会执行的。
2.Coroutines. - Time.timeScale=0 协程函数不会停止,但是会停止WaitForSeconds. 协成函数还是会每一帧都触发,但是WaitForSeconds使用的是当前的Time.deltaTime会变成0
和 InvokeRepeating. -延迟一段时间后掉用指定函数.
4.Particle System 粒子系统.
5.Animations. -动画. 如果我们使用的是Animator,可以设置动画忽略Time.timeScale带来的影响. 只需要把UpdateMode设置为UnScaled Time。
timeScale表示游戏中时间流逝快慢的尺度。这个参数是用来做慢动作效果的。
对于将timeScale设置为0的情况,仅只有一个补充说明。
在实际使用中,通过设置timeScale来实现慢动作特效,是一种相当简洁且不带任何副作用的方法.
但是当将timeScale设置为0来实现暂停时,由于时间不再流逝,所有和时间有关的功能都将停止,有些时候这正是我们想要的,因为毕竟是暂停。
但是副作用也随之而来,在暂停时各种动画和粒子效果都将无法播放(因为是时间相关的),FixedUpdate也将不再被调用。
那么我又如何通过timeScale来实现上面的效果呢?
刚好realtimeSinceStartup 与 timeScale 就无关,也就是说realtimeSinceStartup 不受timeScale 的影响。
因此realtimeSinceStartup 也就成了解决在暂停下的动画和粒子效果的救命稻草。对于Unity动画,
在每一帧,根据实际时间寻找相应帧并采样显示的方法来模拟动画,
public static IEnumerator Play( this Animation animation, string clipName, bool ignoreTimeScale, Action onComplete )
if(ignoreTimeScale)
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.realtimeSinceS
while (isPlaying) {
_timeAtCurrentFrame = Time.realtimeSinceS
_deltaTime = _timeAtCurrentFrame - _timeAtLastF
_timeAtLastFrame = _timeAtCurrentF
_progressTime += _deltaT
_currState.normalizedTime = _inReversePlaying ? 1.0f - (_progressTime / _currState.length)
: _progressTime / _currState.
animation.Sample();
if (_progressTime &= _currState.length) {
switch (_currState.wrapMode) {
case WrapMode.Loop:
_progressTime = 0.0f;
case WrapMode.PingPong:
_progressTime = 0.0f;
_inReversePlaying = !_inReverseP
case WrapMode.ClampForever:
case WrapMode.Default:
Debug.LogWarning("A Default Anim Finished. Animation should be played with wrap mode specified.");
isPlaying = false;
isPlaying = false;
yield return new WaitForEndOfFrame();
yield return null;
if(onComplete != null) {
onComplete();
if (onComplete != null) {
Debug.LogWarning("onComplete will not be called when you set \"ignoreTimeScale\" to true. Use Unity's animation handler instead!)");
animation.Play(clipName);
注:上面这段代码只对Animation有效,那针对Animator我们又如何在timeScale =0的情况下正常播放动画呢?
如果你是想游戏部分暂停,可以把暂停的部分写到FixedUpdate函数里面,不暂停写到Update函数。
float pauseTime =2f;
public void Pause()
if (isProp) {
pauseTime -= Time.fixedDeltaT
if (pauseTime &= 0) {
isProp = false;
pauseTime = 1f;
Time.timeScale = 1;
这个是局部暂停的代码。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:52522次
积分:1159
积分:1159
排名:千里之外
原创:55篇
转载:45篇
(3)(1)(1)(1)(7)(1)(1)(5)(9)(20)(8)(22)(9)(6)(8)Unity3D研究院之Time.timeScale、游戏暂停(七十四) | 雨松MOMO程序研究院
我的图书馆
Unity3D研究院之Time.timeScale、游戏暂停(七十四) | 雨松MOMO程序研究院
项目里面一直在用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 = 它就是控制控制NGUI 的UI动画是否受到ignoreTimeScale影响。如下图所示,你可以看看NGUI在Update里面的实现,它也是根据时间来判断的。忽略timescale的话就用真实时间,不忽略的话就用Time.time 和Time.deltaTime。
2.如何让游戏中某个游戏对象不受Time.timeScale影响。
动画不受timeScale影响:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
static IEnumerator Play( Animation animation, string clipName, bool useTimeScale,System.Action onComplete ) { if(!useTimeScale) { AnimationState _currState = animation[clipName]; bool isPlaying = float _startTime = 0F; float _progressTime = 0F; float _timeAtLastFrame = 0F; float _timeAtCurrentFrame = 0F; float deltaTime = 0F; animation.Play(clipName); _timeAtLastFrame = Time.realtimeSinceS while (isPlaying)
{ _timeAtCurrentFrame = Time.realtimeSinceS deltaTime = _timeAtCurrentFrame - _timeAtLastF _timeAtLastFrame = _timeAtCurrentF
_progressTime += deltaT _currState.normalizedTime = _progressTime / _currState.
animation.Sample (); if (_progressTime &= _currState.length)
{ if(_currState.wrapMode != WrapMode.Loop) { isPlaying = } else { _progressTime = 0.0f; } } yield return new WaitForEndOfFrame(); } if(onComplete != null) { onComplete(); }
} else { animation.Play(clipName); } }
粒子特效不受timescale影响
12345678910111213141516171819202122232425262728293031
using UnityEusing System.C public class ParticaleAnimator : MonoBehaviour {&& private void Awake() { particle = GetComponent&ParticleSystem&(); }
// Use this for initialization void Start () { lastTime = Time.realtimeSinceS }
// Update is called once per frame void Update ()
float deltaTime = Time.realtimeSinceStartup - (float)lastT &&&&&&&& particle.Simulate(deltaTime, true, false); //last must be false!! &&&&&&&& lastTime = Time.realtimeSinceS }
private double lastT private ParticleS }
经过我的测试发现timeScale = 0 时, 播放放粒子特效,效率上有很大问题非常的卡。
举个例子啊,刀塔传奇大家都玩过吧?某个角色放技能的时候,其他所有人物动作全部暂停,并且打出去的技能也暂停。等着角色的技能全部放完,别人才恢复正常。 我觉得向做这类游戏,最好就不要 利用timeScale了,不然写起来太蛋疼了。 不过刀塔传奇也没有 1 倍 2倍 &3倍速 的功能吧,呵呵。
3.timeScale变化时的声音。
当声音播放的同时去修改timescale的数值你会发现声音播放的很奇怪。如下代码所示,你可以封装一个方法,把IgnoreTimeScale作为参数传进去, 如果忽略timescale的话那么速度就应该是1否则就应该是Time.timeScale。
<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df
//添加一个声音组件AudioSource source = gameObject.AddComponent&AudioSource&();//设置播放声音的速度。 默认速度是1 ,那如果我们加速了,那就应该是 Time.timeScalesource.pitch =IgnoreTimeScale?1:Time.timeS//播放声音source.Play();
此时如果修改了Time.timeScale的数值的话,那么正在播放中的声音会非常奇怪。所以当每次播放音频的时候我们需要记录一下这个音频的状态,它是否需要忽略timeScale当前的数值。
//创建一个音频的字典private static Dictionary&AudioSource,bool&soundList = new Dictionary&AudioSource, bool&();//播放声音source.Play();//把音频对象加入字典中,value 就是是否忽略timescalesoundList.Add(source,IgnoreTimeScale);
每当timeScale变化的时候调用一下下面这个方法。就是遍历一下当前保存的所有音频对象,从新设置一下他们的播放频率。
<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df<div data-line="crayon-553df
&&&&public static void TimeScaleChanged()&&&&{ foreach (AudioSource source in soundList.Keys)&& {&& if(source != null) { source.pitch = soundList[source]?1:Time.timeS } }&&&&&&}
如果你有更好的建议,欢迎在下面给我留言,谢谢。
本文固定链接:
转载请注明:
MOMO与MO嫂提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
最后编辑:作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
TA的最新馆藏
喜欢该文的人也喜欢

我要回帖

更多关于 雷神加速器暂停功能 的文章

 

随机推荐