【DaVinci Resolve Fusion】ボタンやOn Changeに書いたAPIスクリプトのリンク切れを起こさせない方法
よくある問題点
その1
マクロ化したときにエクスプレッションはノード名にあわせて自動的に変更され、柔軟に扱うことができます。
しかし、On Changeや実行に書いたスクリプトはリネームが行われません。
なので、ボタンを押したら別のノードに作用してたりしていて扱いずらい…
その2
さらなる問題点として、イベントが起こったノードはtool
変数で取得できますが、
マクロのコントローラとして表出した場合はtool
がマクロを指すというものがあります。
元のノードのコントローラを同じ変数名で表出させておかないと、元のノードの操作ができなくなります。
これらを解決します。
解決策
親子関係をスクリプトでたどる
マクロでもグループでも、どちらでも使用可能なGetChildrenList()
というメソッドがあります。
Lua> for _, tool in pairs(ActiveTool:GetChildrenList()) do -- ActiveToolはグループ
print(tool.ID)
end
Shadow
ofx.com.blackmagicdesign.resolvefx.ShrinkAndGrow
Blur
PipeRouter
Merge
目的のIDだったり、特定のコントローラを持つかどうかなどで条件分岐してノードを特定すれば、
ノード名を指定しないで操作が可能になります!
tool変数に対応する
イベントが起きた時のtool
の値によって処理を分けます。
local targetNodeName = "BigShadow"
local node = nil
if tool.Name:gsub("[_%d]+$", "") == targetNodeName then
node = tool
else
for _, t in pairs(tool:GetChildrenList()) do
if t.Name:gsub("[_%d]+$", "") == targetNodeName then
node = t
break
end
end
end
この例ではBigShadowというマクロを探しています。マクロの中にマクロがある状態です。
マクロ.IDではMacroもしくはGroupが返されて絞り込みにくいため、
Nameの末尾の数値をgsub
で削除して取得と比較を行っています。
最初のif文で、操作されたのが元のノードだった場合にtrueとなります。
マクロのUIから操作して発火したならfalseとなりfor文に入ります。
for文ではグループ内だけに絞って該当するノードを探しに行きます。親子関係をスクリプトでたどる方法を使うわけですね。
もし対象のノードが見つかったという状態になったらifがtrueとなりbreakによってforから強制的に抜けます。
そしてnode変数を使ってやりたかった処理を書いていきましょう💫
チェックボックスの状態について
On Changeを使う際はチェックボックスの併用が多いかなと思い、便利な書き方を紹介しておきます。
チェックボックスが0か1かを取得するにはtool:GetInput(self.ID)
と書けば、ノード名がどうであっても取得できます。
self[0]でも動作するんです、0フレーム目の値を参照という意味です。
しかしレンダリング開始時間によってはコンソールにエラーが出現しており、安定させるなら上記の書き方がよいと思います。
番外編
使用頻度は低いかもしれませんが、前後のつながりをたどることもできます。
(Pythonで実行したときの残し書きです🙏)
Py3> print(comp.MugLazyText2.Input.GetConnectedOutput().GetTool().ID)
Background
InputはFindMainInput(1)
に置き換えも可能なようです。
Output側も似たような方法で取得できます。
Py3> print([input.GetTool().ID for input in comp.Background3.Output.GetConnectedInputs().values()])
['ofx.com.blackmagicdesign.resolvefx.BurnAway', 'ofx.com.blackmagicdesign.resolvefx.BurnAway', 'Fuse.MugLazyText']
またエクスプレッションでも前後のつながりをたどることができます。
こちらの記事にスクリプトが掲載されていました:Expressions — John Holt
self:GetSourceTool("[connected input]"):GetValue("[source parameter]",[source time]
エクスプレッションでは冒頭でもふれたとおりリネームが自動的に効くため、使用頻度は高くありませんが面白いことはできるかもしれませんね。
Discussion