Blenderでオブジェクトをバラバラに動かす。
#blender #tips #文字PV
blender上で複数のオブジェクトを一つのパラメーターを元にバラバラに回転、移動させるためのコード。Python慣れてないのでかなり手探り&ChatGPTのお手伝い入りです。
イラレで作った文字組をOBJで書き出して、それぞれの文字を動かそうと思って作った。
使い方
1. Controllerという名前のエンプティを作って、動かしたいオブジェクトといっしょに選択。
2. 実行。
3. エンプティに4つスライドが付きます。XYZ回転と、Y軸(手前-奥)移動。全部ランダム関数がかかっているのと、回転は奇数番目が反転しているので複雑に動いてくれると思います。
driver_x.expression = f"1.5708 + rotation_control_x * strength_x * {sign}"というところで90度(1.5708)足してるので、ここは多分調節すべきです。IllustratorからOBJを出したら90度ズレてた名残です。
追記:
すみません1行ミスってました。なんかうまくいかなかったので動作確認用のifも最後に追加してます。失敗したら「無理でした」って言ってきます。もし何も言わなかったらコードのせいじゃないです。
bpy.context.scene.objects.get("Controller") 、シーン増やすと同じ名前ではなくて"Controller.001"とかになるので適宜変えてください。57行目です。
動きが反映されない場合、動かすオブジェクトの位置を少しずらすなどして更新してください。X軸少しスライドしてCtrlZするだけでも更新されると思います。
code:スクリプト
import bpy
import random
def setup_rotation_and_movement(controller_obj, target_objs):
for axis in "x", "y", "z":
prop_name = f"rotation_control_{axis}"
if prop_name not in controller_obj:
controller_objprop_name = 0.0
if "movement_control_y" not in controller_obj:
controller_obj"movement_control_y" = 0.0
for i, obj in enumerate(target_objs):
obj"strength_x" = random.uniform(0.5, 1.5)
obj"strength_y" = random.uniform(0.5, 1.5)
obj"strength_z" = random.uniform(0.5, 1.5)
obj"move_strength_y" = random.uniform(0.5, 1.5)
sign = -1 if i % 2 == 1 else 1
driver_x = obj.driver_add("rotation_euler", 0).driver
driver_x.type = 'SCRIPTED'
driver_x.expression = f"1.5708 + rotation_control_x * strength_x * {sign}"
driver_y = obj.driver_add("rotation_euler", 1).driver
driver_y.type = 'SCRIPTED'
driver_y.expression = f"rotation_control_y * strength_y * {sign}"
driver_z = obj.driver_add("rotation_euler", 2).driver
driver_z.type = 'SCRIPTED'
driver_z.expression = f"rotation_control_z * strength_z * {sign}"
driver_move_y = obj.driver_add("location", 1).driver
driver_move_y.type = 'SCRIPTED'
driver_move_y.expression = "movement_control_y * move_strength_y"
for driver, axis in zip(driver_x, driver_y, driver_z, "x", "y", "z"):
var_rotation_control = driver.variables.new()
var_rotation_control.name = f"rotation_control_{axis}"
var_rotation_control.targets0.id = controller_obj
var_rotation_control.targets0.data_path = f'"rotation_control_{axis}"'
var_strength = driver.variables.new()
var_strength.name = f"strength_{axis}"
var_strength.targets0.id = obj
var_strength.targets0.data_path = f'"strength_{axis}"'
var_move_control = driver_move_y.variables.new()
var_move_control.name = "movement_control_y"
var_move_control.targets0.id = controller_obj
var_move_control.targets0.data_path = '"movement_control_y"'
var_move_strength = driver_move_y.variables.new()
var_move_strength.name = "move_strength_y"
var_move_strength.targets0.id = obj
var_move_strength.targets0.data_path = '"move_strength_y"'
controller_obj = bpy.context.scene.objects.get("Controller")
target_objs = obj for obj in bpy.context.selected_objects if obj != controller_obj
if controller_obj and target_objs:
setup_rotation_and_movement(controller_obj, target_objs)
print("できました")
else:
print("無理でした")