5
$\begingroup$

By BGE framerate I mean the rate at which True pulse is fired (and thus attached Python controller script is executed) and by Action framerate I mean the rate at which the value returned by KX_GameObject.getActionFrame() is changing. (I've heard the term Logic framerate in the context of BGE, but I'm not sure if it is the same thing as BGE framerate I'm talking about :-/ Sorry!)

Here is a small snippet which I used for testing (which should clarify what I mean by BGE frame and Action frame):

import bge

BGE_frame = 0

def main(cont):
    global BGE_frame

    arm = cont.owner
    if not arm.isPlayingAction():
        arm.playAction("run", 0, 45, play_mode=bge.logic.KX_ACTION_MODE_PLAY)

    print(BGE_frame)
    print(arm.getActionFrame())

    BGE_frame += 1

Using the above script for Python controller attached to an Always True sensor gives following result (the n-th BGE frame and corresponding Action frame):

http://pastebin.com/NK2RrVkR

As we can see, there is a significant difference in both frame-rates (e.g. the 11th BGE frame corresponds to the 4th Action frame and 16th BGE frame corresponds to the 6th Action frame -- so roughly 5 BGE frames corresponds to 2 Action frames).

Assuming that the action starts playing when BGE frame is 0, in what way can we compute the Action frame from the BGE frame and vice-versa? More precisely, I'm looking something like:

import bge

BGE_frame = 0

def main(cont):
    global BGE_frame

    print(BGE_frame)
    print(BGE_frame_to_Animation_frame(BGE_frame)) # TODO: Outputs same result as above

    BGE_frame += 1

If it is needed here's the .blend file: http://wikisend.com/download/114182/framerate.blend

Thanks!

$\endgroup$

1 Answer 1

2
$\begingroup$

I think I solved it as follows:

import bpy, bge

BGE_frame = 0

scene = bge.logic.getCurrentScene()
bpy_scene = bpy.data.scenes[scene.name]

BPY_FPS = bpy_scene.render.fps / bpy_scene.render.fps_base
BGE_FPS = bge.logic.getLogicTicRate()

BPY_BGE_RATIO = BPY_FPS / BGE_FPS

def BGE_frame_to_Animation_frame(BGE_frame):
    return BGE_frame * BPY_BGE_RATIO

def main(cont):
    global BGE_frame

    arm = cont.owner

    print(BGE_frame)
    print(arm.getActionFrame()) # Kept for comparison
    print(BGE_frame_to_Animation_frame(BGE_frame)) # Outputs approx. same result as above

    if not arm.isPlayingAction():
        arm.playAction("run", 0, 45, play_mode=bge.logic.KX_ACTION_MODE_PLAY)
        BGE_frame = 0
    else:
        BGE_frame += 1        

    print("\n")

I'm not sure of it is a good practice to access blender data from BGE, but it works :-) Comments/suggestions are welcome! Thanks.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .