複数のレイヤーをランダムに配置しましょう。
レイヤー、散らばらせたいですよね。混沌をコントロールするアイディアです。
ではエクスプレッションを考えるために、どんな仕掛けにしたいかを言葉にしてみます。
- コントロールレイヤーで一括管理したい
- 2Dでも3Dでも散らかしたい
- ランダム具合を調整したい
- レイヤー単体の位置で微調整もしたい
- とにかく散らかしたい
X,Y,Zの値をランダムで変更する統括コントローラーでできそうです。
言葉を式に変換していく
コントローラーを準備
ではまずコントローラー用のヌルを置きます。「ランダムコントローラー」とリネームします。
X,Y,Z位置用に対応する3Dスライダー制御エフェクトを「ズレ」という名前で追加しておきます。
配置用レイヤーの位置のエクスプレッション
メインの配置部分です。
散らばらせたいレイヤーを準備し、一旦3Dレイヤーにします。
次元の多い3D用にエクスプレッションを作れれば、2Dに減らす方が簡単なので面倒な方でまず進めます。
例ではwiggle()使います。
random();というランダムな値を生成する関数もあるのですが、0基準となり、位置にぶち込むと考えるとレイヤー単体の位置微調整に「+value」など少~しエクスプレッションが面倒になります。
本当に少しですが、値が
wiggle(0,3Dポイント制御のX値);と「1秒間に何回揺れるか」を0にすればランダムに揺らす数値が受け取れますが、そもそもレイヤーの位置を基準に揺れの大きさが返るので「+value」要りません。好みによりwiggle()で強行します。
random()が好きな方はこちらでもいいです。
さぁ!
var ctrl=thisComp.layer("ランダムコントローラー");
var fx=ctrl.effect("ズレ")(1);
x=wiggle(0,fx[0]);
y=wiggle(0,fx[1]);
z=wiggle(0,fx[2]);
[x[0],y[1],z[2]];
配置できました。
3Dポイント制御のX,Y,Zの値をそれぞれwiggle()に入れ、位置にぶち込みます。
wiggle()はエクスプレッションを記述しているプロパティに対応した次元で返ってきてしまうので、x,y,zそれぞれに位置用の3次元の値が入ります。([960,540,0]など)
なので最終的にx[0]、y[1]、z[2]とそれぞれ対応する次元だけを取り出しています。
2Dレイヤー時も対応するようにエクスプレッションを改善
2Dレイヤーにするとエラーが出るので、ボーナスとして2Dレイヤー状態でのエラー回避の処理を追加します。別に2DレイヤーにしないでZは常に0で使用する方はスキップ可能です。
var ctrl=thisComp.layer("ランダムコントローラー");
var fx=ctrl.effect("ズレ")(1);
var x=wiggle(0,fx[0]);
var y=wiggle(0,fx[1]);
var z=wiggle(0,fx[2]);
if(position.value.length==2){
[x[0],y[1]];
}else{
[x[0],y[1],z[2]];
}
if文で位置の値が何個あるか(.length)で2Dレイヤーか3Dレイヤーか判断できますので、2Dのときは2次元の値を、3Dのときは3次元の値を返してやればエラーが出ません。
シード値を変更できるようにする
今回の例ではコントローラーにスライダー制御をさらに追加し、「シード値」にリネームして使います。
配置レイヤーの位置のエクスプレッションには、
seedRandom(ctrl.effect("シード値")(1)+index, true);
これを追加して使います。
配置するレイヤーのシード値を統一させると同じランダム具合になって同じ位置に配置されてしまうので、レイヤーのindexをプラスしてズラします。
完成
これらを繋げば完成です。
全配置レイヤーの位置に記述するエクスプレッション
var ctrl=thisComp.layer("ランダムコントローラー");
var fx=ctrl.effect("ズレ")(1);
seedRandom(ctrl.effect("シード値")(1)+index, true);
var x=wiggle(0,fx[0]);
var y=wiggle(0,fx[1]);
var z=wiggle(0,fx[2]);
if(position.value.length==2){
[x[0],y[1]];
}else{
[x[0],y[1],z[2]];
}
random()を使うパターン例も
var ctrl=thisComp.layer("ランダムコントローラー");
var fx=ctrl.effect("ズレ")(1);
seedRandom(ctrl.effect("シード値")(1)+index, true);
var x=random(-fx[0],fx[0]);
var y=random(-fx[1],fx[1]);
var z=random(-fx[2],fx[2]);
if(position.value.length==2){
[x,y]+value;
}else{
[x,y,z]+value;
}
今回覚えるエクスプレッション
今回新しく学べるエクスプレッションは
seedRandom();// シード値を指定
random();//乱数を生成
既に優れた解説記事があるのでスキップして調べてもらってもOKです。
↓一応書いておきます。
seedRandom()で「シード値」を指定できます。
プログラムにはランダム具合を決定する「乱数(ランダムの値)の発生に使う変数」を指定できる「シード値」があります。
「乱数の発生に使う変数」を「種」という表現で「シード値」といいます。
仕組みとしては再生する度にランダム具合が変わってしまうと都合が悪い場合が多いため、シード値を決定する条件を固定するという考えです。大体のプログラムにあります。
ゲームでは「宝箱の中身がランダムに変わる」ようなシチュエーションで、シード値の選択ルールが「歩数」となっている作品であればRTA時に有利なアイテムが手に入るルート取りなどが可能です。決まった歩数目で宝箱を開けば同じアイテムが手に入ります。
逆に電源を入れた際にランダムでシード値が選択されるゲームは狙いようがないので宝箱から欲しいアイテムが出なければリセットをするという地獄が待っています。
After Effectsではrandom()、wiggle()などでシード値が使われます(他にもありますか?)。逆に任意のシード値に変えられれば、ランダムな値のランダム具合を簡単に変更可能です。
seedRandom()でできます。random()やwiggle()の「前」に宣言して使います。
引数が2つ必須で、
seedRandom([シード値], [時間で変化させない?→trueかfalse]);
と使い、2つめの引数は筆者の使い方では時間経過でシード値が変わると使いにくいことが多いので基本trueです。
random();
引数に何も指定しないと0~1までの小数点を含む数を毎フレームランダムに生成します。
seedRandom([数値],true);を使うとフレームが変わっても更新を止められます。
引数は2個まで指定でき、
random([最大値]);かrandom([下限値],[上限値]);と使えます。
是非真似して見てください。インプットしただけではその瞬間理解しただけで、いざアウトプットするときに結局調べ直すことになりますので、アウトプットまでをセットで行い、脳に定着させていって欲しいと思います。
この記事へのコメントはありません。