xrift-range
v0.2.1
Published
Shooting-range toolkit for react-three-fiber / WebXR worlds — projectile sim, trigger weapons, targets, hit FX, CJK labels. 射的レンジ構築キット
Downloads
23
Maintainers
Readme
xrift-range
Shooting-range toolkit for react-three-fiber / WebXR worlds — 射的レンジ構築キット。
XRift のワールドに「撃って・当てて・スコアを競う」ミニゲームを組み込むための部品集。 toming工房のシューティングレンジから切り出したもので、縁日射的ワールドの心臓部でもある。
提供するもの
ProjectileStore— 弾のプール+弾道積分。bolt(直進・光線銃)とarc(重力弾道・矢や投擲物、床壁に刺さる)。 rapier不要のスイープ線分判定=速い弾もトンネリングしない。命中判定はコールバックで消費側に委ねるRangeWeapon— トリガー武器の共通ハーネス。xrift-grab での掴み・ 持ち主/置き姿勢のインスタンス同期・VR/デスクトップ両対応の構え・セミオート発射判定・退出者の5秒自動返却。 見た目はchildrenで差し替え(光線銃でもコルク銃でも)useTriggerInput— VRトリガー/マウスの入力ref(DcPen方式)HitBursts— 命中演出の発光リングプール(完全ref制御・state更新ゼロ・常に視線正対ビルボード)ControllerRayHider— VRで武器を握っている手のコントローラーレイを消す(射線との誤認防止)。RangeWeaponには組み込み済み(hideControllerRay={false}で無効化)。XRiftホストの @react-three/xr 実装(target-ray-space配下のBoxGeometryレイ・毎フレームvisible上書き→layersで消す)に 依存するため、ホスト側が変わって見つからないときは何もしない安全設計- 保持中はインタラクト不能化(0.2.1) — 握られている武器は
Interactableをenabled=falseにし、さらにLAYERS.INTERACTABLEレイヤーを外す。ホストのレイビームは このレイヤーに当たる限り描かれるため、これをしないと構えた銃自体に反対の手のホバーレイが 出続ける(レイ非表示は握っている手にしか効かない)。置くと両方復元 RingTargetDisc+ 的の道具箱 — ブルズアイ的・往復運動(壁時計同期=通信なし)・リング得点・ポップ演出係数CjkLabel— CanvasTextureによるCJK/絵文字対応テキスト(フォント同梱不要)playPew/playHit— WebAudio合成の発射音・命中音(音源ファイル不要・距離減衰つき)
同期の設計(重要)
- 発射はイベント1発だけ流し、弾道は各クライアントがローカル再現する(毎フレーム同期しない)
- 命中判定は撃った本人のクライアントだけが行う自己申告方式(サーバー権威なし。カジュアル用途向け)
- スコアは
makeSyncKeys(ns).score(userId)を本人だけが書く=競合しない
インストール
npm i xrift-range xrift-grabnpm公開前はGitHub直依存でも入る:
npm i github:tomingtoming/xrift-range使い方の骨子
const input = useTriggerInput()
const store = useMemo(() => new ProjectileStore(ROOM_BOUNDS), [])
const bursts = useRef<HitBurstsHandle>(null)
const fire = (origin: Vector3, dir: Vector3) => {
store.spawn('bolt', true, origin, dir, 45, performance.now() / 1000)
playPew(0)
emitShot({ ... }) // 消費側のインスタンスイベント
}
<XRGrabProvider>
<RangeWeapon
weaponId="pistol" syncNs="myrange"
home={{ position: HOME_P, quaternion: HOME_Q }}
input={input} onFire={fire}
muzzleLocal={new Vector3(0, 0.083, -0.2)}
viewOffset={[0.17, -0.12, -0.42]}
interactionText="銃をとる(クリックで発射)"
>
<MyGunModel />
</RangeWeapon>
</XRGrabProvider>
<HitBursts ref={bursts} />useFrame内で store.step(dt, now, collide) を回し、collideで的との命中を判定して
bursts.current?.spawn(...) と playHit(...) を鳴らす。完全な実例は
xrift-workshop の ShootingRange を参照。
License
MIT
