👀

8の字で動くclusterスクリプト

2022/10/27に公開約3,900字

突発イベントでやった、8の字で動くclusterスクリプトの解説。
ちょっとイベントgdったんでここで補完できれば。。。

ここではonUpdate系を使い、面白い動きをさせるスクリプトの説明をします!

どんな動きか? +ダウンロード

https://twitter.com/vins_cluster/status/1585624504562511874
動きはこんな感じ、ただ後でもっと光らせたほうがいいと思ったのでプロジェクトではより白く光るようになってます。

プロジェクトはこちらからダウンロード可能です。
https://vins-jp.sakura.ne.jp/zip/clusterMovingTestPack.zip

スクリプトの中身は?

moving.js
$.onUpdate(deltaTime => {
	if (!$.state.isInitialized) {
		$.state.tick = 0;
		$.state.firstPos = $.getPosition();
		$.state.isInitialized = true;
	}

	$.state.tick += deltaTime;
	let pos =
		new Vector3($.state.firstPos.x + Math.sin($.state.tick / 2),
		$.state.firstPos.y + Math.sin($.state.tick) ,
		$.state.firstPos.z);
	$.setPosition(pos);
}
);


さて、付いているのはこんなスクリプトです。
(イベント中firstPosに$.state.を付け忘れているミスがあってスミマセン……)

常にコピペでいい部分!

moving.js
$.onUpdate(deltaTime => {
	if (!$.state.isInitialized) {
		$.state.tick = 0;
		$.state.firstPos = $.getPosition();
		$.state.isInitialized = true;
	}

	$.state.tick += deltaTime;

イベント中も強調しましたが、何かを動かしたいならここまでは毎回コピペでいいです!

コピペ重要

スクリプトの中身と、超重要な知識

● $.onUpdate(deltaTime => {
→毎フレーム(超細かい間隔で)何かをしたいなら毎回ここをコピペ!

$.state. を使うと、データが勝手に書き換わらない。
→これをやらないと、数分に1回くらいデータがリセットされる?

●if (!$.state.isInitialized) {
※ここからの部分もコピペでいいです!
→「もし(if)まだ初期化がされていなかったら……」
(!がついていると「~~ない」という否定に!)

→「秒数カウント($.state.tick)を0に」
→「初期位置($.state.firstPos)を記録
$.getPosition()で現在位置がゲットできる)
→「初期化が済んだこと(
$.state.isInitialized
)を記録しておく」
trueは真、つまり「そうだよ」という意味! 初期化済んでるよ、ということ!)

(※当然、どれも$.state.を付けておいて、勝手にデータが書き換わらないようにしておく)


●とても大事なdeltaTime
→(deltaTimeには前回から何秒経過したかが入っている。普通は0.016秒とか0.033秒とかすごい短い時間)
→これを.state.tickに毎回足していく(+=を使う)。すると **.state.tick** には、ワールドに入ってからの経過時間 がずっと記録される
→この$.state.tickを「三角関数」などにブチこんでいくのがスクリプトの黄金パターン!

●スクリプトの終わり(正確にはonUpdateの終わり)

moving.js
}
);

あと、終わりのここの部分もコピペでいいですね。

オリジナリティが出る、位置計算の部分

moving.js
	let pos =
		new Vector3($.state.firstPos.x + Math.sin($.state.tick / 2),
		$.state.firstPos.y + Math.sin($.state.tick) ,
		$.state.firstPos.z);
	$.setPosition(pos);

ここは書く人のオリジナリティが出る部分です! 今回は8の字の形に動かします。


●let pos =
→「 let 」というのは一時的にデータ保存したいんでハコ(変数)を用意してね、という意味!
→なお、名前は「 pos
→「 Vector3 (x・y・zを保存できる)」のハコ(変数)を一時的に作ってくれよ!

●そのときxは、最初に保存しておいた初期位置($.state.firstPos)のxに三角関数の Math.sin を足そう!
(ここで三角関数には、 $.state.tick 、ワールド入ってからの経過時間をぶちこむ!)
→ちなみに三角関数のsinは0から始まって、1と-1の間をなめらかに行ったりきたりするよ!
→だから 初期位置からxが1だけ右にいったり、1だけ左にいったりするよ!
→ただしその行ったりきたりのスピード(周期)は2で割って半分にしちゃえ!( / で割り算)


●yも同じ感じ、ただし行ったりきたりのスピード(周期)はそのままいくよ!
→これによってxとyの動きが微妙にズレて8の字っぽくなる!

●zは初期値と同じでいい、動かなくていいよ!

最後に位置を変更

●最後に、posに入れたVector3(xyzのセット)を使って位置を変更しろ($.setPosition)!
→これで、球の位置が変わります!

●しかもonUpdateを使っているので、0.016秒とか0.033秒とかすごく短い間隔で位置が変わる! だから滑らかに見える!(まあ他のプレイヤーから見ると微妙にカクカクはするのですが……)

改造例

moving_kaizou.js
$.onUpdate(deltaTime => {
	if (!$.state.isInitialized) {
		$.state.tick = 0;
		$.state.firstPos = $.getPosition();
		$.state.isInitialized = true;
	}

	$.state.tick += deltaTime;
	let pos =
		new Vector3(Math.random()*Math.sin($.state.tick),
		Math.random()*Math.sin($.state.tick),
		$.state.firstPos.z);
	$.setPosition(pos);
}
);

xとyの決め方だけ変更した改造例。

ランダムな数値(Math.random())を入れているので、荒ぶります!
そこに-1から1まで行ったり来たりする三角関数を「掛けて」いる(なぜか*がかけ算です)。
これによって、荒ぶる→落ち着くという動作を繰り返します!

わからなくてもいいです!

わからなくても別にいいです!
ただこれをコピペして、ちょっと途中で出てきた /2 を /4 に変えるとかしているうちに、段々わかってくると思います!


最後に、deltaTimeは大事!
それを$.state.tickに足していくのはもう使いまくるんで、毎回書いちゃってください!

Discussion

ログインするとコメントできます