Skip to content

Game Loop

The previous chapter described the custom_ui. This chapter will lay out the game loop. We start with the template code supplied by OmniStep:

import bpy
from mathutils import Vector, Quaternion, Matrix

class CustomUserScript(UserScriptBase):
    def custom_ui(self):
        self.add_property('example_var', 'BOOLEAN')

    def start(self, context, core):
        pass

    def update(self, context, core):
        if core.input.state['action1'].phase == InputItem.DOWN:
            core.overlay.message(str(self.example_var))

    def late_update(self, context, core):
        pass

    def done(self, context, canceled, core):
        pass

Start

The start method is called once when the OmniStep operator begins running. This is where you can initialize variables, call methods, and define private variables. The core class passed to this method is described in the next chapter

    def start(self, context, core):
        self.my_local_var = 123.4

Update

The update method is called every frame. This method corresponds to the viewport update, not the Blender timeline. In this template, when the user presses the action1 input ( Left Mouse by default), it displays the state of the variable example_var the bottom of the viewport.

    def update(self, context, core):
        if core.input.state['action1'].phase == InputItem.DOWN:
            core.overlay.message(str(self.example_var))

Late Update

There is an additional optional method called late_update, which is called after the player and the animation data is updated. This can be useful for correcting elements that 'lag' behind the player for a single frame.

    def late_update(self, context, core):
        # do things

Here is an excerpt of the OmniStep update loop showing the positions of the update and late_update functions for both UserScripts and Modules:

    if event.type == "TIMER":
        self.core.scene.update()

        self.core.input.update(event, False)

        self.core.modules.update()
        self.core.userscript.update()

        self.core.player.update()

        self.core.animation.update()
        self.core.animation.update_timeline()

        self.core.modules.late_update()
        self.core.userscript.late_update()

        context.area.tag_redraw()
        context.region.tag_redraw()

Done

The done method is called once when you end or abort the operator. The done method has an additional parameter: canceled, a boolean that indicates whether the user pressed Esc or Enter (or the 'Alternate Done' Key).

def done(self, context, canceled, core):
    if canceled:
        # revert changes
    else:
        # apply changes