もくじ
基本
ドライバー・アクション・NLAトラックなどのアニメーションデータへは、オブジェクトごとにアクセスできる。
アクションは bpy.data.actions から直接アクセスできる。
obj = bpy.context.object obj.animation_data # アクションデータ bpy.data.actions
注意点
そのオブジェクトにアニメーションデータがない場合は、animation_dataの中身が無いので注意。
一括処理する際は事前に作成するか、アニメーションデータを持っていないオブジェクトをcontinueで除外する処理が必要。
obj = bpy.context.object
obj.animation_data
for obj in bpy.context.selected_objects:
if not obj.animation_data:
obj.animation_data_create()
if not obj.animation_data.action:
obj.animation_data.action = bpy.data.actions.new(name="Action")
for fc in obj.animation_data.action.fcurves:
# 処理...
contextでのアクセス
アニメーションデータへはcontextを使えば簡単にアクセスすることができる。
実行した際のグラフエディターやドープシートの状態に依存するので注意。
# 表示中のFカーブ bpy.context.visible_fcurves # 編集中のFカーブ bpy.context.editable_fcurves # 選択中のFカーブ bpy.context.selected_visible_fcurves # 選択中の編集中のFカーブ bpy.context.selected_editable_fcurves # アクティブFカーブ bpy.context.active_editable_fcurve # 選択中のキーフレーム bpy.context.selected_editable_keyframes # 選択中のNLAストリップ bpy.context.selected_nla_strips
他のエディターからFカーブ関連のcontextを使う方法
これらのcontextはドープシートやグラフエディターでないとアクセスできない。
そのため、それ以外のエディターのメニューボタンからこのcontextを使いたいという場合は、一旦グラフエディターに変えてから処理して、元のエディターに戻すということが必要。
ただし、コンソールエディターで利用しようとすると、エリアタイプを戻す際にクラッシュする模様。
old_area_type = bpy.context.area.type bpy.context.area.type = 'GRAPH_EDITOR' bpy.context.area.ui_type = 'FCURVES' # ドライバーなら'DRIVERS' bpy.context.selected_visible_fcurves bpy.context.area.type = old_area_type
以下はオブジェクトからアニメーションデータにアクセスする方法を紹介する。
アクション
- オブジェクト > アニメーションデータ
> アクション > 位置[0]など > Fカーブ> キーフレーム
位置を変えたい場合は、ポイント・ハンドルの左・ハンドルの右の3つを動かす必要がある。
obj = bpy.context.object
# アクション
for fc in obj.animation_data.action.fcurves:
for p in fc.keyframe_points:
# ポイントの位置
p.co.x
p.handle_left[0]
p.handle_right[0]
特定のFカーブにアクセスする場合
下記は、選択ボーンのZ位置のキーフレームの位置を表示するサンプル。
アニメーションのデータは、実際にはオブジェクトやボーンなどとは直接関連付けられていない。
data_path というFカーブの名前と、同じデータに関連付けられるようになっている。
このため、別のオブジェクトやボーンなどにも名前さえ同じなら関連付けることができる。
data_pathは単なる文字列であるため、確実に同じデータにアクセスするにはボーン名を検索して対応するFカーブを見つける必要がある。
array_indexは、XYZなどの配列の番号がどれなのかが登録されている。
import re
obj = bpy.context.object
for bone in obj.data.bones:
if bone.select:
fcurves_l = obj.animation_data.action.fcurves
for fcurve in fcurves_l:
if re.findall("pose\.bones\[\"(%s)\"]" % bone.name,fcurve.data_path):
if fcurve.array_index == 2:
if "location" in fcurve.data_path :
for p in fcurve.keyframe_points:
p.co
下記は、data_pathからボーン名を取得するサンプル。
import re
t = 'pose.bones["bone_hoge.L"].rotation_euler'
re.findall("pose\.bones\[\"(.+)\"]",t)
# > bone_hoge.L
ドライバー
- オブジェクト > アニメーションデータ
> ドライバー> 入力値
設定済みのドライバにアクセス
obj = bpy.context.object
for div in obj.animation_data.drivers:
div
ドライバを追加
下記はZ位置(つまりlocation[2])にドライバーを追加するサンプル。
追加したい属性の親データに、driver_add()で属性を指定して新しいドライバーを作成する。
ドライバの中には入力値(variables)があり、この入力値にターゲットにしたいボーン位置などを設定する。
obj = bpy.context.object
# ドライバー
fc = obj.driver_add("location", 2)
div = fc.driver
div.expression = "var + 1"
var = div.variables.new()
var.type = 'TRANSFORMS'
var.targets[0].id = bpy.data.objects["hoge"]
var.targets[0].bone_target = "Bone"
var.targets[0].transform_type = "LOC_Y"
var.targets[0].transform_space = 'LOCAL_SPACE'
NLAトラック
- オブジェクト > アニメーションデータ > NLAトラック > ストリップ
ストリップの位置を動かしたい場合は、frame_startとframe_endに同じ値を加算して動かす。
obj = bpy.context.object
# NLAトラック
for track in obj.animation_data.nla_tracks:
for strip in track.strips
strip.frame_start
strip.frame_end
参考
ソースコードの参考となる自作アドオンはこちら。