文档章节

时间和帧速率管理

LIndieGS
 LIndieGS
发布于 2017/05/25 16:05
字数 1695
阅读 23
收藏 0

原文链接:https://docs.unity3d.com/Manual/TimeFrameManagement.html

    Update()函数允许你有规律地监视输入和其它事件,并作出正确的行为。例如,你可以移动一个角色当“forward”键被按下时。值得记住的是,当处理基于时间的行为时,比如游戏的帧速率,在Update()函数调用中,既不是连续的,也不是持续一段时间的。

    这样一个例子,考虑持续向前移动移动一个物体的任务,一次一帧。起初,你可能想移动这个物体每一帧以一个固定的距离移动。

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerFrame;
    
    void Update() {
        transform.Translate(0, 0, distancePerFrame);
    }
}

    可是,给定的帧时间不是恒定不变的,这个物体就会以不规律的速度移动。如果帧时间是10毫秒,那么物体就会以distancePerFrame每秒向前100次。但是,如果帧时间减少到20毫秒(取决于CPU负载),那么就会每秒向前50次,因此移动更少的距离。解决方案是规定在帧时间里移动的大小。你可以从Time.deltaTime的性质中了解更多。

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerSecond;
    
    void Update() {
        transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
    }
}

    值得注意的是,设置移动,更多的是以distancePerSecond,而不是distancePerFrame。当帧速率改变时,每步移动的大小也会相应的改变,因此,物体的速度也就不会改变。

固定时间步(Fixed Timestep)

    不像主帧的刷新,Unity的物理系统是以固定时间步工作的,这对精确的模拟现实很重要。在物理刷新的一开始,也就是上一个物理刷新结束,Unity设置一个“alarm”,并添加固定时间步到时间里。脚本就会开始计算直到alarm结束。

    你可以从TimeManager中改变固定时间步的大小,你也可以使用Time.FixedDeltaTime的性质从脚本中读取固定时间步。值得注意的是,时间步越小,物理刷新越快,模拟得就更精确,但这会消耗更多的CPU负载。其实,只要你对物理引擎没有更高的要求,你就可能不需要改变默认的时间步。

最大允许时间步

    固定时间步实时地保持物理模拟得准确性,但是它也会导致一些问题。比如在游戏的某个场景使物理模拟得占用过大,同时游戏的帧率也会变得很低。(取决于场景中物体的数量)主帧刷新的过程不得不在规律的物理刷新和如果有许多进程要去做,然后数个物理刷新在一帧中同时发生中设法腾出空间。因此,在一个帧时间中,物体的位置和其他的性质在一帧开始时被冻结,画面能和跟频繁的物理刷新同时出现。

    自然而然的,CPU的自由有限,但是Unity可以选择是你有效地减慢物理时间,使帧处理能跟上。最大允许时间步设置(在Time Manger中)放一个时间量的限制,Unity就会在这段时间里处理物理事件,FixedUpdate在给定的帧刷新中调用。如果一帧的更新时间超过了最大允许时间步,物理引擎就会“停止时间”,使帧的处理更跟上。一旦帧更新结束,物理将会继续,即使从它停止后没有就时间了。这就导致刚体(rigidbodies)不能实时完美运行,但这种减速是轻微的。不管怎样,物理时钟会仍然跟踪它们,即使它们在正常移动。这种物理延迟通常是注意不到的,是一个种接受的与游戏性能的折中。

Time Scale

    对于一些特殊的效果,例如“子弹时间”,有时放慢游戏的速度,便于动画和脚本的反应在降低的帧率下发生。另外,你想完全冻结游戏里的时间,比如在游戏暂停时。Unity有一个Time Scale的属性控制游戏里的时间相对于真实时间的快慢。如果大小设为1.0,那么游戏时间相当于真实时间。如果设为2.0,使游戏时间是真实时间的两倍(动作将会加速)。当设为0.5时,就会将游戏时间速度减半。设为0时会使时间完全停止。值得注意的是,time scale不会真正减慢执行速度但会改变time step,从而改变Update和FixedUpdate函数的Time.deltaTime和Time.fixedDeltaTime。当游戏时间减慢,但deltaTime帧会减少,Update函数会被比平时调用得更频繁。其他的脚本函数不会受time scale的影响,所以在游戏停止时,你可以正常显示GUI。

    Time Manager有一个属性可以让你设置全局time scale,这很方便的从脚本这设值,使用Time.timeScale属性。

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    void Pause() {
        Time.timeScale = 0;
    }
    
    void Resume() {
        Time.timeScale = 1;
    }
}

