※240825に追記しスクリプトの中身も変わっています。
今回はエクスプレッション記事の「お手軽エクスプレッションwiggle() で揺らす」でも紹介したエクスプレッションのおさらい記事です。スクリプト記事ということで、ワンクリックで適用出来るようスクリプト化していきます。
[完成品_途中版]
var sel=app.project.activeItem.selectedLayers;
function f_posWigglr(){
var wigFx=[];
for(i=0;i<sel.length;i++){
wigFx[0]=sel[i].property("ADBE Effect Parade").addProperty("ADBE Slider Control");
wigFx[0].enabled=false;
wigFx[0].name="wigFreq";
wigFx[1]=sel[i].property("ADBE Effect Parade").addProperty("ADBE Slider Control");
wigFx[1].enabled=false;
wigFx[1].name="wigAmp";
sel[i].position.expression=
'wiggle(effect("wigFreq")(1),effect("wigAmp")(1));';
}//for
}
app.beginUndoGroup("posWigglr");
f_posWigglr();
app.endUndoGroup();
[完成品]
var sel=app.project.activeItem.selectedLayers;
function f_posWigglr_V2(){
var wigFx=[];
for(i=0;i<sel.length;i++){
wigFx[0]=sel[i].property("ADBE Effect Parade").addProperty("ADBE Slider Control");
wigFx[0].enabled=false;
wigFx[0].name="wigFreq";
wigFx[1]=sel[i].property("ADBE Effect Parade").addProperty("ADBE Slider Control");
wigFx[1].enabled=false;
wigFx[1].name="wigAmp";
//by MotionScript.com - Controlling Wiggle Speed
sel[i].position.expression=
'freq = effect("wigFreq")(1);\r'+
'amp = effect("wigAmp")(1);\r'+
'n = freq.numKeys;\r'+
'if (n > 0 && freq.key(1).time < time){\r'+
' accum = freq.key(1).value*(freq.key(1).time - inPoint);\r'+
' for (i = 2; i <= n; i++){\r'+
' if (freq.key(i).time > time) break;\r'+
' k1 = freq.key(i-1);\r'+
' k2 = freq.key(i);\r'+
' accum += (k1.value + k2.value)*(k2.time - k1.time)/2;\r'+
' }\r'+
' accum += (freq.value + freq.key(i-1).value)*(time - freq.key(i-1).time)/2;\r'+
'}else{\r'+
' accum = freq.value*(time - inPoint);\r'+
'}\r'+
'wiggle(1,amp,1,.5,accum)';
}//for
}
app.beginUndoGroup("posWigglr_V2");
f_posWigglr_V2();
app.endUndoGroup();
[概要]
位置へのウィグルエクスプレッション適用時に、スライダーを噛ませることで柔軟性を上げるスクリプト。
[使い方]
- 適用したいレイヤーを選択する
- スクリプトを実行する
- レイヤーに追加されるエフェクト「wigFreq」「wigAmp」の数値でウィグルの強さを設定する
エクスプレッションのwiggleは値を2つ必要とするため、「wigFreq」は1秒間に何回目標位置を変えるか、「wigAmp」は最大何ピクセル揺らすか、をそれぞれ指定します。
「wigFreq」の方をキーフレームで数値を変えようとすると、毎フレーム目標位置を変えてしまうようで、「wigFreq」は固定し、「wigAmp」の揺らす強さの方で調整すると、↓改善済み
それぞれキーフレーム制御できるため、”一瞬揺れて収まる”、”次第に揺れが大きくなる”アニメーションを自然に表現できます。
[オプション]
- 追加されるエフェクト2つはスライダーエフェクトの為、キーフレームを設定しウィグルをコントロールできる
- ウィグルの揺れ方はseed値で決まり、これはレイヤー番号が変わるだけで異なるseed値が読み込まれるため、揺れ方を完全コントロールするというより、「揺れればいい」程度で使用するのが良い
[解説]
wiggle()はレイヤーを揺らす関数です。「()」の中に2~5個の引数が指定でき、2つの引数は必要な関数です。また引数が足りなかったり多かったりすればエラーとなります。
wiggle(1秒間に揺らす回数, 揺れの大きさ, 細かさ, 揺れ大きさの倍率, 時間);
これら5つの引数は実際には
↓
wiggle(2,15,1,.5,time);
のように最大5つの引数を指定し、揺れ具合をコントロールします。
初めの2つのみ必須で、後半3つは省略可能です。省略した場合は上記のグレーの数値がデフォルトで入ります。
引数の意味は、wiggle(1秒間に揺らす回数,揺れの最大ピクセル数);です。
wiggle(.5,100);
ならゆっくりと大きな揺れ、
wiggle(30,5);
なら素早く細かな揺れになります。
カメラの位置に適用し3Dレイヤーに対して手ブレを表現したり、レイヤーそのものの位置に適用し震えを表現したりできます。
今回は手軽に一つのレイヤー位置に適用し、スクリプトの挙動を確認します。
挙動の確認
それぞれ指定の1秒間に揺らす回数、揺れの最大ピクセル数内で動いているのがわかります。
ウィグルは位置のエクスプレッションとして直接打ち込んでもいいのですが、その場合は手軽な反面、初めから終わりまで揺れ方を変えることができません。
キャラクターがモノに当たったときや、ショックを受ける際に「揺れて、止めたい」「途中から揺れはじめさせたい」という場合は、wiggle(freq,amp);に渡す値が変更可能なものでなくてはいけません。
そこでキーフレームで値を制御できるスライダー制御を噛ませることで、柔軟性を持たせたのがこのアイディアです。
仕組みを知っていくと他のエクスプレッションやスクリプトを使用する際にカスタマイズできるからです。
[ブラッシュアップ部分]
ここで、「freqをキーフレーム変化させるとampが無視されMAX?になる」という挙動があり、エクスプレッションの箇所にて、使い道のわからなかった5つめの引数「時間」にaccumとした計算を入れ込むと該当の挙動を自然な結果にすることができます。
ただここにもハードルが1つあり、引数の5つめにアクセスする場合、途中の省略可能な3,4番目の引数も指定しなければいけません。省略時に勝手に入るデフォルト値(細かさ=1,揺れ大きさの倍率=.5)をそのまま記入してやり過ごします。
wiggle(1秒間に揺らす回数, 揺れの大きさ, 細かさ=1, 揺れ大きさの倍率=.5, 時間);
経緯
Adobe Communityにてwiggleの質問スレッドがあり、そこで知ったのですが私が解決できず、さらに当時そこまでこだわりがなく長年放置していた問題に実は答えがもうありました。不勉強を嘆くと同時に、歓喜です。
↓流れはこちらのスレッド。
「freqをキーフレーム変化させるとampが無視されMAX?になる」という同じ悩みを持った方がおり、Community ExpertのMukaida様が回答しています。
下記サイトの「Controlling Wiggle Speed」に対処法が掲載されているので参考にしてみてはどうでしょう。
MotionScriptは、昔から有名なサイトの一つです。
Controlling Wiggle Speed
とのことで、MotionScript.comというサイトで、この問題へ対応するエクスプレッションの言及がありました。
https://www.motionscript.com/articles/speed-control.html#wiggle
こちらを組み込んだものが改善版のスクリプトとしてエクスプレッション部分に反映してあります。
先人たちの知恵を拝借いたしました。ありがとうございます。
ダウンロード
posWigglr_V2.jsx
次回予告
次回はJavaScriptのみならず、プログラミングの醍醐味、「条件分岐」について学びます。条件によって処理を振り分ける、プログラミングで出来ることを一気に広げる知識です。
下記リンクから飛べます。
この記事へのコメントはありません。