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$
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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.