捕捉帧率

    一个关于时间管理的特案是你想以视屏的形式记录游戏。因此,保存屏幕画面的任务会花费很多时间,如果你在正常的游戏里企图这样做,游戏的帧率将会大幅下降。这就导致,视屏不能真实反映游戏的情况。

    幸运的是,Unity提供了一个Capture Framerate的属性,它能让你绕过这个问题。当属性值被设为任何一个大于0的数,游戏时间将会减慢,帧刷新会在准确的规则的间隔执行。这些间隔在帧与帧之间等于1/Time.captureFramerate,因此如果你将值设为5,那么刷新就会在一秒钟执行5次。因为对帧率的需求有效地降低,你就有时间在Update函数里保存截屏或执行其他操作。

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    // Capture frames as a screenshot sequence. Images are
    // stored as PNG files in a folder - these can be combined into
    // a movie using image utility software (eg, QuickTime Pro).
    // The folder to contain our screenshots.
    // If the folder exists we will append numbers to create an empty folder.
    string folder = "ScreenshotFolder";
    int frameRate = 25;
        
    void Start () {
        // Set the playback framerate (real time will not relate to game time after this).
        Time.captureFramerate = frameRate;
        
        // Create the folder
        System.IO.Directory.CreateDirectory(folder);
    }
    
    void Update () {
        // Append filename to folder name (format is '0005 shot.png"')
        string name = string.Format("{0}/{1:D04} shot.png", folder, Time.frameCount );
        
        // Capture the screenshot to the specified file.
        Application.CaptureScreenshot(name);
    }
}

    虽然使用了这种技术的游戏录制功能看起来不错,但游戏可能难以游玩当速度减得很慢时。你可能需要测试一下Time.captureFramerate的值,允许足够的时间来记录,而不会使测试人员的工作过度的复杂。

© 著作权归作者所有

共有 人打赏支持
LIndieGS
粉丝 0
博文 9
码字总数 6421
作品 0
程序员
走在网页游戏开发的路上(六)

本文转自吴秦博客园博客,原文链接:http://www.cnblogs.com/skynet/archive/2011/06/11/2078554.html,如需转载请自行联系原作者Flash动画原理 ——动画是将静止的画面变为动态的艺术.实现...

老朱教授
2017/11/26
0
0
业界 | Facebook刚刚定义了一个新的时间单位Flicks,造福程序猿

今天凌晨,Facebook推出了一款新"产品"——Flicks,一种新的时间单位。是的,一个新的时间单位,和“秒”或“分钟”或“小时”一样的时间单位。 Facebook开源官方发推特发布了这一消息 不少人...

阿里云_云栖社区
01/24
0
0
计算机网络之数据链路层

数据链路层功能: 数据链路的建立、维护与拆除;帧包装 帧传输 帧同步;帧的差错恢复 ;流量控制 ; 以太网: 局域网就是以太网;以太网工作在数据链路层; 以太网注意的三个问题:数据的冲突...

闪耀小行星
01/04
0
0
Canvas 入门6 requestAnimationFrame实现动画

本文学习资源来自《HTML5 Canvas核心技术 图形、动画与游戏开发》 尽量不要使用setInterval和setTimeout来实现动画,而应该使用requestAnimationFrame()方法来让浏览器自行决定帧速率。 由于...

xundh
2017/12/07
0
0
交换机性能指标

一般厂商标称交换机性能会包含两个指标,一是交换背板(或者叫交换矩阵),一是包转发速率。 交换背板是指交换机内部架构的带宽,单位是bps,比如说super720的交换背板能力为720Gbps。这是引...

余二五
2017/11/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

TypeScript基础入门之高级类型的字符串字面量类型

转发TypeScript基础入门之高级类型的字符串字面量类型 高级类型 字符串字面量类型 字符串字面量类型允许你指定字符串必须的固定值。 在实际应用中,字符串字面量类型可以与联合类型,类型保护...

durban
19分钟前
2
0
iOS权限授权添加

<!-- 相册 --> <key>NSPhotoLibraryUsageDescription</key> <string>App需要您的同意,才能访问相册</string> <!-- 相册写入 --> <key>NSPhotoLibraryAddUsageDescription</key> <string>App......

RainOrz
23分钟前
1
0
支配树(Dominator Tree)

MAT中的支配树 在使用MAT分析项目的内存泄漏问题时,其中有一个支配树(Dominator)视图。如果我们把Java对象之间的引用关系看做一张有向图(可以存在环)的话,对象的支配树体现了对象之间的...

akane_oimo
25分钟前
1
0
xshell官网下载及安装(免费版本)

百度搜索xshell,点击xshell官网下载链接,如图 然后点击下图的按钮 点击Latest Products,可以下载最新版本,选择要下载的版本,点击下载 选择上面红框里面的,并填写内容,submit之后会有邮...

曾大大胖
30分钟前
2
0
Android 调用系统分享文字、图片、文件,可直达微信、朋友圈、QQ、QQ空间、微博

兼容SDK 18以上的系统,直接调用系统分享功能,分享文本、图片、文件到第三方APP,如:微信、QQ、微博等 因为偷懒,可直达微信、朋友圈、QQ、QQ空间、微博的分享仅写了图片分享的,其他的文本...

她叫我小渝
31分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部