How to add a flock of birds (boids) in the GE - stuck in a workaround using a script

For an art project we’ve been working on, I’d still like to add a flock of birds. We have yet to accomplish this.


This is a Cycles render.

Basically it’s a low poly breathing landscape where as a user (player) you can make it breathe deeper (input now is either a joystick or keyboard, later we’ll use an Arduino to make the input real breathing using a mic or other sensor).

Few months ago I posted a thread seeking help on a similar issue (the dispersion of the trees, while keeping their animation), yet I solved it differently by simply converting particles to objects (meshes) then joining the meshes with the landscape.

http://www.blenderartists.org/forum/showthread.php?356770-Convert-animated-particles-to-animated-meshes-for-use-in-Blender-Game-engine

While the boids system, available for regular animations, seems perfect, I’m unable to implement it to the Game Engine.

I couldn’t find a way to convert animated particles (duplicated objects, or rather groups in my case) to regular animated meshes until I found the script below.

While a true boids system would be more convenient - as there could even be interaction with the environment - just an animated flock flying around at a safe distance without interacting would be just as fine. Hence I was glad to find this script that will convert a particle system to animated meshes.

import bpy
# Set these to False if you don't want to key that property.
KEYFRAME_LOCATION = True
KEYFRAME_ROTATION = True
KEYFRAME_SCALE = True
KEYFRAME_VISIBILITY = True  # Viewport and render visibility.

def create_objects_for_particles(ps, obj):
    # Duplicate the given object for every particle and return the duplicates.
    # Use instances instead of full copies.
    obj_list = []
    mesh = obj.data
    for i, _ in enumerate(ps.particles):
        dupli = bpy.data.objects.new(
                    name="particle.{:03d}".format(i),
                    object_data=mesh)
        bpy.context.scene.objects.link(dupli)
        obj_list.append(dupli)
    return obj_list

def match_and_keyframe_objects(ps, obj_list, start_frame, end_frame):
    # Match and keyframe the objects to the particles for every frame in the
    # given range.
    for frame in range(start_frame, end_frame + 1):
        bpy.context.scene.frame_set(frame)
        for p, obj in zip(ps.particles, obj_list):
            match_object_to_particle(p, obj)
            keyframe_obj(obj)

def match_object_to_particle(p, obj):
    # Match the location, rotation, scale and visibility of the object to
    # the particle.
    loc = p.location
    rot = p.rotation
    size = p.size
    if p.alive_state == 'ALIVE':
        vis = True
    else:
        vis = False
    obj.location = loc
    # Set rotation mode to quaternion to match particle rotation.
    obj.rotation_mode = 'QUATERNION'
    obj.rotation_quaternion = rot
    obj.scale = (size, size, size)
    obj.hide = not(vis)
    obj.hide_render = not(vis)

def keyframe_obj(obj):
    # Keyframe location, rotation, scale and visibility if specified.
    if KEYFRAME_LOCATION:
        obj.keyframe_insert("location")
    if KEYFRAME_ROTATION:
        obj.keyframe_insert("rotation_quaternion")
    if KEYFRAME_SCALE:
        obj.keyframe_insert("scale")
    if KEYFRAME_VISIBILITY:
        obj.keyframe_insert("hide")
        obj.keyframe_insert("hide_render")

def main():
    # Assume only 2 objects are selected.
    # The active object should be the one with the particle system.
    ps_obj = bpy.context.object
    obj = [obj for obj in bpy.context.selected_objects if obj != ps_obj][0]
    ps = ps_obj.particle_systems[0]  # Assume only 1 particle system is present.
    start_frame = bpy.context.scene.frame_start
    end_frame = bpy.context.scene.frame_end
    obj_list = create_objects_for_particles(ps, obj)
    match_and_keyframe_objects(ps, obj_list, start_frame, end_frame)

if __name__ == '__main__':     main()

When applying this script to my birds, they stop ‘living’, they lose their wing movement. Because I’m using a group of three birds animated with an armature.

Next problem is also that I’d have to assign each mesh an action Actuator. Going through all boids separately seems a tedious job, almost undoable; so I’m looking for a way to automatically add the animation to the game engine. (just friggin’ add the boids to the game engine, aargh …)

So either I’m looking for ways to enhance this script or completely new ways of thinking. I also thought of using an animated texture (video). I also tried to create a flock using the seek actuator, but that really looked bad.

Want clarification or the file we’re working on? More than glad to share …

well, you need at least a tag in each armature,

bird or something


import bge
scene = bge.logic.getCurrentScene()
for objects in scene.objects:
    if 'Bird' in objects:
        objects.playAction(check the api)

It might be better to do the simulation live in the bge rather than baking it.

Now if only I could, I would … I don’t think there is a quick solution to implement Blenders particle boids to the game engine. Maybe there is a script out there that I have yet to stumble upon.

I’ll try and dig into the coding to add the suggestion by @BluePrintRandom
If I have any success I’ll update - but I do not have high hopes on succeeding as I have little python experience.

Python is no magic. It will not in a mysterious way suddenly make possible what you wish.

The BGE does not support Blender’s particles. So you can’t use them.

But, you do not need that anyway. Have a look at your requirement: a flock of birds.

Creating a flock of birds
You do not need particles to create birds. Particles are just a helpers. The BGE allows you to create a copy of a bird (see add object). You can do that in a static way via logic brick configuration or in a dynamic way via Python (yes, you need some python skills).

This way you get a lot of birds.

Bird behavior
The next feature is to describe and perform the behavior of each single bird. A typical way is that each bird brings it’s own behavior with it. As each bird is the copy of a single one … this is no big deal.

An alternative would be to “remote control” the birds. This means you have one separate object that acts as behavior for all birds. The birds are “just” data that gets processed. This benefits from the fact that the birds share the same behavior.

[This does not mean they create the same result. The behavior can depend on local status (e.g. position, hunger, speed)]

The question left is: What do you want to birds to do when?

Thanks for your input, much appreciated. I’m adding my comments as I try several things, I understand that much study on my part is needed if I wish to accomplish this. I’m willing to learn more as I go about and would appreciate more of your insights.

As I am no Python expert, to me a lot is magical :wink:

That’s why I’m looking for a workaround, recording the animation did seem like a good idea.

My attempts at doing this in the logic editor have not been successful; I can add an object when using e.g. a keyboard input; but that’s about it.
I have some experience in using the logic editor, but don’t fully grasp how you can connect or relate the different pieces. e.g. After adding a bird, make it move with a flocking behavior, and then adding several other birds.

Are there in the logic editor other things besides ‘seek’ and ‘flee’ that I could use to create such behavior?

Once the game has started at least one flock should keep flying about in the scene, probably best following a ‘prey’ that flies in a loop. To make it even better the birds should avoid flying into or through other objects.

Not that there is much accomplished besides making one bird follow a target using the Steering, Seek actuator; but none the less, I’m putting the blend file here as a reference.

birds_flock_game.blend (3.21 MB)