纯唠
做游戏的时候想做一个"子弹时间"的效果,也就是帝国时代电影,或者说例如暗影魔多游戏里面的瞄准时间。
做法是:是以120架照相机精确地摆放在一条由电脑追踪系统设定的路线上,然后让这些相机的快门按照电脑预先编程好的顺序和时间间隔开始拍照,然后把各个角度拍得的照片全部扫描进电脑,由电脑对相邻两张照片之间的差异进行虚拟修补,这样就能获得360度镜头下拍摄对象的连贯、顺滑的动作,最后再由电脑将该连贯的动态图象与背景融合,才有了我们在电影中看到的令人拍案叫绝的新奇镜头。
不对 !我们是要在unity游戏里面实现,这和拍电影不一样。接下来让我们开始吧。
-------------------------------------------------------------
Update和FixUpdate定义
Update:
在每次渲染新的一帧的时候才会调用。也就是说,这个函数的更新频率和设备的性能有关以及被渲染的物体。在性能好的机器上可能fps 30,差的可能小些。
这会导致同一个游戏在不同的机器上效果不一致,有的快有的慢。因为Update的执行间隔不一样了。
FixedUpdate:
是在固定的时间间隔执行,不受游戏帧率的影响。但是会受到Time.Scale影响。
实验
so,接下来和我一起猜想,然后实验,最后给出方案。
实验条件:设定Fixed Timestep为0.02 (当为0.02一秒会执行50次,可以在project setting的tim设置),减少Time.timeScale为0.1
实验步骤:为了方便观察,在两个Update里Debug输出了时间,运行游戏,先观察输出,然后用按钮改变Time.timeScale=0.1f,再观察变化;
private void Update()
{
Debug.Log("Update");
Debug.Log(Time.deltaTime);
}
private void FixedUpdate()
{
Debug.Log("FixedUpdate");
}
private void OnTriggerStay2D(Collider2D collision)
{
Debug.Log("进入了他");
}
void ChangeTimeScale()
{
Time.timeScale = 0.1f;
}
改变前:观察输出次数
改变TimeScale后:
①.Update不受影响,观察改变scale前后的输出速度一样,依然一秒输出N次;
②改变TimeScale后,FixedUpdate受到了影响!从原来的50次,缩小到0.1倍,一秒只输出5次左右,符合猜想√;
问题随之而来,TimeScale的减少后发现---物理碰撞经常失效!
③碰撞检测,也受到了影响,一秒也只输出5次左右,符合猜想√;
④这个是dealtime,可以看到改变之后dealtime减少了10倍
结论:
update在改变timeScale后不受影响,因为这个只和性能有关。
Fixedupdate和碰撞检测受到了影响
受timeScale影响的一些主要函数和Component
- MonoBehaviour.Invoke()
- MonoBehaviour.InvokeRepeating()
- yield WaitForSeconds()
- GameObject.Destroy()
- Animation Component
- Time.time, Time.deltaTime
----------------------------------------------------------------
实现方案
实现子弹时间的效果,相信大家都会第一时间想到,只要整个游戏放慢,再让主角不受影响或者加快主角就可以了!
但因为碰撞也会受到影响,所以思考后,有个2个实现方案:
①如果单纯减少的timescale来实现时间变慢就要去处理碰撞检测次数减少的问题了!
可能在开启timescale需要减少相应的Fixed Timestep数值,但是可能会遇到主角的fixedupdata增加等问题;
②然后就有了另外一个大胆的想法,去控制除主角外其他所有物体的一切速度,例如动画的speed,特效的speed,运动的deltaTime,所有角色组件的deltaTime...
听上去很麻烦,不过我们在实际游戏开发过程中,一般都有各种Mgr,Mgr持有了所有对象。只需要分发有影响的速度的委托或者管理好资源池然后去遍历改变。