首先上效果图
重点
重点一
首先当你想用Time.timeScale=0使游戏暂停的时候,FixedUpdate是不会被调用的,Animation也不会继续播放,所以我们只能用代码去控制动画的播放了。
重点二
不可以用Lerp插值和SmoothDamp函数来用代码实现动画的播放。
他们都需要用到Time.timeScale,但是Time.timeScale=0,所以他们也不考虑了。
重点三
realtimeSinceStartup与timeScale无关。
我们来看看realtimeSinceStartup的官方描述
定义:游戏开始以来的实际时间(只读)。
在几乎所有情况下,您都可以并且应该使用 Time.time。
realtimeSinceStartup 返回自启动以来的时间,不受 Time.timeScale 的影响。 在播放器暂停期间(在后台),realtimeSinceStartup 仍会不断增加。 当您需要通过将 Time.timeScale 设置为 0 来暂停游戏,但仍希望能够以某种方式测量时间时, realtimeSinceStartup 非常有用。
注意,realtimeSinceStartup 返回系统计时器报告的时间。 根据平台和硬件的不同,它可能会在数个连续帧中报告相同的时间。 如果您需要用某个值除以时间差,一定要考虑到这一点 (时间差可能会变为 0!)。
这就给了我们制作暂停动画的可能。
具体实现
先给上UI的原来的坐标(正常游戏的坐标,此时UI是在屏幕之外)
UI变换之后的坐标(此时UI在屏幕的中间)
总效果
扫描二维码关注公众号,回复:
14230705 查看本文章

代码
当玩家按下暂停键的时候调用如下代码:
private IEnumerator Pause()
{
Time.timeScale = 0f;
RectTransform rectTransform = GetComponent<RectTransform>();//需要移动的UI的RectTransform
float lastFrameTime;//上一帧的时间
float currentFrameTime;//当前帧的时间
float deltaTime;//相邻两帧的时间间隔
while (rectTransform.anchoredPosition3D.y > Mathf.Epsilon)//如果UI的y坐标大于0(Mathf.Epsilon代表浮点数的最小值,浮点数运算尽量别用整数)
{
lastFrameTime = Time.realtimeSinceStartup;//更新上一帧的时间
yield return null;//跳过这一帧,为了在下一帧计算相邻两帧的间隔
currentFrameTime = Time.realtimeSinceStartup;//更新当前帧的时间
deltaTime = currentFrameTime - lastFrameTime;//计算相邻两帧的时间间隔
/*
* menuOriginPosY代表UI的原来的y坐标
* rectTransform.anchoredPosition3D + Vector3.down * menuOriginPosY的意思是将UI的y坐标从原来的位置变换到y=0的位置,也就是中心位置
*/
rectTransform.anchoredPosition3D = Vector3.Lerp(
rectTransform.anchoredPosition3D,
rectTransform.anchoredPosition3D + Vector3.down * menuOriginPosY,//可以理解为 y = y + (-1) * y;
deltaTime * animationDeltaTimeRate);//animationDeltaTimeRate是变换频率,如果该值过高变换速度快
}
//指定到暂停的位置,因为Lerp不能准确定位到一个整数,所以我们这里给它定位一下
rectTransform.anchoredPosition3D = m_menuPausePos;
}
下面实现下继续游戏的代码(步骤基本一样我就不写注释了)
public IEnumerator Resume()
{
RectTransform rectTransform = GetComponent<RectTransform>();
float lastFrameTime;
float currentFrameTime;
float deltaTime;
while (rectTransform.anchoredPosition3D.y < menuOriginPosY)
{
lastFrameTime = Time.realtimeSinceStartup;
yield return null;
currentFrameTime = Time.realtimeSinceStartup;
deltaTime = currentFrameTime - lastFrameTime;
rectTransform.anchoredPosition3D = Vector3.Lerp(
rectTransform.anchoredPosition3D,
rectTransform.anchoredPosition3D + Vector3.up * menuOriginPosY,
deltaTime * animationDeltaTimeRate);
}
//恢复到原位
rectTransform.anchoredPosition3D = m_menuOriginPos;
Time.timeScale = 1f;
}