1
$\begingroup$

I am using python script to move an object (a ball) in a room, and it should be in the room, not going out. I have set the rigid body, when play it is ok, it can stop when hit the wall. but when controlled by script, it goes through the wall.

    ball = bpy.data.objects['ball']
    ball.select_set(True)
    bpy.ops.rigidbody.object_add()
    bpy.context.object.rigid_body.mass = 1
    ball.select_set(False)

    ball.location[0] = ball.location[0]+0.1  #this is in timer, repeat

how can I make it stop automatically when hit the wall? can I running python code control its movements when in playing?

$\endgroup$
5
  • $\begingroup$ 3d collision detection is a complex problem. No easy way to do in low level code. $\endgroup$
    – X Y
    Commented Apr 21, 2022 at 11:43
  • $\begingroup$ sure, I do not want to do 3d collision myself, blender already does it well. the question is, how to let blender do it. as we know, in play mode, it does, but in play mode, the python code seems not work. $\endgroup$
    – Franson Wu
    Commented Apr 21, 2022 at 12:07
  • $\begingroup$ Unfortunately, Blender unlike the game engine. In blender, If you control the position manually, you need determine when the Rigid Body is Active. $\endgroup$
    – X Y
    Commented Apr 21, 2022 at 14:35
  • $\begingroup$ You may add force to the object instead control the location. $\endgroup$
    – X Y
    Commented Apr 21, 2022 at 14:56
  • $\begingroup$ good suggestion, how to add force by code? $\endgroup$
    – Franson Wu
    Commented Apr 21, 2022 at 22:53

1 Answer 1

1
$\begingroup$

Example scene for physics collision

enter image description here

Run the script to get the scene.

import bpy

# select and delete all object
if bpy.context.object:
    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.select_all(action = "SELECT")
    bpy.ops.object.delete(use_global=True, confirm=False)

unit_settings = bpy.context.scene.unit_settings
unit_settings.system            = 'METRIC'
unit_settings.scale_length      = 1
unit_settings.length_unit       = 'METERS'
unit_settings.mass_unit         = 'KILOGRAMS'
unit_settings.time_unit         = 'SECONDS'
bpy.context.scene.use_gravity   = True
bpy.context.scene.gravity[0]    = 0
bpy.context.scene.gravity[1]    = 0
bpy.context.scene.gravity[2]    = -9.81


bpy.ops.mesh.primitive_plane_add(size=5, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
bpy.context.object.name = "floor"
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'PASSIVE'
bpy.context.object.rigid_body.collision_shape = 'BOX'


bpy.ops.mesh.primitive_cube_add(size=5, enter_editmode=False, align='WORLD', location=(5, 0, 0), scale=(1, 1, 1))
bpy.context.object.name = "wall"
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'PASSIVE'
bpy.context.object.rigid_body.collision_shape = 'BOX'


bpy.ops.mesh.primitive_cube_add(size=0.2, enter_editmode=False, align='WORLD', location=(0, 0, 0.101), scale=(1, 1, 1))
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'ACTIVE'
bpy.context.object.rigid_body.collision_shape = 'BOX'
bpy.ops.rigidbody.mass_calculate(material='Iron', density=7874)


bpy.ops.object.empty_add(type='CIRCLE', align='WORLD', location=(-0.41, 0, 0), rotation=(0, 1.5708, 0), scale=(1, 1, 1))
bpy.context.object.name = "force"
bpy.ops.object.forcefield_toggle()
bpy.context.object.field.type = 'WIND'
bpy.context.object.field.strength = 100000
$\endgroup$
3
  • $\begingroup$ cool, so the basic idea is to add some force? code control box move will not make blender "know" collision? can we add some force to an object (so we can add different force to different objects)? rather than a wind field? $\endgroup$
    – Franson Wu
    Commented Apr 22, 2022 at 6:49
  • $\begingroup$ If you know when the cube hit the wall, at that time, you can turn the Rigid Body Setting (Animated off) of the cube. That is bpy.context.object.rigid_body.kinematic = False. Then the cube will control by Rigid Body. $\endgroup$
    – X Y
    Commented Apr 22, 2022 at 6:57
  • $\begingroup$ You also can use other Force type: bpy.context.object.field.type = 'FORCE'. I tested it can work. But you need change the force Power and direction. $\endgroup$
    – X Y
    Commented Apr 22, 2022 at 7:03

You must log in to answer this question.

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