做游戏的时候想做一个"子弹时间"的效果,也就是帝国时代电影,或者说例如暗影魔多游戏里面的瞄准时间。
做法是:是以120架照相机精确地摆放在一条由电脑追踪系统设定的路线上,然后让这些相机的快门按照电脑预先编程好的顺序和时间间隔开始拍照,然后把各个角度拍得的照片全部扫描进电脑,由电脑对相邻两张照片之间的差异进行虚拟修补,这样就能获得360度镜头下拍摄对象的连贯、顺滑的动作,最后再由电脑将该连贯的动态图象与背景融合,才有了我们在电影中看到的令人拍案叫绝的新奇镜头。
-------------------------------------------------------------
不对 !我们是要在unity游戏里面实现。
so,接下来和我一起猜想,然后实验,最后给出方案。
实现子弹时间的效果,相信大家都会第一时间想到,只要整个游戏放慢,再让主角不受影响或者加快主角就可以了!
也就是减少Time.timeScale,但问题随之而来!timeScale的减少后发现---物理碰撞经常失效!
我猜想是Fixedupdate和碰撞检测受到了影响,然后就有了以下测试效果。
我为了方便观察,debug的时候输出了时间,然后我设定Fixed Timestep为0.02,大家可以在project setting的time里面查看,按道理来说这样的设置,fixedupdate里debug会每秒输出50次。
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;
}
----------------------------------------------------------------
接下来实验开始,我们运行游戏,先观察输出,然后用按钮改变Time.timeScale=0.1f,再观察变化;
实验效果如下:
①.Update不受影响,观察改变scale前后的输出速度一样,依然一秒输出N次;
②FixedUpdate受到了影响!可以看到基本一秒只输出5次左右,符合猜想√;
③碰撞检测,也受到了影响,一秒也只输出5次左右,符合猜想√;
④这个是dealtime,可以看到改变之后dealtime减少了10倍
受timeScale影响的一些主要函数和Component
-
MonoBehaviour.Invoke()
-
MonoBehaviour.InvokeRepeating()
-
yield WaitForSeconds()
-
GameObject.Destroy()
-
Animation Component
-
Time.time, Time.deltaTime
欢迎留言补充其他测试效果或者指出错误。
-----------------------
思考后,我有个2个实现方案:
①如果单纯减少的timescale来实现时间变慢就要去处理碰撞检测次数减少的问题了!
可能在开启timescale需要减少相应的Fixed Timestep数值,但是可能会遇到主角的fixedupdata增加等问题;
②我就有了另外一个大胆的想法,去控制除主角外其他所有物体的一切速度,例如动画的speed,运动的dealtime...
听上去很麻烦,但只需要分发有影响的速度的委托或者管理好资源池然后去遍历改变。
-----------------------------------------
欢迎提出讨论其他解决方案和更好的想法。