![enter image description here](https://cdn.statically.io/img/i.sstatic.net/EMvcd.gif)
You can run the script to get scene
import bpy
from mathutils import Vector
# 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.context.scene.render.fps = 60
bpy.context.scene.frame_set(1)
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.context.object.rigid_body.friction = 0.02
bpy.context.object.rigid_body.restitution = 0.9
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_0"
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'PASSIVE'
bpy.context.object.rigid_body.collision_shape = 'BOX'
bpy.context.object.rigid_body.friction = 0.02
bpy.context.object.rigid_body.restitution = 0.9
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_1"
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'PASSIVE'
bpy.context.object.rigid_body.collision_shape = 'BOX'
bpy.context.object.rigid_body.friction = 0.02
bpy.context.object.rigid_body.restitution = 0.9
bpy.ops.mesh.primitive_cube_add(size=5, enter_editmode=False, align='WORLD', location=(0, 5, 0), scale=(1, 1, 1))
bpy.context.object.name = "wall_2"
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'PASSIVE'
bpy.context.object.rigid_body.collision_shape = 'BOX'
bpy.context.object.rigid_body.friction = 0.02
bpy.context.object.rigid_body.restitution = 0.9
x = -1
balls = []
for r in range(10):
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.1, enter_editmode=False, align='WORLD', location=(x, 0, 0.101), scale=(1, 1, 1))
bpy.context.object.name = f"ball_{r}"
bpy.ops.object.shade_smooth()
bpy.ops.rigidbody.object_add()
oj = bpy.context.object
balls.append(oj)
oj.rigid_body.type = 'ACTIVE'
oj.rigid_body.kinematic = True
oj.rigid_body.collision_shape = 'MESH'
bpy.context.object.rigid_body.collision_margin = 0.001
bpy.context.object.rigid_body.friction = 0.02
bpy.context.object.rigid_body.restitution = 0.9
bpy.ops.rigidbody.mass_calculate(material='Iron', density=7874)
oj.keyframe_insert(data_path="location", frame=1)
oj.keyframe_insert(data_path="rigid_body.kinematic", frame=1)
oj["control_by_rigid_body"] = False
x += 0.2
def inside_room(x, y):
if -2.3 < x < 2.3:
if -2.5 < y < 2.3: return True
return False
speed = 0.05
v = [
Vector((-1.0, 0.0)).normalized() * speed,
Vector((-0.9, 0.2)).normalized() * speed,
Vector((-0.8, 0.4)).normalized() * speed,
Vector((-0.6, 0.6)).normalized() * speed,
Vector((-0.4, 0.7)).normalized() * speed,
Vector((-0.1, 1.0)).normalized() * speed,
Vector((0.1, 1.0)).normalized() * speed,
Vector((0.3, 0.8)).normalized() * speed,
Vector((0.5, 0.5)).normalized() * speed,
Vector((1.0, 0.0)).normalized() * speed,
]
for r in range(2, 121):
# bpy.context.scene.frame_set(r)
for i, b in enumerate(balls):
if b["control_by_rigid_body"] == False:
b.location[0] += v[i][0]
b.location[1] += v[i][1]
if inside_room(b.location[0], b.location[1]):
b.keyframe_insert(data_path="location", frame=r)
else:
b.rigid_body.kinematic = False
b.keyframe_insert(data_path="rigid_body.kinematic", frame=r)
b["control_by_rigid_body"] = True
To do this, first you need to know when to hit the wall. In my case, if location[0]
of the ball > 2.4 will hit the right side (depends on the wall position).
if near the wall, keyframe the "rigid_body.kinematic"
. Then control by the Rigid Body.
![enter image description here](https://cdn.statically.io/img/i.sstatic.net/0HZMM.png)