【エクスプレッション】インデックス系エクスプレッションをかんたんに3D対応化

もしかしたら、苦労して作ったインデックス整列エクスプレッションをかんたんに3D対応にできるかもしれません。

以下は『インデックス系エクスプレッションでよく使う式』を参考にしつつ作った例です。なるべく多くの調整をエクスプレッション制御でできるようにしてあります。

■円状整列
まず、各レイヤーの位置パラメータで微調整できる仕様にしてあるので、各レイヤーの位置を[0,0]にする。
各レイヤーを『ヌル 1』と『ヌル 2』ではさみ、
『ヌル 1』に『スライダー制御』1つ『角度制御』2つを適用して、
各レイヤーの『位置』プロパティに以下のエクスプレッションを適用。

function mGetRotPt ( aStdPt , aRot , aLgt ){
	//aRotそのままだと、ゼロ度で横方向への位置となるので、上方向始まりとなるよう-90する。
	var mDtoR = degreesToRadians( aRot - 90 );
	var X = Math.cos( mDtoR ) * aLgt;
	var Y = Math.sin( mDtoR ) * aLgt;
	return ([X,Y] + aStdPt);
}

mCtrlF = thisComp.layer("ヌル 1");
mCtrlL = thisComp.layer("ヌル 2");
mActIdx = index  - mCtrlF.index;
mActNumLyrs = ( mCtrlL.index - mCtrlF.index ) -1;

mRotDiv = mCtrlF.effect("角度制御 2")("角度");
mRot = ( mRotDiv / mActNumLyrs ) * ( mActIdx - 1 );
mRotAdd = mCtrlF.effect("角度制御")("角度");
mLgt = mCtrlF.effect("スライダー制御")("スライダー");
//ヌル 1が親子になっていたとき対策。アンカーポイントから位置を得る。
mStdPt = mCtrlF.toWorld(mCtrlF.anchorPoint);
mRstPt = mGetRotPt ( mStdPt , mRot + mRotAdd , mLgt )+ value;

■XY整列
まず、各レイヤーの位置パラメータで微調整できる仕様にしてあるので、各レイヤーの位置を[0,0]にする。
各レイヤーを『ヌル 1』と『ヌル 2』ではさみ、
『ヌル 1』に『スライダー制御』3つを適用して、
各レイヤーの『位置』プロパティに以下のエクスプレッションを適用。

mCtrlF = thisComp.layer("ヌル 1");
mCtrlL = thisComp.layer("ヌル 2");
mActIdx = index  - mCtrlF.index;
mActNumLyrs = ( mCtrlL.index - mCtrlF.index ) -1;

mDivNum = mCtrlF.effect("スライダー制御")("スライダー");
mMtplNum1 = mCtrlF.effect("スライダー制御 2")("スライダー");
mMtplNum2 = mCtrlF.effect("スライダー制御 3")("スライダー");

X = ((mActIdx - 1)  % mDivNum) * mMtplNum1;
Y = ( Math.floor( (mActIdx - 1 ) / mDivNum ) ) * mMtplNum2;

mLgtSumX = ( mMtplNum1 * ( mDivNum - 1 ) ) / 2;
mLgtSumY = (( Math.floor( (mActNumLyrs - 1 ) / mDivNum ) ) * mMtplNum2) / 2;

//ヌル 1が親子になっていたとき対策。アンカーポイントからヌル 1の位置を得ている。
mRstPt = mCtrlF.toWorld(mCtrlF.anchorPoint) + [X,Y] - [mLgtSumX,mLgtSumY] + value;

方法

もしも、作ったエクスプレッションが例のように『ヌルが移動すれば連動して各レイヤーも動く仕様』となっていれば、最後に以下の式を加えればかんたんに3D対応化可能です。

ヌル.toWorld( 結果の値 - ヌル.toWorld( ヌル.anchorPoint ));

例の場合は以下となります。

mCtrlF.toWorld( mRstPt - mCtrlF.toWorld( mCtrlF.anchorPoint ));

これで、各レイヤーとヌルを3D化すれば「ヌルが3D回転、スケールしても追従する」エクスプレッションとなります!

  • もしも作ったエクスプレッションの最後が『〇〇+××』などの式やメソッドになっているならば『変数 = 〇〇+××』と書き換え、その変数を『結果の値』のところに当てはめればOKです。
  • もしも全体の位置移動を『ポイント制御』などにしている場合は、そこを『ヌルの位置』で制御する形に変えればOKです。

使いどころ

インデックス系エクスプレッションを作るのは一苦労です。3D対応化なると「…めんどくさいから別の機会に」となるかと思います。そんなときにお使いください。

解説

やっていることは

  • 結果の値(整列させた後のレイヤーの位置)からヌルの位置を引けば、ヌルを[0,0]とした座標となる。
  • その座標はレイヤーの『ヌルのレイヤー座標基準での位置』と解釈できる。
  • ならばそれを『ヌルのレイヤー座標基準での位置』としてtoWorld関数に入れれば、ヌルがスケールや回転したらヌルのレイヤー座標もスケールや回転するので、それを考慮したワールド座標が得られる。

ということです。

ヌル.toWorld( 結果の値 - ヌル.toWorld( ヌル.anchorPoint ));

座標とその変換に関してはアンカーポイントで学ぶ座標系toCompメソッドはなぜややこしい?の記事が理解の助けになるやもです。

*注意点
ヌルとレイヤーの位置関係を参照、変換しているため『ヌルが動けばレイヤーも追従して動く』仕様ではない場合は意図した動きになりません。場合分けを以下に記しますが、込み入っているので「この方法が使えたらラッキー」くらいでよいかと思います。

  • 例えば『全体移動にポイント制御などを使っている』場合、各レイヤーはヌル位置を基準にスケールや回転が追従しますが、ヌルの移動には追従しません。「ヌルを動かせばスケールや回転のピンも移動してしまう」というイメージです。
  • また『レイヤー位置(value)そのものをヌル位置と関連させずに参照している、あるいはレイヤー位置(value)をヌルの位置と関連させずに整列位置の割り出しに使っている』場合、ヌルやレイヤーを動かせば位置関係も変わってしまうため、toWorldに意図した値が入らず意図通りの3D対応になりません。

例では微調整のためにvalueを使っていますが、これは問題ありません。ヌルとレイヤーの位置を関連させた整列位置割り出しを行った後に、そこ基準で単純に微調整+ーするための欄として使っているので、ヌルを動かせばレイヤーも同じように動く仕様は変更されていないから大丈夫、ということです。

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