This page has been translated automatically.
视频教程
界面
要领
高级
实用建议
UnigineEditor
界面概述
资产工作流程
设置和首选项
项目开发
调整节点参数
Setting Up Materials
Setting Up Properties
照明
Landscape Tool
Sandworm
使用编辑器工具执行特定任务
Extending Editor Functionality
嵌入式节点类型
Nodes
Objects
Effects
Decals
光源
Geodetics
World Nodes
Sound Objects
Pathfinding Objects
Players
编程
搭建开发环境
Usage Examples
C++
C#
UnigineScript
UUSL (Unified UNIGINE Shader Language)
Plugins
File Formats
Rebuilding the Engine Tools
GUI
双精度坐标
应用程序接口
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
创建内容
Content Optimization
Materials
Art Samples
Tutorials

引擎主循环

This article describes in detail the steps taken by the UNIGINE engine when the Engine::update(), Engine::render(), and Engine::swap() functions are called. For other steps and general information about execution sequence, see the Execution Sequence article.本文详细介绍了UNIGINE引擎在调用Engine::update(), Engine::render()Engine::swap()函数时所采取的步骤。有关执行顺序的其他步骤和一般信息,请参阅执行顺序文章。

注意
Each stage of the main loop is initiated by the application window created during the Initialization stage.主循环的每个阶段都由申请窗口初始化阶段创建。

The total time the main loop has taken is displayed by the Total counter in the Performance Profiler.主循环所用的总时间由 Total 计数器显示性能分析器.

UpdateUpdate#

