🔫
ワールドクラフトで弾を撃つ(音もでる)
ワールドクラフトで弾を撃てるスクリプトです。
音もでます(下のはアニメGIFなんで音は鳴っていませんが)。
撃った後にプレイヤーが移動してもそのままの軌道で飛び続けてくれます。
unitypackage
cluster公式さんの「テンプレートワールド」など、クラフトアイテムをアップロードできる状態のUnityのプロジェクトに読み込んでください。
モデル・マテリアル・スクリプト・音声などなど、改変はお好きにどうぞ~
https://vins-jp.sakura.ne.jp/pack/wc_bullet.unitypackage
基本に自信がない人は
クラフトアイテムアップロードの基本はこの記事を。
スクリプトの基本はこの記事を。
スクリプト全文
弾を撃つ距離を長くしたい方はbulletLifeを、スピードを変えたい方はbulletSpeedをいじってください。
持った部分がクルクル回転する要素が要らなければgrabObjRotSpeedを0にするのが手っ取り早いです。関係するコードを消してもいいですが。
const bulletNum = 3;
const bulletsAr = [];
for (let bulletNo = 0; bulletNo < bulletNum; bulletNo++) {
bulletsAr.push($.subNode("Bullet" + bulletNo));
}
const grabObj = $.subNode("GrabObj");
const grabObjRotSpeed = 360;
const audioNum = 1;
const audioAr = []
for (let audioNo = 0; audioNo < audioNum; audioNo++) {
audioAr.push($.audio("Audio"+audioNo));
}
const bulletLife = 0.5;
const bulletSpeed = new Vector3(0, 0, 20);
const defBulletPos = new Vector3(0, 0.85, 0);
const initProc = () => {
$.state.initialized = true;
for (let bulletNo = 0; bulletNo < bulletNum; bulletNo++) {
bulletsAr[bulletNo].setEnabled(false);
}
$.state.firstPos = $.getPosition();
$.state.firstRot = $.getRotation();
$.state.grabObjRotZ = 0;
$.state.currentBulletNo = 0;
};
$.onUse((flag) => {
if (!flag)
return;
let result = false;
for (let bulletNo = 0; bulletNo < bulletNum; bulletNo++) {
if (ShootProc(($.state.currentBulletNo + bulletNo)%bulletNum)) {
$.state.currentBulletNo = ($.state.currentBulletNo+1)%bulletNum;
result = true;
break;
}
}
if (!result)
return;
audioAr[0].play();
}
);
const ShootProc = (no) => {
if ($.state[no*4])
return false;
const rot = $.getRotation();
bulletsAr[no].setEnabled(true);
$.state[no*4] = true;
$.state[no*4+1] = $.getPosition().add(defBulletPos.clone().applyQuaternion(rot)); //ワールド座標で管理
$.state[no*4+2] = bulletSpeed.clone().applyQuaternion(rot);
$.state[no*4+3] = 0.0;
return true;
}
const BulletProc = (no,rotInv,parentPos,deltaTime) => {
if (!$.state[no*4])
return;
$.state[no*4+3] += deltaTime;
if ($.state[no*4+3] >= bulletLife) {
bulletsAr[no].setEnabled(false);
bulletsAr[no].setPosition(defBulletPos); //初期位置はローカル座標そのままでOK
$.state[no*4] = false;
return;
}
//ワールド座標で加算していく
const pos = $.state[no * 4 + 1].add($.state[no * 4 + 2].multiplyScalar(deltaTime));
$.state[no * 4 + 1] = pos;
//親の座標を引いたものに反転したクォータニオンをかけるとローカル座標になる
const localPos = pos.sub(parentPos).applyQuaternion(rotInv);
bulletsAr[no].setPosition(localPos);
}
$.onUpdate(deltaTime => {
if (!$.state.initialized) {
initProc();
}
const rotInv = $.getRotation().invert();
const parentPos = $.getPosition();
for (let bulletNo = 0; bulletNo < bulletNum; bulletNo++) {
BulletProc(bulletNo,rotInv,parentPos,deltaTime);
}
$.state.grabObjRotZ += deltaTime * grabObjRotSpeed;
grabObj.setRotation(new Quaternion().setFromEulerAngles(new Vector3(0, 0, $.state.grabObjRotZ)));
}
);
Discussion