[BPY tip] Pre-game and post-game callbacks

Hi everyone,

I thought I’d mention this, because it’s a relatively recent addition following the Hive patches submitted by Sjoerd de Vries.

The bpy API now provides handlers for pre-game and post-game execution in the embedded player (since 2.6 something).

These are very useful if you are writing an addon or a helper script which requires data that doesn’t exist in the Blender Game Engine, or for pre-computing complex problems. You should use these in combination with the save and load callbacks to ensure that this works for the external player to.

One example is: Writing a callback which reads all Curve objects, stores the bezier information to a file, then reads this in the Blender Game Engine and uses drawLine to draw the bezier.

Check out bpy.app.handlers on the documentation website.

I’ve been using save_pre for a while now. :wink:

Does this handler works on standalone player?

Fantastic, good to know someone’s using the api :wink:

Ucupumar, as I said, it’s only for the internal player, as the standalone player is launched specifically for that purpose. Simply use the save and load callbacks instead of game callbacks to ensure that you save the relevant information to the blend file.

by change is possible do this:when press P -> find all mesh , if has a subsurf, applymodifier ,and add the changes somewherewhen esc -> restore all models changed restoring the modifier.note that you can do this manually , pressing CTRL+Z (UNDO) after the game is ended but is obviously not handly.is possible make a script for this?

You can, but it would be better to do this manually.

If you still wanted to do this, then it would be better to create copies of the objects, and save their names in a text file. When you save the blend file or start the game, copy any objects with incompatible modifiers, and apply the modifiers on the original objects. Then on file loading / game exit, delete the original and rename the copied object.

also this:maybe some workaround to solve the annoyng bug of children dynamics?

One example is: Writing a callback which reads all Curve objects, stores the bezier information to a file, then reads this in the Blender Game Engine and uses drawLine to draw the bezier.

The thing about beziers sounds great, I want to get some data from curves for the visual curve of an arrow in flight, or for a spiraling, zigzagging magic missile so I can use it for effects in game.

Check out the magic missile effect at 3:22

I think I can work with the data, scaling it and rotating the points so the missile will go to the target, but I don’t know how to get the info from the bezier curve using bpy. I haven’t worked with the bpy API much (I did years ago, but can’t remember anything about it).

I was going to use data from mouse position and then draw the curves freehand, but using bezier curve data would give a much better result.

Could you point me towards the functions I’d need?

I can’t share any code with you, as I’ve written it whilst employed with another company.

I can share my development process, as the information is in the public domain.

In the bpy API, Curve objects all share similar attributes. Bezier curves have splines stored on object.data.splines.
Each spline object has “bezier points” stored on the attribute bezier_points. Each point represents an origin, and two handle locations.

A bezier spline (bspline) is a series of bezier curves, each following the other. Hence for (N + 1) bezier points, there are N bezier curves.
A bezier curve is quite simple to define, and you can sample it either using matrices or traditional algebra. The matrix form was significantly faster, I found, though mathutils requires some care in how you construct the matrices. You can save the result of the last two matrix multiplications and then you’ve only to perform a single Vector * Matrix operation for each sample point.

Matrix sampling (first section)

You can also do this in a different manner:

There’s already a bezier function in mathutils.

bezier = mathutils.geometry.interpolate_bezier(knot1Vect, handle1Vect, handle2Vect, knot2Vect, resolution)

for i in range(1,resolution): #Visualization
    bge.render.drawLine(bezier[i-1], bezier[i], colorVect)

Edit: Oh I didn’t notice that the point was in getting bezier data from curve objects.

:slight_smile: Honestly I don’t really care how I get the data, I just want to be able to get curved lines for which I can manipulate the start end and mid points. My game doesn’t really use any physics, so approximate data is fine.

Once I have a collection of points I can use transformation, scale and rotation matrices to put the points where they are needed and then objects can be made to follow the points rather easily.

The mathutils option sounds interesting, I’ll try it out.