AfterEffects Scripts & Expression
スクリプト開発中に気づいたバグや仕様など。殴り書きからちょっと整えた。分類おかしいとこあるかも。間違いあったらゴメンぽよ全般
app.scheduleTaskはローカル関数の参照不可?
scheduleTaskで実行する関数が、そのときになんか値参照したいならグローバル関数にしとかないと参照できない。でもグローバル変数を大量宣言はしたくない。
⇒ウィンドウだけグローバルにして、必要なものはウィンドウのプロパティに追加するようにしとく?
「取り消しのグループが一致しません。修正します。」が出る
これが出た時は、app.beginUndoGroup() ~ app.endUndoGroup() の使い方にミスがある。ちゃんとペアで機能していない時に出る。
app.beginUndoGroup() ~ app.endUndoGroup() は一対で使うもの。スクリプトでAEに対しての処理(プロパティ変更したり)を行うと、通常1アクション毎に1アンドゥしなければいけないところを、これらで挟んだ処理をまとめて1アンドゥで戻れるようにできるもの。
通常、書き方はこんな感じ。
app.beginUndoGroup("[編集>ヒストリー]で表示する名前");
/* 1つのUndoでまとめたい処理をこの間に書いてサンドイッチする */
app.endUndoGroup();
思いつくミスは、
スペルミス
分岐・returnでミスってる
入れ子にしている
ズボラしてる
など。
■スペルミス
どんまい
■分岐・returnでミスってる
もしかしたら勘違いしている可能性がある。「ペアで記述しないといけない」というのは正確には間違い。「ペアで呼ばれないといけない」が本質ということを理解する。まぁ当たり前なんだけれど。
例えば、app.beginUndoGroup() を呼びだした。その後、app.endUndoGroup() をifの中に書いていていたが、実行時はifではなくelseを通過したとか。
例えば、app.beginUndoGroup() ~ app.endUndoGroup() の間で処理を書いているが、その中で条件満たしてない場合に中止の意味でreturnしちゃってるとか。
なので、どのフローを通っても必ず一対で呼ばれるようにすればいい。分岐中にreturnする必要があるならreturn前にもapp.endUndoGroup() を呼べばいい。
1つのapp.beginUndoGroup() に対して1つしかapp.endUndoGroup() を書いてはいけない訳ではない。複数書いておいて、実行時にどれか1つだけapp.endUndoGroup() が呼ばれるように組む。
■入れ子にしている
公式は「入れ子に出来るよ!」とか書いてるけど、エラーにはならないというだけ。毎回「修正します。」が出るんやったら「出来る」と書くな、と思うけど。
回避策は、「入れ子にしない」。
■スボラしてる
「めんどいから全体囲っちゃえ!」って人には天罰が下る。上記の理由に当てはまらない人は多分、
/* 1つのUndoでまとめたい処理をこの間に書いてサンドイッチする */
の中でタブーを犯している。
実はこのサンドイッチの間で、
importFile() でAEPを読み込んだ
openInViewer() を使った
alert(), confirm()を使った
(知られざるタブーが他にもあるかも...)
をしていると、app.beginUndoGroup() がなかったことにされるっぽい。それはつまり app.endUndoGroup() の対が存在しないということなので、もちろん「取り消しのグループが一致しません」よね。
importFile()については、スクリプト関係なくAEPをインポートするとヒストリーは消える。AEの仕様。手動でもそう。アンドゥでインポート前には戻せないはず。
なのでまぁその影響でしょうな、ってところ(フッテージアイテムなら問題ない)。まぁ理解は出来る。
なのでimportFile() でAEPをインポートした後に
app.beginUndoGroup();
を使用することで対応する。
他のに関しては何でだろう?ヒストリーが消えるわけではないのでアンドゥで戻ることは出来るけど。原因はよくわからん。
まぁ実際「修正します」が出ちゃうので、これらはサンドイッチの外側に書く。
この回避によって、本来1アンドゥにまとめたかったところを、複数のアンドゥに分割しなければならないケースが出てくるであろう。どんまい。
座標
「アンカーポイント」はローカル座標。「位置」はコンポ座標。これをうまく使う。
swf書き出しのバグ
CS6だとバグがあるらしい。swf書き出しても映像がない。解決策は、平面にフラクタルノイズを適用、展開を適当にアニメーションさせる。X軸90度傾けて、見えないようにする。するとうまくいく。とyoutubeで外国人が言っていたので、やってみたらうまくいった。
アルファ付きってだせないのかしら。アルファ付けれたらScriptUIアニメーションが使えると思ったのにな。
ディスプレイの座標
$.screens
で、接続してるモニターの座標が取れる。
$.screens.toSource()
で中身を見てみると、
[
({
left: 0,
top: 0,
right: 1920,
bottom: 1080,
primary: true,
toString: (function () { return this.left + ':' + this.top + '-' + this.right + ':' + this.bottom; })
}),
({
left: 1920,
top: 0,
right: 3840,
bottom: 1080,
primary: false,
toString: (function () { return this.left + ':' + this.top + '-' + this.right + ':' + this.bottom; })
}),
({
left: -1080,
top: 0,
right: 0,
bottom: 1920,
primary: false,
toString: (function () { return this.left + ':' + this.top + '-' + this.right + ':' + this.bottom; })
})
]
ディスプレイ数と同じ長さの配列が返ってくる。配列の各要素は各スクリーンに関する情報を格納したObjectになっていて、そのプロパティは次のよう。(通常Objectは { } で囲うことで表現するが、ExtendScriptだとさらに ( ) で囲って、 ({~}) の形で表現される)
left,top,right,bottom:そのまま。左、上、右、下の座標値。
primary:メインディスプレイの場合true。あとはfalse。
toString():座標範囲を文字列化したものを返す。
画像化するとこんな感じ
Windowsのモニター番号と、配列の順番は必ずしも一致しないようである。(黒地に白文字がWindowsの機能で表示したモニター番号)
スクリプトからウィンドウ表示する際、前回のウィンドウ位置を記憶しておいてそこに表示させたい場合、基本的にはWindow Objectのlocationを取っておいて、表示するときにlocationにぶち込めばいい。ただ、モニターの数や配置が変わった時、locationの値が画面外になる可能性がある。そうするとウィンドウは見えないところで表示されることになる。なので、そういうときはこの $.screen を使って、ちゃんと見える部分に表示されるか確認したほうがいい。ディスプレイの範囲外だったら WindowObject.center() とか使って、確実に見える場所に持ってくるべし。
見つからないファイルかどうかの判別
「見つからないフッテージ」であるかどうかは
[AVItem].mainSource.footageMissing
で確認できるが、スクリプト内でファイル移動などしてリンク切れを発生させた後にアクセスするとちょっと厄介。スクリプト実行前から「見つからないフッテージ」ならばもちろん問題ない。
どうやら、AE上で「フッテージが見つかりません」のダイアログが出て、プロジェクトパネル上でプレースホルダー(カラーバー)に置き換わらない限り「見つからないフッテージ」判定にならず、footageMissing も false のまま変化しない。で、スクリプトの実行が終わるまでこれは行われない。
厄介なのはスクリプトでリンク切れさせた後に元々のファイルパスを拾おうとした時。
まず考えるのは、リンク切れしているはずだから「見つからないフッテージ」のリンク切れ前のファイルパスを格納している
[AVItem].mainSource.missingFootagePath
の値を見たいと思う。しかし先述の通り footageMissing は false であり、 missingFootagePath には何も値が入っていない。
じゃあ「まだリンク切れしていない体なのか」と、普通に
[AVItem].file
にアクセスしてみると、ファイルは既に存在しないので、
After Effects エラー: 内部確認に失敗しました。{FILE_DirInqFileSpecByName: bad parameters}
となりエラーが発生する。
解決策としては、パスが必要な場合は、ファイルの移動前にそのファイルパスを変数に取っておく。
最新の footageMissing の値を知りたい場合は、
try { item.file; }
catch (e) { continue; }
として file にアクセスしてみて、エラーになるかどうかで分岐するしかないか。
AEのバージョン番号
CC2015がマイナーアップデートだったり...。
2022が他のCreativeCloudアプリとバージョン番号を統一するため、前バージョンとの間に欠番があったり...。
に注意。
CS3: 8.0
CS4: 9.0
CS5: 10.0
CS5.5: 10.5
CS6: 11.0
CC: 12.0
CC2014: 13.0
CC2015: 13.5
CC2017: 14.0
CC2018: 15.0
2019: 16.0
2020: 17.0
2021: 18.0
2022: 22.0
勝手にESTKが立ち上がる
スクリプト実行時にESTKが立ち上がることがある。原因は2つ。
環境設定で「JavaScriptデバッガーを使用」をONにしている状態で、スクリプト実行時にエラーが発生した
$.writeln() でコンソール出力した
2は見落としやすいところ
importFileの戻り値がおかしい
importFileでAEPを読み込んだ後、正しい戻り値が取れないケースが有る。
CS6では問題なかった。2019,2020,2021,2022で確認済み。
(function () {
/**@type {File} AEPファイル */
var f = File("~/desktop/aep1.aep");
/**@type {FolderItem} 親にするフォルダ */
var parent = app.project.items.addFolder("parent");
/**@type {FolderItem} 子にするフォルダ */
var child = app.project.items.addFolder("child");
// 選択状態にしてから子にする
child.selected = true;
child.parentFolder = parent;
/**@type {FolderItem} 2つ目のAEPをインポートして出来るFolderItem */
var aep = app.project.importFile(f);
// 変数AEPに入っているアイテムの名前を表示
$.writeln("name of aep: " + aep.name);
})();
この出力結果は
name of aep: child
となる。期待していたのは、
name of aep: aep1.aep
である。
発動条件
問題は、「閉じたフォルダアイテムの中に、選択状態のフォルダアイテムが入っている」状態による?っぽい???
選択された状態の FolderItem を別の「閉じたFolderItem」の子にする。閉じていることが重要。開いたフォルダに入れても発動しない。順番も重要で、「選択された状態のもの」を子にする。子にしてから選択状態にすると、自動的にフォルダが開かれるので条件を満たさなくなり、発動しない。
この状態で、importFile() でAEPをインポートする。その戻り値を変数に入れて、データ内容を確認すると、あら不思議。さっき子にした FolderItem が入っているわ。ちなみにAEP以外、つまりフッテージやPSDをコンポとして読み込みなどの場合は問題ないっぽい。
注意点は、1つのスクリプトで無くとも発生すること。AEPをインポートするより先に別のスクリプトによって「選択状態のFolderItemが、別の閉じたFolderItemの子になっている」状態が成り立っていると発生してしまう。
対策方法
対策としては、parentFolderを設定する前に選択状態を解除しておくこと。これだけで解決。
ちなみに
これ、手動で発生条件を整えることは出来ない。なぜなら、ドラッグアンドドロップで「選択フォルダ」を「閉じたフォルダ」の子にした時点で、「選択フォルダ」の選択解除が自動で働くからである。だが、スクリプトで設定した場合にはこれが働かないようで、発生条件が整ってしまう。
また、条件成立した状態で、プロジェクトパネルを触って選択状態が変わったりするとそれでももちろん発生しない。
エクスプローラでネットワークドライブの登録が勝手に増える
Windowsでドライブの割当を変更したりして、存在しないドライブへのショートカットと化してしまった状態で「ファイルの場所を開く」をすると勝手にそのドライブが登録されるみたい?ショートカットファイルはコンピューター名などの情報は持っていないと思うけど、なぜ?持ってんのか?
つまり本来AfterEffectsの問題では無いのだが。AE起動時に読み込まれるプリセットやプラグインに、見つからない場所へのショートカットがあるとドライブが勝手に増える可能性がある。消したり、修正したりすれば多分直る。CS6では出たが、同じ環境でも2020では起きないみたい。
あまり詳細調べてないが、調べてみる価値はある。
$.fileNameの戻り値がバックスラッシュ表記になる
単純にこんなスクリプトを実行してみる。
alert(File.decode($.fileName));
(File.decodeを使用しているのは、アラート内容がマルチバイト文字だけパーセントエンコードで表示されるのを防ぐためであって、この話題の趣旨とは関係ない)通常、
/d/テスト/test.jsx
といった感じで、スラッシュ区切りでの表記で戻ってくる。
ただしVSCodeから実行した場合、パスの中にマルチバイト文字が含まれていると
d:\テスト\test.jsx
のようにバックスラッシュ(or¥マーク)表記で返ってきてしまうかもしれない。
前はそんなことなかったので、おそらくExtendScript Debuggerのバージョンが2.0.0になったのが関係していると思っている。
対策としては、一回Fileオブジェクトにしてしまって、
File($.fileName).fullName
とすればスラッシュ表記で取得できる。
コンポジション
3DレイヤースイッチをONにするとレイヤーの位置が変わる
語ってもよいですかな?こちら。
レンダーキュー
RenderQueueItem.render の注意点
レンダーキューのチェックが入ってると、RenderQueueItem.render = true。入っていないとfalse。
ってのはいいんだけど、チェックマークが見えない状態(ステータスが「完了」など)でも、render == true になってる。なのでズボラしないでちゃんとstatusで状態把握してからじゃないと困ることがある。同じことを下でも書いている。
[RenderQueueItem].status == RQItemStatus.QUEUED
RenderQueueItem.statusの注意点
DONE
「ステータス」が「完了」の状態。
それはまぁいいんや。この「完了」の時、レンダーキュー内の「レンダリング」チェックマーク(RenderQueueItem.renderプロパティの値に相当するもの)が見た目上は無くなるが、内部的にはONの状態(true)を持っている。
なので、レンダリングされる予定のアイテムだけを探したい時に render プロパティだけで探すとえらい目に合う、事がある。
試したことないけど、他のステータス状態
ERR_STOPPED
QUEUED
RENDERING
USER_STOPPED
WILL_CONTINUE
も同じか?
NEED_OUTPUT
出力先がない状態。厳密には「ステータス」が「出力先が必要」となっている状態。
なので「一度設定してた出力先のフォルダを消しました」というときは、NEED_OUTPUTにはならない。あくまでレンダーキュー内の「ステータス」列の表示に一致する。
出力名がコンポ名に連動しなくなる
出力ファイル名に[compName]という表記を使うと、レンダリングで出力されるファイル名がコンポ名と連動する、というのはAfterEffectsユーザーなら知っていないといけないことだが、ここに落とし穴が出来た。
右図の青い文字の部分をクリックして、手動で出力先を変更する際、
従来だと、ファイル名は変更せずに出力先フォルダだけを変更した場合、[compName]の表記は維持された状態で出力先を変更できた。
2020から?同じことをした場合、[compName]の表記が「コンポ名の直打ち」に変更されてしまう。この状態だともちろんコンポ名をいくら変更しても出力ファイル名は変わらない。
元に戻すには、出力先を手動変更した後に青文字の左、「v」マークのドロップダウンから「コンポジション名」など適当なものを再選択する。
レンダーキューのチェックボックスが消えない/レンダリングログが間違っている
AEのレンダーキューパネルからレンダリングした時に、完了したキューのチェックボックスが消えないことがある。ただしムービー等は問題なく出てる。チェックボックスが生きてるのでレンダリング終了後にそのまま何度でもレンダリング出来てしまう。この影響かはまだ不明だが、レンダリングログの「出力先」の内容が間違っている。
以下の2つを満たしていると多分発生する。
①古いバージョンのAEで作ったキューをそのまま流用している
原因の1つはキュー自体が古いせい。新しいバージョンでAEP保存したとしても、そのキューアイテムがAEPをインポートしたことで追加されたものではだめ。「レンダーキューに新規登録された時のバージョン」が問題。古いバージョンから秘伝のタレのように新しいバージョンで上書きし続けてきたら発生する可能性がある。2020で新規追加したキューでは発生しなかった。「古い」というのがどこより古いものを指すのかは不明。私の環境だと6.5かCS4、CS6のどれかで作ったキューで発生しているはず。(どれかまでは調べてない。)
②①のAEPを複数読み込んでいる
①で作ったAEPを現在のプロジェクトに複数読み込んでいて、問題になるキューが複数存在している
解決策としては、キューを登録し直すのが無難。そしたらレンダリングログも直った。
エフェクト
InstantHDのアスペクト比固定がおかしい
1:1になるw
もうInstant4K使ったほうがいいんじゃないかなぁ...。
ドロップダウン制御エフェクトの日本語問題
「ドロップダウン制御」エフェクトを追加した後はほぼ100%、選択肢を設定することになる。じゃないと、「項目1」「項目2」「項目3」のままだと使いにくいから。
しかし、ここでお馴染み日本語バグ。
[Property].setPropertyParameters(["あいう", "えお"]);
のように日本語の選択肢を追加した瞬間にAEが死ぬ。
2021では解消していた。
ドロップダウン制御エフェクトのマッチネーム
スクリプトから「ドロップダウン制御」エフェクトを適用するには
[Layer].effect.addProperty('ADBE Dropdown Control');
とすれば良い。特に問題ない。
「ドロップダウン制御」エフェクトのマッチネームを調べると、
ADBE Dropdown Control
が返ってくるのだと期待するが実際やってみると、例えば
Pseudo/@@FKUYv4qdSYitWk++Tcq/Hg
のようになる。エフェクトを複製して、新しいほうのマッチネームを調べると、例えば
Pseudo/@@h7Tju8QiS7+iNpZUcIDTqA
のようになっている。このようにマッチネームが一意に定まらない。
Pseudo (スード)というのは「疑似」とかそんな意味。これは2017だか2018くらいから作れるようになった、「Pseudoエフェクト」として扱われているということがわかる。(ユーザーが自分でコントローラーエフェクトを作成できるやつ)
理由としては予想だけど、ユーザーが自分で選択肢を設定できるので、マッチネームで「同じエフェクト」と扱ったとしてもそのエフェクトが持つ選択肢の数が変わったりして何かしらに不都合が出てくるから?
なので、「ドロップダウン制御」エフェクトかどうかを判断するには、マッチネームが使えない。
「マッチネームの先頭が『Pseudo/@@』で判断すればいいやん!」と思った人は、多分Pseudoエフェクトを使ってないからそれでも問題ないかも(いつか問題になっても知らないけど)。Pseudoエフェクトに馴染みがある人は、確実な方法をとったほうがいい。
開発陣はこれにもちろん気づいていて、
[Property].isDropdownEffect
というプロパティが新しく用意されている。これがtrueの時、「ドロップダウン制御」エフェクトであると正確に判断できる。
コンポジション
addCompのバグ?
スクリプトでaddComp()する時の尺が微小なずれが出てる可能性がある。16コマで作成すると、タイムラインは16コマまでだが、コンポ設定が17コマになってしまう。一度適当な尺で作成後、durationだけ再設定することで、16コマで表示された。
ramPreviewTest() メソッド
CompItemObjectにあるメソッド。何に使うかはわからない。引数は3つ。
Boolean : ビュワーの透明グリッド。true->背景色表示、false->透明グリッド表示。
Number : ビュワーの拡大率。1で100%。0.5で50%。
Number : ビュワーの露出。
実行すると自動RAMプレビューが行われ、一度再生された後、次のような戻り値が来る。
meanFPS: 24.002183 lowestFPS: 22.939410 stdDev: 0.230002
平均FPS、最低FPS、標準偏差。意味はわかるが、わからん。
saveFrameToPng() メソッド
CompItemObjectにあるメソッド。指定したフレームをアルファ付きのPNGで書き出す。引数は2つ。
Number : 書き出したいフレームを秒指定。
File : 書き出したいPNGのFileObject。
レンダリングしなくてもフレーム画像を取り出せるのでいろいろ役立つ。アルファチャンネルを持っているが、ストレートカラー表示したときは、アルファ部分はコンポの背景色になっている。コンポの解像度を1/2、1/4などにしていると、書き出されるPNGの大きさもそれに比例する。
第3のレンダラー
compItemObjectの持つrenderersを見ると3種類ある。UIからだと「クラシック3D」「レイトレース3D」の2つしか選べないのに。
こうなると設定してみたくなるのが人間の性。やってみた。
var comp=app.project.activeItem;
comp.renderer=comp.renderers[2];
設定してからコンポ設定を開くと、
コンポ設定から項目が消えた。この状態で、適当にレイヤーを3Dレイヤーにしてみると、表示されなくなる。3Dレイヤーの計算がされなくなる。AEが3Dレイヤー対応する前の遺品?設定するメリットは特になさそう。
フレームレート23.976
フレームレート23.976のコンポのフレームレートをスクリプトで取得してみると
23.9759979248047
が返ってくる。
コンポのtimeを例えば10に設定してから、インジケータの値、つまり設定したtimeの値を確認してみると
10.01001001001
になる。計算時に微小なズレが出て困る場合は、数値の直打ちよりも、これらの値を使用したほうが無難かもしれない。
レイヤー
LayerObj.copyToComp() の戻り値
LayerObj.copyToComp() はコピー先の選択しているレイヤーの上にコピーされる。選択レイヤーが無い場合は一番上。
戻り値がないため、コピー後のレイヤーを拾いたいときは、
コピー先のコンポのレイヤー選択をすべて解除してからcopyToCompを実行。それからレイヤー#1を拾う
コピー先の選択レイヤー(複数選択ある場合は一番上のレイヤー)の一つ上を拾う
いずれかの方法を取る。
LayerObj.applyPreset()の罠
applyPreset(訳:プリセット適用)は、レイヤーオブジェクトのプロパティとして用意されてるんやから、そのレイヤーに対してプリセット適用すると思うやん? まさか、選択レイヤーに適用するとは誰が想像しようか。
例えば「レイヤー#1」に適用しようと思って「レイヤー#1」をスクリプトで取得したが、「レイヤー#1」が選択状態でなかった場合(つまりレイヤーのselected=false)、適用されずパニクること必至。よく調べてみると、同じコンポ内の選択されている他のレイヤーにだけ適用されている。
これはもう、そういう仕様として受け入れる。ずーーーーーっと前からそう。少なくともCS4のときから。(2023現在でも同様)
解決法は、
コンポ内の全レイヤーの選択状態を取得しておく
コンポ内でプリセット適用したいレイヤーの選択状態(selected)をtrue、それ以外のレイヤーはfalseにする
applyPresetを実行する
1で取得したデータを元に、コンポ内の全レイヤーの選択状態を元に戻す
選択状態の復帰が不要なら1と4は不要。
applyPresetを使うためにLayerObjを取得する必要があるが、それはもうなんでもいい。適用にAVレイヤー選択しとけば。
プリセット適用されるレイヤーと、applyPreset呼び出しのために取得したレイヤーは一切関係ない。
3Dレイヤーにすると位置がズレる?
詳細はこちら
レイヤースタイル
レイヤースタイルのenabledが厄介
見えているときは問題なし。見えてないときが厄介。
何もしてないとき(デフォルト状態)だとすべてtrue。
何かを割り当てたとき、それ以外falseに。
削除したときは直前の状態が残ってる。
見えないものにsetValueするとエラー
テキストレイヤー
textDocumentの謎
テキストレイヤーからtextLayer.sourceText.valueでtextDocumentを取得して、中身書きかえてsetValueで再設定するも、それが適用されない。CS6だけなのかどうか知らんけど。textDocument.textを空文字にするか、setValueを2回連続で実行してやればなぜかうまくいった。よくわからん。
target.sourceText.setValue( texDoc );
target.sourceText.setValue( texDoc ); //テキストを空文字にするか、setValueを二回やるとなぜかちゃんと適用される。
↑解明した
空文字のテキストレイヤーに対して
[TextDocument].sourceText.setValue(textDocument)
を設定するとちゃんと反映されない。反映されないのは、文字パネル上で出来る設定。フォント、塗り、線、フォントサイズなど。テキスト内容、左揃えなどの段落関係は問題ない。
「後で塗りとか設定する時にテキストも一緒に設定するから...」と、スクリプト内でテキストレイヤー作成時にダミーのつもりで空文字にしていると、「あれ?反映されない、なんでなんで!?」と焦る。1文字でも何か入れてあるとちゃんと反映するので、"a" でも "dummy" でも入れておけばよい。
↑で「2回やればOK」だったのは、一度目の適用ではテキスト内容だけが適用され、二度目の適用時点では空文字ではなくなっているので、塗りなどの設定も反映された、ということ。
スクリプトでテキストのjustificationが設定できない。
テキストレイヤーに改行が入っているとjustificationを設定し直しても無視される。一度、改行なしのダミーテキストを入れてから[TextLayer].sourceText.valueでtextDocumentを取得。textDocumentのtextとjustificationを設定して、textLayer.sourceText.setValue()する。
プロパティ
勝手にプロパティが展開されてうざい
スクリプトからタイムリマップONにしたりした場合、タイムラインパネル上でプロパティが展開表示された状態になる。必要ないものが(しかも勝手に)展開されているとイライラする。いくつか解決法がある。
コンポジションビュワーで開いていない時は展開されないので、先にごちゃごちゃ必要なことをしてから、openInViewer()を使う
AVLayerObject.replaceSource()を使う。レイヤーソースを置き換えるとプロパティが全部閉じるのでこれを利用する。タイムリマップONにしたりしたあとに同じ素材で置き換えを行う。すると展開されていたものがすべて閉じる。ハッピー。
上記の方法だとテキストレイヤーなどレイヤーソースがないものには対応できない。そんなときはDuplicateでレイヤーを複製。複製された方はプロパティが全て閉じた状態。複製レイヤーの名前を元のと合わせてから、元のレイヤーを削除。
都合いいものを使う。
プロパティが設定できない?
UI上で表示されていないプロパティはsetValueなどで値を設定できないときがある。
例えば、P_ColorSelectionでは「SetColor」プロパティで設定できるカラープロパティの数を変更できるが、それに合わせてUI上に表示されるプロパティの数も変わる。SetColorを変更したことによって新しく見えるようになったプロパティに対して設定しようとすると、
Error Code# 1: After Effects error: Can not “set value” with this property, because the property or a parent property is hidden.
と言われて、エラーになる。
この場合は、エフェクトを複製したり、新規追加した後で設定すると上手くいく。
[CompItem].time = [CompItem].time;
のようにコンポの time を設定するなども効果はあるが、1回の実行中に1度しか使えない。ループなどで複数回実行しようとすると、エラーになる。
なのでなんでもいいので適当なエフェクトを追加して削除が無難。これは何回でも効果がある。
エフェクトの追加・削除・入れ替えなどすると、エフェクトを参照している変数が無効になるので再取得しないといけない。
var fx = /*適用しているエフェクトのPropertyGroupを取得しているとする*/;
var pIndex = fx.propertyIndex;
// 複製と削除
fx.duplicate().remove();
// 再取得
fx = effect.property(pIndex);
エクスプレッション
「After Effects 警告: エラー : 時間 -259199 にアクティブカメラがありません」
エクスプレッションで thisComp.activeCamera を使っているときで「After Effects 警告: エラー : 時間 -259199 にアクティブカメラがありません」て言われることがある。
カメラレイヤーの尺が足りていないだけでした。コンポ尺の外でアクティブカメラが見つからないフレームがある。はず。カメラレイヤーを伸ばせばよい。もしくはエクスプレッション書いてるレイヤーを短くしてカメラレイヤーの尺に収める
エクスプレッションのエラーメッセージを好きな文章にする
try~catchでエラーを拾った後、catch内で
$.error = "" + quote + "カメラ 1" + quote + " を 1 ノードカメラにすることはできません。"
みたいに書くと、エラーの文章が変わる。
エッセンシャルプロパティ
エッセンシャルプロパティ内のエクスプレッションでタイムリマップ値を取得したい
timeRemapを拾うのではなく、timeで拾う。さらに、startTime分だけずれるので補正する。
エッセンシャルグラフィックスパネルで設定した「名前」をスクリプトで拾えないことがある
エッセンシャルグラフィックスパネルで設定した名前は
[CompItem].motionGraphicsTemplateName
で取得できるが、設定したにも関わらず値が Untitled になるパターンがある。
日本語でAEを起動。エッセンシャルグラフィックスパネルで「名前」を設定しAEP保存
ae_force_english.txt でAEを英語起動し、1のAEPを開く
エッセンシャルグラフィックスパネルで「Name」の欄を確認
すると、1で設定したはずの名前が入っておらず、Untitled が取得される。
逆に、英語環境で保存した時は日本語環境でも正常に取得できる。
スクリプト関係なく発生するが、mothionGraphicsTemplateName を使用する時は注意する。
2020
・addEventListener("enterKey")が使用できない。代わりにonEnterKeyを使用する
・ただしonEnterKeyは2回呼ばれる。
CS6で矢印キーが反応しなかったのがきくようになった
スクロールバーがオシャレになりすぎて、両端の矢印ボタンが無くなった。クリックでワンステップずつスクロールできなくなったかと思いきや。マウスホイールが反応するようになっている。ドロップダウンも反応する。最近しなくなった。
// inPointを変えるとCCだとバグ?outも変わるし、durationも変わるし...どういうこっちゃ...
// CS6の時はoutは変わったけど、durationは変わらなかった
// なので先に取っておこう
ドロップダウン制御エフェクトをエッセンシャルプロパティに設定した状態で、ドロップダウン項目の編集(削除?)を行うとAEが落ちる
ドロップダウン制御エフェクトの項目に区切りを指定するには項目名に「(-」を指定する
ドロップダウン制御エフェクトについて
setPropertyParameters()を実行するとドロップダウンアイテムを設定できるが、 2020の時は日本語が含まれていると死ぬ。2021では問題なし。
また、setPropertyParameters()実行時にエフェクトのオブジェクトが無効されるので、変数も使用不可になる。(プロパティ追加時などと同じ挙動)
その際、エフェクト名も何故か影響を受けているので、setPropertyParameters()を実行する前にエフェクト名を変更すると、エフェクト名が空文字になったり(2020)、デフォルトに戻されたり(2021)する。
エフェクト名の変更は後でやったほうが無難
$オブジェクト
$.fileNameの返り値が変わる
$.fileNameの戻り値が変わることがある。
条件は多分、
VSCode(ExtendScript Debugger)から実行している
スクリプトのパスに日本語(マルチバイト文字)が含まれている
通常は、
~/Desktop/%E3%81%82/fileName.jsx
という感じで返ってくるはずだが、条件を満たした場合、
d:\Users\(username)\Desktop\あ\fileName.jsx
という感じで、バックスラッシュ(円マーク)区切りの表記で返ってきてしまう。もちろんフォルダ名だけでなく、ファイル名自体に日本語(マルチバイト文字)を使用している場合でも起きる。
AEやESTKで実行した場合はこれは発生しない。ちゃんとスラッシュで区切られた表記で返ってくる。
ESTKで作成していたスクリプトを、VSCodeで実行した場合に焦る場合がある。
$.fileName で取得した文字列をスラッシュ区切り前提でごちゃごちゃ操作していると思った通りに文字列取得できておらず結果、エラーにつながることがある。
解決策としては一度ファイルオブジェクトにしてしまう。
// スラッシュ区切り
File($.fileName).fullName;
// ファイルシステムに合わせた表記(Windowsならバックスラッシュ(\)または円(¥)記号)
File($.fileName).fsName;
として、確実にどちらかの表記にしてしまう。