🌨️

【clusterスクリプト】雪的なものが落ちてくる

2022/12/22に公開約3,300字

ワールドクラフトで雪的なものが落ちてくるやつです。
今回は雑解説です。

基本に自信がない人は

クラフトアイテムアップロードの基本はこの記事を。
スクリプトの基本はこの記事を。

雪っぽい白い球を4つほど準備



まずこんな風に、空(から)のオブジェクトの子に4つほど白い球(スフィア、Sphere)を付けてあげます。

スクリプト

それでは空のオブジェクトにScriptableItemを追加し、スクリプトを付けます。

長いように見えますが、途中からは同じことのくり返しです。

const snowA = $.subNode("snowA");
const snowB = $.subNode("snowB");
const snowC = $.subNode("snowC");
const snowD = $.subNode("snowD");

const snowVec = new Vector3(0,-1,0);
const groundY = 0;
const skyY = 8;

$.onUpdate(deltaTime => {
	let pos = snowA.getPosition();
	if(pos.y < groundY) {
		snowA.setPosition(new Vector3(pos.x,skyY,pos.z));
	} else {
		snowA.setPosition(pos.add(snowVec.clone().multiplyScalar(deltaTime)));
	}
	
	pos = snowB.getPosition();
	if(pos.y < groundY) {
		snowB.setPosition(new Vector3(pos.x,skyY,pos.z));
	} else {
		snowB.setPosition(pos.add(snowVec.clone().multiplyScalar(deltaTime*1.1)));
	}

	pos = snowC.getPosition();
	if(pos.y < groundY) {
		snowC.setPosition(new Vector3(pos.x,skyY,pos.z));
	} else {
		snowC.setPosition(pos.add(snowVec.clone().multiplyScalar(deltaTime*0.9)));
	}

	pos = snowD.getPosition();
	if(pos.y < groundY) {
		snowD.setPosition(new Vector3(pos.x,skyY,pos.z));
	} else {
		snowD.setPosition(pos.add(snowVec.clone().multiplyScalar(deltaTime*1.2)));
	}
});

配列や関数を使えばもっとエレガントな書き方もできますが、今回は力業にしました。

各パートの説明

今回は雑説明ですが、いちおうやります。

const snowA = $.subNode("snowA");
const snowB = $.subNode("snowB");
const snowC = $.subNode("snowC");
const snowD = $.subNode("snowD");

まず事前準備として4つの球にアクセスできるように $.subNodeを使って準備。

const snowVec = new Vector3(0,-1,0);
const groundY = 0;
const skyY = 8;

動くスピードの基本は、下方向に毎秒1。
「これ以上下にいったら上に戻る」の数字を0、「上に戻るときの高さ」を8に設定。

$.onUpdate(deltaTime => {

「毎フレーム処理をする」は $.onUpdateって奴から始めるんでしたね。
前回の記事で解説しました。

	let pos = snowA.getPosition();
	if(pos.y < groundY) {
		snowA.setPosition(new Vector3(pos.x,skyY,pos.z));
	} else {
		snowA.setPosition(pos.add(snowVec.clone().multiplyScalar(deltaTime)));
	}

現在の雪の位置をゲット、もし指定位置より(Yが)下に行っていたらXとZはそのままに、Yを高い位置に戻します。
そうでなければ(elseというのはそうでなければという意味)、雪の位置を少しずつ下に下げます。

雪の現在位置 + snowVec(動くスピード) × deltaTime(経過時間)
ここにsetPositionで雪の位置を動かしてしまうわけです。

あとは雪の玉の数だけ同じ事をsnowB・snowC・snowDで繰り返しています(配列とか関数とかいうテクニックを覚えると、もうちょっとカッコよく短く書けます)。

まとめ

  • まず $.subNodeで子のアイテム(今回は雪の玉)にアクセスできるようにする
  • $.onUpdateで毎フレーム処理(今回なら移動)ができる
  • ifで条件チェックができ、 elseで「そうでなければ」 の処理ができる
  • Vector3を使う一時的な計算のときは、clone()を使わないと元の値(今回は移動スピード)が変わってしまう
  • 配列や関数というのを使うと、雪の玉の数だけ長い処理を繰り返す必要はなくなる! (今回は使っていませんが)

Discussion

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