【clusterスクリプト】パーツが動くクラフトアイテム
こんな感じで、パーツが動くクラフトアイテムです。
なおオリジナルのものを作るとき、クラフトアイテムは「メッシュが8種類まで」「マテリアルが2つまで」という制限があることにも注意しましょう。
クラフトアイテムのパッケージ
カプセル
https://vins-jp.sakura.ne.jp/pack/capsule.unitypackage
ウサギ
https://vins-jp.sakura.ne.jp/pack/usagi.unitypackage
まずはclusterのテンプレートワールドをダウンロード・MinimalSampleシーンなどを開きましょう。
そしてダウンロードしたunitypackageをUnityにドラッグアンドドロップして追加してください。
この記事では、よりシンプルな「カプセル」のunitypackageのほうを使って説明していきます。
カプセルアイテムの構造
このように、Itemの子にbodyとhandRとhandLがあります。体と両手ですね。
スクリプトは?
ScriptableItemの「capsule_move」をクリックするとスクリプトの場所に飛べる。テキストエディタなどで閲覧しましょう
まず前半の基本構造から見ていきます。
const TICK_MAX = 2.0;
const body = $.subNode("body");
const handL = $.subNode("handL");
const handR = $.subNode("handR");
ここでは、「全体を何秒で繰り返すか(今回は2秒)」と、体のパーツ(subNode)を登録しています。
$.onStart(() => {
$.state.tick = 0;
});
$.onUpdate((deltaTime) => {
$.state.tick += deltaTime;
if ($.state.tick > TICK_MAX) {
$.state.tick -= TICK_MAX;
}
bodyProc();
handLProc();
handRProc();
});
さて、ここがメインパートですが、やっていることは
- 毎フレーム $.state.tickを、経過時間(deltaTime)だけ増やしていく
- 一定秒数(今回は2秒)過ぎたら最初に戻る
- 各パーツの処理を呼び出す
だけです。キモはbodyProcなどの各処理(と、本当はその先にも)にあるわけですね。
パーツの処理
体のパーツの処理を見てみます。
const bodyPos = [new Vector3(0, 0.5, 0), new Vector3(0, 0.65, 0), new Vector3(0, 0.45, 0)];
const bodyTick = [0, 0.5,1.5, TICK_MAX];
const bodyProc = () => {
setPos(body, bodyPos, bodyTick);
};
なんだかよくわからないかもしれません。
- bodyPosは、体の位置の移り変わりの内容
- bodyTickは、何秒のタイミングで動きが切りかわるか
- bodyProc、これが$.onUpdateから呼び出されているわけです。でも、やっていることはsetPosを呼び出すだけ(bodyは序盤で登録したsubNodeですね)
ということになります。
実は、メインの処理をしているのはもっとずっと後にあるsetPos関数です。ですが、その中身はだいぶややこしいので理解しなくてかまいません!
さて、もう少しデータを見ていきましょう。bodyPosは良く見るとVector3の2番目の数字、つまりY(上下)しか変わっていないことがわかります。0.5→0.65→0.45ですから、少しあがって、少し下がるわけですね。
つづけてbodyTickを見ると、「0.5秒、1.5秒」のタイミングで動きが切りかわることがわかります(TICK_MAXは序盤に登録した2.0秒)。
時間 | 処理 |
---|---|
0秒~0.5秒 | Yを0.5→0.65に |
0.5秒~1.5秒 | Yを0.65→0.45に |
1.5秒~2.0秒 | Yを0.45→0.5(元の数字に) |
という処理であることがわかります。
基本はこれだけです!
回転のほうの処理
handL、左手のほうも見てみましょう(右手もほとんど同じ)。
const handLRot = [new Vector3(0, 0, 0), new Vector3(0, 0, 20), new Vector3(0, 0, -10)];
const handLTick = [0, 0.6,1.6, TICK_MAX];
const handLProc = () => {
setRot(handL, handLRot, handLTick);
};
今度はsetRotという関数を呼び出しています。回転させたいからですね。
handLRotは、Vector3の3番目の数字、つまりZが変わっています。パーツの配置によって色々変わってきますが、今回はZの値が「手を上下」させる回転に当たるのです。
時間 | 処理 |
---|---|
0秒~0.6秒 | 回転Zを0→20に |
0.6秒~1.6秒 | 回転Zを20→-10に |
1.6秒~2.0秒 | 回転Zを-10→0(元の数字に) |
なお、ここでの回転は0~360度で表現される数字です。算数とか数学で習ってきた、一番メジャーな角度の表現方法ですね。
他の部分は?
別に理解しなくてもいいです!
setPosとsetRotを使い、そこに適切なデータをあげるだけで問題ありません。
ウサギのほうはスクリプトがもっとフクザツ(パーツが多いので……)ですが、結局やっていることは全然変わりません。
位置を動かす時ただ一定のペースで動かすのではなく滑らかにする 、特に書かなくても最後は位置や回転を初期値に戻す、などの処理も加えていますが、そういう部分を理解するのはもっと先でかまいません。
まずは用意された関数を使って改変することに慣れてください。それだけでもかなり大変だと思うので……
Discussion