The update part of the execution sequence includes the following:执行序列的 update 部分包括以下内容:

  1. The FPS value of the application starts to be calculated.开始计算应用程序的 FPS 值。

    注意
    Calculation of FPS starts only with the second rendered frame, while the very first one is skipped.FPS 的计算仅从第二个渲染帧开始,而跳过第一个。
  2. All pending console commands that were called during the previous frame are executed. The commands are executed in the beginning of the update() cycle, but before the scripts are updated, because otherwise they may violate the current process of rendering or physical calculations. 执行在前一帧期间调用的所有待处理控制台命令。命令在 update() 周期的开始执行,但在脚本更新之前,否则它们可能会违反当前的渲染或物理计算过程。
  3. If a world has been unloaded during the previous frame, another world is loaded: WorldLogic::init().如果在前一帧中卸载了一个世界,则加载另一个世界:WorldLogic::init()
  4. If the video_restart console command was executed previously (not in the current update stage), world shaders are created.如果之前执行了 video_restart 控制台命令(不在当前更新阶段),则会创建世界着色器。

    注意
    When video is restarted (for example, when the video mode is changed), the application window calls the destroyRenderResources() methods of the system and editor logic and plugins. However, it is performed not in the current update stage, but earlier.当视频重新启动时(例如更改 video mode 时),应用程序窗口调用系统和编辑器逻辑和插件的 destroyRenderResources() 方法。但是,它不是在当前更新阶段执行,而是更早执行。
  5. Properties, input, and controls are updated.更新了属性、输入和控件。
  6. Update of streamed textures, sound, and landscape.更新流式纹理、声音和景观。
  7. Game FPS and materials are updated.游戏 FPS 和材料更新。
  8. Ambient sound sources timers are updated.环境声源计时器已更新。
  9. The World Logic init() function for the newly loaded world is called.调用新加载世界的 World Logic init() 函数。
  10. The update() function of all plugins is called. What happens during it, solely depends on the content of this custom function.调用所有插件 update() 函数。在此期间会发生什么,完全取决于此自定义函数的内容。
  11. The Editor-related Logic is updated by calling the Editor update() function.通过调用 Editor update() 函数更新与编辑器相关的逻辑。
  12. The System Logic is updated. The default system script update() function performs the following:
    • The system script handles the mouse. It controls whether the mouse is grabbed when clicked (by default), the mouse cursor disappears when not moved for some time (set by the MOUSE_SOFT definition), or not handled by the system (set by the MOUSE_USER definition, which allows input handling by some custom module).The system script handles the mouse. It controls whether the mouse is grabbed when clicked (by default), the mouse cursor disappears when not moved for some time (set by the MOUSE_SOFT definition), or not handled by the system (set by the MOUSE_USER definition, which allows input handling by some custom module).
    • The main menu logic is updated (if the MENU_USER definition is not set).The main menu logic is updated (if the MENU_USER definition is not set).
    • Other system-related user input is handled. For example, the world state is saved or restored, or a screenshot of the current UNIGINE window contents is made, if required.Other system-related user input is handled. For example, the world state is saved or restored, or a screenshot of the current UNIGINE window contents is made, if required.
    • If the GPU Monitor plugin is initialized (the HAS_GPU_MONITOR definition is set), the plugin output is displayed in the application window and additional console commands become available.If the GPU Monitor plugin is initialized (the HAS_GPU_MONITOR definition is set), the plugin output is displayed in the application window and additional console commands become available.

      警告
      本段介绍的功能在 Community SDK 版本中不可用。
      您应该升级到 Sim SDK版本才能使用它。
    The system script handles the mouse. It controls whether the mouse is grabbed when clicked (by default), the mouse cursor disappears when not moved for some time (set by the MOUSE_SOFT definition), or not handled by the system (set by the MOUSE_USER definition, which allows input handling by some custom module).The main menu logic is updated (if the MENU_USER definition is not set).Other system-related user input is handled. For example, the world state is saved or restored, or a screenshot of the current UNIGINE window contents is made, if required.If the GPU Monitor plugin is initialized (the HAS_GPU_MONITOR definition is set), the plugin output is displayed in the application window and additional console commands become available.
    系统逻辑已更新。默认系统脚本update()函数执行以下操作:
    • The system script handles the mouse. It controls whether the mouse is grabbed when clicked (by default), the mouse cursor disappears when not moved for some time (set by the MOUSE_SOFT definition), or not handled by the system (set by the MOUSE_USER definition, which allows input handling by some custom module).系统脚本处理鼠标。它控制鼠标点击时是否被抓取(默认),鼠标光标在一段时间不移动时消失(由 MOUSE_SOFT定义设置),或者不被系统处理(由MOUSE_USER定义设置,允许输入处理一些自定义模块)。
    • The main menu logic is updated (if the MENU_USER definition is not set).更新主菜单逻辑(如果未设置 MENU_USER定义)。
    • Other system-related user input is handled. For example, the world state is saved or restored, or a screenshot of the current UNIGINE window contents is made, if required.处理其他与系统相关的用户输入。例如,如果需要,保存或恢复世界状态,或者制作当前 UNIGINE 窗口内容的屏幕截图。
    • If the GPU Monitor plugin is initialized (the HAS_GPU_MONITOR definition is set), the plugin output is displayed in the application window and additional console commands become available.如果 GPU Monitor插件已初始化(设置了HAS_GPU_MONITOR定义),则插件输出将显示在应用程序窗口中,并且其他控制台命令可用。

      警告
      本段介绍的功能在 Community SDK 版本中不可用。
      您应该升级到 Sim SDK版本才能使用它。
  13. If the world is loaded (it can be done from the console or via the System Logic), the World Logic gets updated. In the World Logic update() function, you can code frame-by-frame behavior of your application (see details here). 如果世界已加载(可以从安慰或通过系统逻辑),世界逻辑得到更新。在 World Logic update() 函数中,您可以对应用程序的逐帧行为进行编码(请参阅详细信息这里)。

    注意
    Physics, if any, and continuous operations (pushing a car forward depending on current motor's RPM, simulating wind blowing constantly, performing immediate collision response, etc.), can be implemented separately in the updatePhysics() function. This function is called with a fixed frame rate (while the update() function is called each frame).物理(如果有)和连续操作(根据当前电机的 RPM 推动汽车向前,模拟不断吹来的风,执行即时碰撞响应等),可以在 updatePhysics() 函数中单独实现。该函数以固定的帧速率调用(而 update() 函数每帧调用一次)。

    The world and its world logic are updated in the following order:世界及其世界逻辑按以下顺序更新:

    1. The World Logic updateAsyncThread() function is executed. It is designed to perform logic functions that should be called every frame independently of the rendering thread. This function doesn't block the Main Thread.World Logic updateAsyncThread() 函数被执行。它旨在执行逻辑功能,这些功能应该独立于渲染线程在每一帧中调用。这个函数不会阻塞主线程。
    2. The World Logic updateSyncThread() function is executed: all parallel logic functions that should be executed before update(). This function blocks the Main Thread until all calls are completed.World Logic updateSyncThread()函数被执行:所有应该在update()之前执行的并行逻辑函数。该函数会阻塞主线程,直到所有调用完成。
    3. The World Logic update() function is executed: node parameters are updated, transformations for non-physical nodes are set and so on.执行 World Logic update() 函数:更新节点参数,设置非物理节点的转换等。
    4. The state of nodes existing in the world is updated (mostly for visible nodes): skinned animation is played, particle systems spawn new particles, players are repositioned, and so on. Triggered world callbacks are added to a stack (they will be executed later).世界中现有节点的状态被更新(主要是可见节点):播放蒙皮动画,粒子系统产生新粒子,重新定位玩家,等等。触发的世界回调被添加到堆栈中(它们将被执行之后)。
    5. World Expressions are updated. Code in World Expressions can be written via UnigineEditor.World Expressions 已更新。 World Expressions 中的代码可以通过 UnigineEditor 编写。
    6. GUI is updated.图形用户界面已更新。
    7. The World Logic postUpdate() function is called.World Logic postUpdate() 函数被调用。
  14. The System Logic postUpdate() function is executed, if necessary (see details here). It can access the updated data on node states and correct the behavior accordingly in the same frame.如有必要,将执行 System Logic postUpdate() 函数(请参阅详细信息这里)。它可以访问节点状态的更新数据,并在同一帧中相应地纠正行为。
  15. The Editor Logic postUpdate() function is executed.Editor Logic postUpdate() 函数被执行。
  16. The postUpdate() function of all plugins is called.postUpdate()调用所有插件的函数。
  17. The world spatial tree is updated.世界空间树已更新。
  18. The file system is updated.文件系统已更新。

At the end of the update stage, physics and pathfinding start to be updated in their separate threads. Then they perform their tasks on all available threads in parallel to rendering.在更新阶段结束时,物理寻路开始在各自的线程中更新。然后他们在所有可用线程上与渲染并行执行任务。

注意
Nodes with computationally heavy bodies (like clothes and ropes) should not have one parent; otherwise, they will be updated in one thread.具有计算重实体的节点(如衣服和绳索)不应只有一个父节点;否则,它们将在一个线程中更新。

The total time of update stage is displayed by the Update counter in the Performance Profiler.update 阶段的总时间由 Update 计数器显示在性能分析器.

RenderingRendering#

As soon as the update stage is completed, UNIGINE can start rendering the world. In parallel, the pathfinding is performed in a separate thread. Depending on the physics update mode, parts of the physics calculations are performed in the main thread or in parallel to it. This approach enables to effectively balance the load between CPU and GPU, and thus allows for higher framerate in the UNIGINE-based application.一旦更新阶段完成,UNIGINE 就可以开始渲染世界。同时,寻路在单独的线程中执行。取决于物理更新模式,部分物理计算在主线程中执行或与其并行执行。这种方法能够有效地平衡 CPU 和 GPU 之间的负载,从而在基于 UNIGINE 的应用程序中实现更高的帧率。

Here is what happens during the render stage:这是渲染阶段发生的事情:

Render Physics Pathfinding
  1. The Editor Logic render() function is called.Editor Logic render() 函数被调用。
  2. The render() function of plugins is called, if they exist.调用插件render() 函数(如果存在)。
  3. UNIGINE renders the graphics scene (the world) and the sound scene, as they should be in the current frame. The graphics scene is sent to GPU, while the sound scene is sent to the sound card. As soon as the CPU finishes preparation of data and feeds rendering commands to the GPU, the GPU becomes busy with rendering the frame.

    The total time of rendering stage is displayed by the Render counter in the Performance Profiler. After that, the CPU is free, so we can load it with calculations we need.The total time of rendering stage is displayed by the Render counter in the Performance Profiler. After that, the CPU is free, so we can load it with calculations we need.

    The total time of rendering stage is displayed by the Render counter in the Performance Profiler. After that, the CPU is free, so we can load it with calculations we need.
    UNIGINE 渲染图形场景(世界)和声音场景,因为它们应该在当前帧中。图形场景被发送到GPU,而声音场景被发送到声卡。一旦 CPU 完成数据准备并将渲染命令提供给 GPU,GPU 就会忙于处理渲染框架。

    The total time of rendering stage is displayed by the Render counter in the Performance Profiler. After that, the CPU is free, so we can load it with calculations we need.渲染阶段的总时间由 Render计数器显示 性能分析器.之后,CPU 是空闲的,所以我们可以加载我们需要的计算。

  4. The gui() function of plugins (if any) is called.调用插件gui() 函数(如果有)。
  5. At last and atop of all, GUI is rendered, if required. And the total time of interface rendering is displayed by the Interface counter in the Performance Profiler.最后,最重要的是,如果需要,将呈现 GUI。并且界面渲染的总时间由 Interface 计数器显示在性能分析器.
  1. The physics module calls the plugin updatePhysics() function, if it exists.物理模块调用插件updatePhysics() 函数(如果存在)。
  2. The physics module calls the world logic updatePhysics() function. In the updatePhysics() function, you can modify physics.

    The updatePhysics() function is not called each frame. The physics module has its own fixed framerate, which does not depend on the rendering framerate. During each of such physics frames (or ticks), a number of calculation iterations are performed (updatePhysics() is called before each iteration).The updatePhysics() function is not called each frame. The physics module has its own fixed framerate, which does not depend on the rendering framerate. During each of such physics frames (or ticks), a number of calculation iterations are performed (updatePhysics() is called before each iteration).

    The updatePhysics() function is not called each frame. The physics module has its own fixed framerate, which does not depend on the rendering framerate. During each of such physics frames (or ticks), a number of calculation iterations are performed (updatePhysics() is called before each iteration).
    物理模块调用世界逻辑updatePhysics()功能。在里面updatePhysics()功能,你可以修改物理.

    The updatePhysics() function is not called each frame. The physics module has its own fixed framerate, which does not depend on the rendering framerate. During each of such physics frames (or ticks), a number of calculation iterations are performed (updatePhysics() is called before each iteration).updatePhysics()函数不是每帧调用一次。物理模块有它的 自己的固定帧率, 哪一个不依赖于渲染帧率.在每个这样的物理帧(或滴答)期间,一些计算迭代执行(在每次迭代之前调用 updatePhysics())。

  3. The physics module is updated: internal physics simulation starts. During this step, UNIGINE performs collision detection for all objects that have physical bodies and collision shapes.
    In the Performance Profiler, the total time of updatePhysics() together with physics simulation is displayed by the Physics counter.
    物理模块更新:内部物理模拟开始。在此步骤中,UNIGINE 对所有具有物理实体和碰撞形状的对象执行碰撞检测。
    性能分析器, updatePhysics() 和物理模拟的总时间由 Physics 计数器显示。
  • The pathfinding module is updated. In the thread performance profiler, the total time of pathfinding is displayed by the PathFind counter.寻路模块已更新。在里面线表现分析器,寻路的总时间由PathFind计数器显示。

SwapSwap#

The swap stage is the last one in the main loop. It includes the following:交换阶段是主循环中的最后一个阶段。它包括以下内容:

  1. If the video_grab console command is executed previously, on this stage, the taken screenshot is saved in folder where all application data is stored.如果之前执行了 video_grab 控制台命令,在此阶段,截取的屏幕截图将保存在所有申请资料被储存了。
  2. Synchronization of physics and pathfinding with the rendered world, i.e. waiting for all additional threads to finish their tasks. Results of the physical calculations are applied to the world. That is, on the previous step we have calculated how physical bodies with collision shapes have changed their position and orientation (due to our update-based logic or interaction). Now these transformations can be finally applied to nodes, i.e. rendered meshes.物理和寻路与渲染世界的同步,即等待所有附加线程完成它们的任务。物理计算的结果应用于世界。也就是说,在上一步中,我们已经计算了具有碰撞形状的物理物体如何改变它们的位置和方向(由于我们基于更新的逻辑或交互)。现在这些变换可以最终应用于节点,即渲染网格。

    注意
    As the synchronization of physics follows the rendering stage (in default Async Rendering physics mode), applied physical transformations will be visible on the screen only in the next frame. To calculate physics before the rendering enable the Before Rendering physics mode.由于物理同步跟随渲染阶段(默认为 Async Rendering 物理模式),应用的物理变换将仅在下一帧中在屏幕上可见。要在渲染之前计算物理,请启用 Before Rendering 物理模式。
  3. The World Logic swap() function is executed. It operates with the results of the updateAsyncThread() function.World Logic swap() 函数被执行。它使用 updateAsyncThread() 函数的结果进行操作。
  4. The plugin swap() function is called, if it exists.调用插件swap() 函数(如果存在)。
  5. Unloading of the world, if another world is going to be loaded in the next frame.卸载世界,如果下一帧要加载另一个世界。
  6. Deletion of all objects that are planned to be deleted.删除所有计划删除的对象。
  7. Values shown in the performance profiler are updated.性能分析器中显示的值已更新。

After the swap stage is completed, the application window initiates GPU buffers swapping as described here.交换阶段完成后,应用程序窗口将启动 GPU 缓冲区交换,如下所述这里.

最新更新: 2021-06-24
Build: ()