I am trying to use a script to add some rules to the boid brain of a particle system and the operators on website here, https://docs.blender.org/api/current/bpy.ops.boid.html, don't seem to be doing anything. Does anyone know a way to do add various rules to a boid brain system via script?
I am using the following code to add the particle system to an existing selected object in the scene. Everything works up until the last line where I try to add the Boid rule. That line doesn't seem to do anything to the particle system.
#adding particle system with custom particle system settings for smoke explosion below
obj = bpy.context.active_object
if len(obj.particle_systems) == 0:
obj.modifiers.new("part", type='PARTICLE_SYSTEM')
part = obj.particle_systems[0]
settings = part.settings
settings.name = 'Bug System'
settings.count = 1000
settings.frame_start = 1
settings.frame_end = (250)
settings.lifetime = 500
settings.lifetime_random = 0
settings.emit_from = 'FACE'
settings.physics_type = 'BOIDS'
bpy.context.object.show_instancer_for_render = False
settings.show_unborn = True
settings.use_dead = True
settings.render_type = 'COLLECTION'
settings.particle_size = 0.05
settings.size_random = 0.3
bpy.data.particles["Bug System"].instance_collection = bpy.data.collections[context.scene.spyderfy_tool.my_stringbugsystem]
settings.show_unborn = False
settings.use_dead = False
settings.jitter_factor = 0
settings.object_factor = 1
settings.effector_weights.turbulence = 0
#adding boid brain rules in correct order
bpy.ops.boid.rule_add(type='FLOCK')
return{'FINISHED'}
UPDATE EDIT and Follow Up Question: lemons answer worked for adding the boid rules. The last issue I am having now is adding a goal target via the script as well? Do I need to override something here as well. I've attached the code below. Only the last line is not working. For clarification the "Bug System Goal" object is an Empty that has already been added to the scene.
#adding BOID BRAIN RULES in correct order(help from stackexchange users lemon and batfinger)
# Copy the current context
context_override = bpy.context.copy()
# Override the wanted property
context_override["particle_settings"] = settings
# Call the operators
bpy.ops.boid.rule_add(context_override, type='FLOCK')
bpy.ops.boid.rule_add(context_override, type='GOAL')
#conditional to follow bug system goal if checkbox is selected by user
if (context.scene.spyderfy_tool.my_goalobject == True):
bpy.data.particles["Bug System"].rules["Goal"].object = bpy.data.objects["Bug System Goal"]
SECOND UPDATE and troubleshooting: Hi Lemon thanks for the response. Using the code you mentioned to add a goal object in my script I get the following error saying that the particle system object has no attribute "settings".
Tried to fill in the gaps in my code that would be specific to my script. I must be overlooking something? The goal assignment code where the error occurs is written last under the conditional statement.
#Now we adjust our newly appended particle system with custom particle system settings for the boids system below(from article on stackexchange)
obj = bpy.context.active_object
if len(obj.particle_systems) == 0:
obj.modifiers.new("part", type='PARTICLE_SYSTEM')
part = obj.particle_systems[0]
settings = part.settings
settings.name = 'Bug System'
settings.count = 1000
settings.frame_start = 1
settings.frame_end = (250)
settings.lifetime = 500
settings.lifetime_random = 0
settings.emit_from = 'FACE'
settings.physics_type = 'BOIDS'
bpy.context.object.show_instancer_for_render = False
settings.show_unborn = True
settings.use_dead = True
settings.render_type = 'COLLECTION'
settings.particle_size = 0.05
settings.size_random = 0.3
bpy.data.particles["Bug System"].instance_collection = bpy.data.collections[context.scene.spyderfy_tool.my_stringbugsystem]
settings.show_unborn = False
settings.use_dead = False
settings.jitter_factor = 0
settings.object_factor = 1
settings.effector_weights.turbulence = 0
#adding BOID BRAIN RULES in correct order(help from stack exchange users lemon and batfinger)
# Copy the current context
context_override = bpy.context.copy()
# Override the wanted property
context_override["particle_settings"] = settings
# Call the operators
bpy.ops.boid.rule_del(context_override)
bpy.ops.boid.rule_del(context_override)
bpy.ops.boid.rule_add(context_override, type='GOAL')
bpy.ops.boid.rule_add(context_override, type='SEPARATE')
bpy.ops.boid.rule_add(context_override, type='FLOCK')
if (context.scene.spyderfy_tool.my_goalobject == True):
# Get the particle object
obj = bpy.context.object
# Get the goal
empty = bpy.data.objects["Bug System Goal"]
particle_system = bpy.data.particles["Bug System"]
# You can also:
#particle_system = obj.particle_systems["Bug System"]
# Get the boid part
boids_part = particle_system.settings.boids #WHERE THE ERROR OCCURS
# Get the state (it seems there is one boid state)
state = boids_part.states[0]
# Get the 'Goal' rule from its index
# You should know its index as you've set it up earlier
rule = state.rules[1] # '1' is an example, so
# Or:
#rule = state.rules['Goal'] # But may be the same name several times
# Assign the empty as goal
rule.object = empty
Not sure where I am going wrong here.