🛹

ワールドクラフトで振り子運動

2023/02/01に公開

ワールドクラフトで振り子運動です。
回転させて置いたときの処理がいまいちイケてない気もしますが、まあいいことにします。
(※一度乗った後でやっぱり位置を回転させたい、という場合は一度削除してから再設置してください)

unitypackage

cluster公式さんの「テンプレートワールド」など、クラフトアイテムをアップロードできる状態のUnityのプロジェクトに読み込んでください。
モデル・マテリアル・スクリプトなどなど、改変はお好きにどうぞ~

https://vins-jp.sakura.ne.jp/pack/wc_furiko.unitypackage

基本に自信がない人は

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

これまでとの違い

今回はアイテムそのものを動かすので、子アイテムの構造はあまり気にしなくてもいいです。
乗れるアイテムにしたほうが楽しいと思うので、結果的に子アイテムは作る必要が出てきそうですが。

オマケ

なんかスロープっぽいアイテムがオマケで入っています。

逆側のスロープは180°回転して置いてください。コライダーは凸状なのでなんか微妙に足が浮きます

スクリプト全文

青い方(左右に動く方)です。
前後に動かしたい場合はisXMoveをfalseに、isXRotをtrueにしましょう。
あとは適宜数字を調整してください。

const furikoSpeed = 0.25 * Math.PI;

const isXMove = true; //falseならZ方向に動く
const isXRot = false; //falseなら回転のZが傾く

const XZTimes = 8.0; //マイナスにすれば最初に動く方向が変わる
const YTimes = 8.0;
const rotTimes = 30.0; //どれくらい乗りものが傾くか

$.onUpdate((deltaTime) => {
	if (!$.state.initialized || !$.state.isRiding) {
		return;
	}

	$.state.tick += deltaTime * furikoSpeed;

	const sinVal = Math.sin($.state.tick);
	const currentY = $.state.firstY - Math.cos(sinVal) * YTimes;
	if (isXMove) {
		const currentX = $.state.firstX + Math.sin(sinVal) * XZTimes;
		$.setPosition(new Vector3(currentX, currentY, $.state.firstZ));
	} else {
		const currentZ = $.state.firstZ + Math.sin(sinVal) * XZTimes;
		$.setPosition(new Vector3($.state.firstX, currentY, currentZ));
	}

	if (isXRot) {
		$.setRotation(new Quaternion().setFromEulerAngles(new Vector3($.state.firstRotX, $.state.firstRotY, $.state.firstRotZ - sinVal * rotTimes)));
	} else {
		$.setRotation(new Quaternion().setFromEulerAngles(new Vector3($.state.firstRotX - sinVal * rotTimes, $.state.firstRotY, $.state.firstRotZ)));
	}
});

$.onRide((flag) => {
	if (flag && !$.state.initialized) {
		$.state.tick = 0;
		$.state.firstPos = $.getPosition();
		$.state.basePos = $.state.firstPos.add(new Vector3(0, YTimes, 0));
		$.state.firstX = $.state.basePos.x;
		$.state.firstY = $.state.basePos.y;
		$.state.firstZ = $.state.basePos.z;
		$.state.baseRot = $.getRotation().createEulerAngles();
		$.state.firstRotX = $.state.baseRot.x;
		$.state.firstRotY = $.state.baseRot.y;
		$.state.firstRotZ = $.state.baseRot.z;

		$.state.initialized = true;
	}
	if (!flag) {
		$.setPosition($.state.firstPos);
		$.setRotation($.state.baseRot);
		$.state.tick = 0;
	}
	$.state.isRiding = flag;
});

Discussion