See Also: Engine
Before a Urho3D application can enter its main loop, the Engine subsystem object must be created and initialized by calling the UrhoEngine.Initialize method.
Main Loop Iteration
The main loop iteration (also called a frame) is driven by the Engine. In contrast it is the program's (for example Urho3DPlayer) responsibility to continuously loop this iteration by calling Engine.RunFrame. This function calls in turn the Time subsystem's Engine.BeginFrame and Engine.EndFrame functions, and sends various update events in between.
There are a number of events that are raised, these events can be monitored by calling one of the various SubscribeToXxx methods in the UrhoObject base class.
The event order is:
- Time.FrameStarted: signals the beginning of the new frame. Input and Network react to this to check for operating system window messages and arrived network packets.
- Engine.Update: application-wide logic update event. By default each update-enabled Scene reacts to this and triggers the scene update (more on this below).
- Engine.PostUpdate: application-wide logic post-update event. The UI subsystem updates its logic here.
- Engine.RenderUpdate: Renderer updates its viewports here to prepare for rendering, and the UI generates render commands necessary to render the user interface.
- PostRenderUpdate: by default nothing hooks to this. This can be used to implement logic that requires the rendering views to be up-to-date, for example to do accurate raycasts. Scenes may not be modified at this point; especially scene objects may not be deleted or crashes may occur.
- EndFrame: signals the end of the frame. Before this, rendering the frame and measuring the next frame's timestep will have occurred.
The update of each Scene causes further events to be sent:
- SceneUpdate: variable timestep scene update. This is a good place to implement any scene logic that does not need to happen at a fixed step.
- SceneSubsystemUpdate: update scene-wide subsystems. Currently only the PhysicsWorld component listens to this, which causes it to step the physics simulation and send the following two events for each simulation step:
- PhysicsPreStep: called before the simulation iteration. Happens at a fixed rate (the physics FPS). If fixed timestep logic updates are needed, this is a good event to listen to.
- PhysicsPostStep: called after the simulation iteration. Happens at the same rate as PhysicsPreStep.
- SmoothingUpdate: update SmoothedTransform components in network client scenes.
- ScenePostUpdate: variable timestep scene post-update. ParticleEmitter and AnimationController update themselves as a response to this event.
Variable timestep logic updates are preferable to fixed timestep, because they are only executed once per frame. In contrast, if the rendering framerate is low, several physics simulation steps will be performed on each frame to keep up the apparent passage of time, and if this also causes a lot of logic code to be executed for each step, the program may bog down further if the CPU can not handle the load. Note that the Engine’s minimum FPS, by default 10, sets a hard cap for the timestep to prevent spiraling down to a complete halt; if exceeded, animation and physics will instead appear to slow down.
Main Loop and the Application Activation State
The application window's state (has input focus, minimized or not) can be queried from the Input subsystem. It can also effect the main loop in the following ways:
- Rendering is always skipped when the window is minimized.
- To avoid spinning the CPU and GPU unnecessarily, it is possible to define a smaller maximum FPS when no input focus. See Engine.MaxInactiveFps.
- It is also possible to automatically pause update events and audio when the window is minimized. Use Engine.PauseMinimized to control this behaviour. By default it is not enabled on desktop, and enabled on mobile devices (Android and iOS.) For singleplayer games this is recommended to avoid unwanted progression while away from the program. However in a multiplayer game this should not be used, as the missing scene updates would likely desync the client with the server.
- On mobile devices the window becoming minimized can mean that it will never become maximized again, in case the OS decides it needs to free memory and kills your program. Therefore you should listen for the InputFocus event from the Input subsystem and immediately save your program state as applicable if the program loses input focus or is minimized.
- On mobile devices it is also unsafe to access or create any graphics resources while the window is minimized (as the graphics context may be destroyed during this time); doing so can crash the program. It is recommended to leave the pause-minimized feature on to ensure you do not have to check for this in your update code.
Note that on iOS calling Engine.Exit is a no-op as there is no officially sanctioned way to manually exit your program. On Android it will cause the activity to manually exit.
Assembly: Urho (in Urho.dll)
Assembly Versions: 184.108.40.206
The members of Urho.Engine are listed below.
See Also: UrhoObject
|AutoExit||Boolean. Return whether to exit automatically on exit request. Or Set whether to exit automatically on exit request (window close button.)|
|[read-only]||Exiting||Boolean. Return whether exit has been requested.|
|[read-only]||Headless||Boolean. Return whether the engine has been created in headless mode.|
|[read-only]||Initialized||Boolean. Return whether engine has been initialized.|
|MaxFps||Int32. Return the maximum frames per second. Or Set maximum frames per second. The engine will sleep if FPS is higher than this.|
|MaxInactiveFps||Int32. Return the maximum frames per second when the application does not have input focus. Or Set maximum frames per second when the application does not have input focus.|
|MinFps||Int32. Return the minimum frames per second. Or Set minimum frames per second. If FPS goes lower than this, time will appear to slow down.|
|NextTimeStep||Single. Get timestep of the next frame. Updated by ApplyFrameLimit(). Or Override timestep of the next frame. Should be called in between RunFrame() calls.|
|PauseMinimized||Boolean. Return whether to pause update events and audio when minimized. Or Set whether to pause update events and audio when minimized.|
|TimeStepSmoothing||Int32. Return how many frames to average for timestep smoothing. Or Set how many frames to average for timestep smoothing. Default is 2. 1 disables smoothing.|
|Type||StringHash. Urho's type system type.|
|TypeName||String. Urho's low-level type name.|
|TypeNameStatic||String. Urho's low-level type name, accessible as a static method.|
|TypeStatic||StringHash. Urho's low-level type, accessible as a static method.|
Get the timestep for the next frame and sleep for frame limiting if necessary.
Create the console and return it. May return null if engine configuration does not allow creation (headless mode.)
Create the debug hud.
Dump information of all memory allocations to the log. Supported in MSVC debug mode only.
Dump profiling information to the log.
Dump information of all resources to the log.
Render after frame update.
Run one frame.
Subscribes to the PostRenderUpdate event raised by the Engine.
Subscribes to the PostUpdate event raised by the Engine.
Subscribes to the RenderUpdate event raised by the Engine.
Sends the frame update events.
|PostRenderUpdate||Invoked after the RenderUpdate event has been raised. This can be used to implement logic that requires the rendering views to be up-to-date, for example to do accurate raycasts.|
|PostUpdate||Event raised after the Engine.Update event is from the Engine.UpdateFrame method.|
|RenderUpdate||Event raised after Engine.PostUpdate event in preparation for rendering.|
|Update||Application-wide logic update event, the first called from the Engine.UpdateFrame method.|