【エクスプレッション】親レイヤーを途中で変える(位置だけ)

AEユーザーの見果てぬ夢「親レイヤーの途中変更」を試みました。
子レイヤーの回転や大きさは変えられず、位置だけ成功したので、いわば「バケツリレーコンストレイント」的な感じです。

STEP
準備。

親2つと子を用意します。
そして、親2つに「ここから親レイヤーになります」という印のマーカーを打っておきます。

*写真では黄ヌルが子で、赤ヌルが親レイヤー1、青ヌルが親レイヤー2です。

STEP
子の「位置」に以下のエクスプレッションを適用。

親名はヌル 1とヌル 2になっているので、適宜変えてください。

var はスクリプトでは必要ですが、エクスプレッションではあってもなくてもよいので、消しても大丈夫です。

var mNul1 = thisComp.layer("ヌル 1");
var mNul2 = thisComp.layer("ヌル 2");
var mInitTime = mNul1.marker.key(1).time;
var mAltTime = mNul2.marker.key(1).time;

if(time < mInitTime){
	value;
}else{
	var mValNul1LyrCrd = mNul1.fromComp(value,mInitTime );
	if(time < mAltTime){
		mNul1.toComp(mValNul1LyrCrd);
	}else{
		var mNul1LastPt = mNul1.toComp(mValNul1LyrCrd ,mAltTime );
		var mNul2LyrCrd = mNul2.fromComp(mNul1LastPt,mAltTime );
		mNul2.toComp(mNul2LyrCrd );
	}
}
STEP
完成!

親レイヤー1のマーカー時間まではどちらも親レイヤーではなく、
親レイヤー1のマーカー時間からは親レイヤー1に追従し、
親レイヤー2のマーカー時間からは親レイヤー1に追従します(位置だけ)。

使いどころ

前述のように「バケツリレー」的表現のときには使えるんじゃないでしょうか?

*使用時の注意点
3段階のどの場面でも子レイヤーにキーを打って移動させられます。が、通常の親子レイヤーと違い、[0,0]で親レイヤーと重なるわけではなく、親レイヤーのマーカー時間のポジション値と同じ値を入れると重なります。

なんだかわかりにくい場合は子レイヤーをヌルにしておき、そのヌルを親、動かしたいレイヤーを子とした普通の親子レイヤーをさらに設定するとよいやもです。そうすれば、動かしたいレイヤーは通常の親子レイヤーの感覚で動かすことができます。

また、通常の親子レイヤーと同じなのですが、子レイヤーの位置を変えると全体のアニメーションに影響が出ます。
そして、親レイヤー1から親レイヤー2へ移り変わった後でも、親レイヤー1のアニメーションを変えると、それが親レイヤー2のアニメーション終了前であれば子レイヤーの位置に影響が出ます。注意してください。

解説

このエクスプレッションの肝の部分はfromCompとtoCompです。
これらはfromComp(座標、時間)といったように、時間指定できます。

■手順1
初めに「親1のマーカーに来たら親子関係スタート」を実装します。

通常の親子レイヤーを考えてみてください。変形や移動している2つのレイヤーを親子関係にするとき、「どの時間で親子にするか」で動きが変わってきますよね?このエクスプレッションではその時間をマーカーで決めます。

まずはfromCompで、子の、親1基準での相対位置(レイヤー座標)を得ます。このときに親1マーカー時間で時間指定しとくのがポイントです。通常の親子レイヤーで言えば、「マーカー時間にインジケータを合わせて親子にする」って感じですね。通常の親子レイヤーであればそれだけでいいんですが、エクスプレッションだとそれをコンポ座標に変換せにゃなのでtoCompします。親が動けば子も動くようにしたいので、このtoCompは時間指定しません。

■手順2
次に、親1と親2での親子レイヤー交換です。

やることはかわらないのですが、ちょっと事前準備が必要になります。手順1では子のレイヤー座標を得るためのfromCompの引数にvalueを使えたのですが、現状の子の位置は手順1内の計算結果なので、valueを使えません。
なので、手順1内の計算結果を使います。ただし、手順1の最後のtoCompは時間指定していないものなので、親2のマーカー時間を指定したバージョンを作って使います。

手順1の最後のtoComp
mNul1.toComp(mValNul1LyrCrd);
手順2の最初のtoComp
mNul1.toComp(mValNul1LyrCrd ,mAltTime );

あとは手順1と同じ要領で追従処理をするだけです!

■その他
手順1と2が時間によって切り替わるよう、if(time < mInitTime)やif(time < mAltTime)のif文で分岐させてあります。

*追記
作り終わってテストしているときに「なんで子レイヤーをアニメーションさせても大丈夫なんだろうか?」と思いまして、検証してみました。その結果、〇〇.toComp(座標[XY],時間T)の意味するところは「〇〇レイヤーの時間Tのところで座標[X,Y]を変換する」という意味のようです(fromCompも一緒)。
つまり、時間指定した場合、
「〇〇レイヤーの座標値がアニメーションしていても、時間指定してるので結果値は変わらない」
「しかし、座標[X,Y]がアニメーションしていたら結果値は変わる」
ということみたいです。

つまり、今回の処理に照らし合わせると「特定時間(マーカー時間)の子のレイヤー座標を得て、それを現在時間のコンポ座標に変換する」「子がアニメーションしてると、その都度、得た特定時間レイヤー座標も変わってしまう」「しかし、連続的に変化するので、むしろ子レイヤーを動かせるようになり、好都合」という感じです。

めちゃめちゃややこしいですね…自分で書いてて「何を書いてるんだ?」となりました。しかし偶然、いい感じになりました。「toComp(座標、時間)やfromComp(座標、時間)を使ってるのに値が変化しちゃうんだけど?」となったときは、このことを思い出すのもよいやもです。

■さらなる発展
テストしていませんが、以下のような実装方法でもっと使いやすくなったり、目的に沿うものになるやもです。
toWorldとfromWorldにしてみる。
マーカーを親ではなく子に付け、マーカー名で管理する。
親1に再び戻す処理にしてみる。
親レイヤーをエクスプレッション制御で得る。
マーカーではなくインポイント、アウトポイントにする。
手順2を増やしてさらに何度も親レイヤー交代できるようにしてみる。
などなど。

以上です!ぜひともお試しください!




よかったらシェアしてね!
  • URLをコピーしました!