@xrift/world-components 0.12.0 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -0
- package/dist/components/SpawnPoint/index.d.ts.map +1 -1
- package/dist/components/SpawnPoint/index.js +32 -11
- package/dist/components/SpawnPoint/index.js.map +1 -1
- package/dist/scenes/SpawnPointTestScene.d.ts +6 -0
- package/dist/scenes/SpawnPointTestScene.d.ts.map +1 -0
- package/dist/scenes/SpawnPointTestScene.js +12 -0
- package/dist/scenes/SpawnPointTestScene.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -479,6 +479,68 @@ function MyWorld() {
|
|
|
479
479
|
- シェーダーを使用した軽量な実装です
|
|
480
480
|
- シーンの背景色も自動的に設定されます
|
|
481
481
|
|
|
482
|
+
### SpawnPoint コンポーネント
|
|
483
|
+
|
|
484
|
+
ワールド内のプレイヤーのスポーン(出現)地点を指定するコンポーネントです。開発時には位置と向きを視覚的に確認できるヘルパーが表示されます。
|
|
485
|
+
|
|
486
|
+
```tsx
|
|
487
|
+
import { SpawnPoint } from '@xrift/world-components'
|
|
488
|
+
|
|
489
|
+
function MyWorld() {
|
|
490
|
+
return (
|
|
491
|
+
<>
|
|
492
|
+
{/* 原点にスポーン、正面向き */}
|
|
493
|
+
<SpawnPoint />
|
|
494
|
+
|
|
495
|
+
{/* 位置と向きを指定 */}
|
|
496
|
+
<SpawnPoint position={[0, 0, 5]} yaw={180} />
|
|
497
|
+
</>
|
|
498
|
+
)
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### Props
|
|
503
|
+
|
|
504
|
+
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|
|
505
|
+
|-----------|-----|------|-----------|------|
|
|
506
|
+
| `position` | `[number, number, number]` | - | `[0, 0, 0]` | スポーン位置 |
|
|
507
|
+
| `yaw` | `number` | - | `0` | スポーン時の向き(度数法 0-360) |
|
|
508
|
+
|
|
509
|
+
#### 開発時ヘルパー
|
|
510
|
+
|
|
511
|
+
開発環境(`import.meta.env.DEV === true`)では、スポーン位置と向きを視覚的に確認できるヘルパーが表示されます:
|
|
512
|
+
|
|
513
|
+
- 半透明の円柱(下から上にかけて透明度が増すグラデーション)
|
|
514
|
+
- 黄緑色の矢印でスポーン方向を表示
|
|
515
|
+
|
|
516
|
+
本番ビルドではヘルパーは表示されず、コードも含まれません。
|
|
517
|
+
|
|
518
|
+
#### useSpawnPoint フック
|
|
519
|
+
|
|
520
|
+
プラットフォーム側で現在設定されているスポーン地点を取得するフックです。
|
|
521
|
+
|
|
522
|
+
```tsx
|
|
523
|
+
import { useSpawnPoint } from '@xrift/world-components'
|
|
524
|
+
|
|
525
|
+
function PlayerSpawner() {
|
|
526
|
+
const spawnPoint = useSpawnPoint()
|
|
527
|
+
|
|
528
|
+
useEffect(() => {
|
|
529
|
+
if (spawnPoint) {
|
|
530
|
+
player.position.set(...spawnPoint.position)
|
|
531
|
+
player.rotation.y = THREE.MathUtils.degToRad(spawnPoint.yaw)
|
|
532
|
+
}
|
|
533
|
+
}, [spawnPoint])
|
|
534
|
+
|
|
535
|
+
return null
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
#### 注意事項
|
|
540
|
+
|
|
541
|
+
- 1つのワールドに複数のSpawnPointがある場合、最後に設定されたものが有効になります
|
|
542
|
+
- `useSpawnPoint`は主にプラットフォーム側(xrift-frontend)での使用を想定しています
|
|
543
|
+
|
|
482
544
|
## 開発
|
|
483
545
|
|
|
484
546
|
```bash
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SpawnPoint/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SpawnPoint/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAU,MAAM,OAAO,CAAA;AAmCvC,OAAO,QAAQ,oBAAoB,CAAC;IAClC,UAAU,aAAa;QACrB,wBAAwB,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAA;KACxE;CACF;AAED,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAqE1C,CAAA"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from 'react';
|
|
3
3
|
import { shaderMaterial } from '@react-three/drei';
|
|
4
|
-
import { extend } from '@react-three/fiber';
|
|
5
|
-
import { DoubleSide } from 'three';
|
|
4
|
+
import { extend, useFrame } from '@react-three/fiber';
|
|
5
|
+
import { DoubleSide, Euler, Quaternion, Vector3 } from 'three';
|
|
6
6
|
import { useSpawnPointContext } from '../../contexts/SpawnPointContext';
|
|
7
|
+
// ワールド座標取得用の一時変数(毎フレーム生成を避けるため)
|
|
8
|
+
const _worldPos = new Vector3();
|
|
9
|
+
const _worldQuat = new Quaternion();
|
|
10
|
+
const _euler = new Euler();
|
|
7
11
|
const GradientCylinderMaterial = shaderMaterial({ color: [0, 1, 0.53], opacity: 0.5 },
|
|
8
12
|
// vertex shader
|
|
9
13
|
`
|
|
@@ -40,15 +44,32 @@ extend({ GradientCylinderMaterial });
|
|
|
40
44
|
*/
|
|
41
45
|
export const SpawnPoint = ({ position = [0, 0, 0], yaw = 0, }) => {
|
|
42
46
|
const { setSpawnPoint } = useSpawnPointContext();
|
|
47
|
+
const groupRef = useRef(null);
|
|
43
48
|
const yawRad = (yaw * Math.PI) / 180;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
// 初回のみワールド座標を取得するためのフラグ
|
|
50
|
+
const initializedRef = useRef(false);
|
|
51
|
+
useFrame(() => {
|
|
52
|
+
if (initializedRef.current || !groupRef.current)
|
|
53
|
+
return;
|
|
54
|
+
initializedRef.current = true;
|
|
55
|
+
// ワールド座標を取得
|
|
56
|
+
groupRef.current.getWorldPosition(_worldPos);
|
|
57
|
+
groupRef.current.getWorldQuaternion(_worldQuat);
|
|
58
|
+
// クォータニオンからyaw(Y軸回転)を抽出
|
|
59
|
+
_euler.setFromQuaternion(_worldQuat, 'YXZ');
|
|
60
|
+
const worldYawRad = _euler.y;
|
|
61
|
+
const worldYawDeg = (worldYawRad * 180) / Math.PI;
|
|
62
|
+
// ワールド座標(度数法に変換、0-360に正規化)
|
|
63
|
+
const normalizedYaw = ((worldYawDeg % 360) + 360) % 360;
|
|
64
|
+
const worldPosition = [
|
|
65
|
+
_worldPos.x,
|
|
66
|
+
_worldPos.y,
|
|
67
|
+
_worldPos.z,
|
|
68
|
+
];
|
|
69
|
+
setSpawnPoint({ position: worldPosition, yaw: normalizedYaw });
|
|
70
|
+
});
|
|
47
71
|
// Vite以外の環境では import.meta.env が存在しない可能性があるため安全にアクセス
|
|
48
72
|
const isDev = typeof import.meta !== 'undefined' && import.meta.env?.DEV;
|
|
49
|
-
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return (_jsxs("group", { position: position, children: [_jsxs("mesh", { position: [0, 0.375, 0], children: [_jsx("cylinderGeometry", { args: [0.5, 0.5, 0.75, 32, 1, true] }), _jsx("gradientCylinderMaterial", { transparent: true, side: DoubleSide, depthWrite: false })] }), _jsxs("group", { rotation: [0, -yawRad, 0], children: [_jsxs("mesh", { position: [0, 0.3, -0.1], rotation: [Math.PI / 2, 0, 0], children: [_jsx("cylinderGeometry", { args: [0.03, 0.03, 0.3, 8] }), _jsx("meshBasicMaterial", { color: "#00ff88" })] }), _jsxs("mesh", { position: [0, 0.3, 0.12], rotation: [Math.PI / 2, 0, 0], children: [_jsx("coneGeometry", { args: [0.08, 0.15, 8] }), _jsx("meshBasicMaterial", { color: "#00ff88" })] })] })] }));
|
|
73
|
+
return (_jsx("group", { ref: groupRef, position: position, rotation: [0, yawRad, 0], children: isDev && (_jsxs(_Fragment, { children: [_jsxs("mesh", { position: [0, 0.375, 0], children: [_jsx("cylinderGeometry", { args: [0.5, 0.5, 0.75, 32, 1, true] }), _jsx("gradientCylinderMaterial", { transparent: true, side: DoubleSide, depthWrite: false })] }), _jsxs("group", { children: [_jsxs("mesh", { position: [0, 0.3, 0.0], rotation: [Math.PI / 2, 0, 0], children: [_jsx("cylinderGeometry", { args: [0.03, 0.03, 0.4, 15] }), _jsx("meshBasicMaterial", { color: "#00ff88" })] }), _jsxs("mesh", { position: [0, 0.3, 0.27], rotation: [Math.PI / 2, 0, 0], children: [_jsx("coneGeometry", { args: [0.08, 0.15, 8] }), _jsx("meshBasicMaterial", { color: "#00ff88" })] })] })] })) }));
|
|
53
74
|
};
|
|
54
75
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/SpawnPoint/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAW,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/SpawnPoint/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpawnPointTestScene.d.ts","sourceRoot":"","sources":["../../src/scenes/SpawnPointTestScene.tsx"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,mBAAmB,4CAqClC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Skybox } from '../components/Skybox';
|
|
3
|
+
import { SpawnPoint } from '../components/SpawnPoint';
|
|
4
|
+
import { SpawnPointProvider } from '../contexts/SpawnPointContext';
|
|
5
|
+
/**
|
|
6
|
+
* SpawnPointのテストシーン
|
|
7
|
+
* Triplexでコンポーネントを確認するためのシーン
|
|
8
|
+
*/
|
|
9
|
+
export function SpawnPointTestScene() {
|
|
10
|
+
return (_jsxs(SpawnPointProvider, { children: [_jsx(Skybox, {}), _jsx("ambientLight", { intensity: 0.5 }), _jsx("directionalLight", { position: [5, 10, 5], intensity: 1 }), _jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], position: [0, 0, 0], receiveShadow: true, name: "Floor", children: [_jsx("planeGeometry", { args: [20, 20] }), _jsx("meshStandardMaterial", { color: "#cccccc" })] }), _jsx(SpawnPoint, { position: [0, 0, 0], yaw: 0 }), _jsx(SpawnPoint, { position: [3, 0, 3], yaw: 45 }), _jsx(SpawnPoint, { position: [-3, 0, 3], yaw: 180 }), _jsxs("mesh", { position: [0, 0.5, -3], name: "ReferenceCube", children: [_jsx("boxGeometry", { args: [1, 1, 1] }), _jsx("meshStandardMaterial", { color: "orange" })] })] }));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=SpawnPointTestScene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpawnPointTestScene.js","sourceRoot":"","sources":["../../src/scenes/SpawnPointTestScene.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAElE;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,CACL,MAAC,kBAAkB,eAEjB,KAAC,MAAM,KAAG,EAGV,uBAAc,SAAS,EAAE,GAAG,GAAI,EAChC,2BAAkB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,GAAI,EAGxD,gBACE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACnB,aAAa,QACb,IAAI,EAAC,OAAO,aAEZ,wBAAe,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAI,EACjC,+BAAsB,KAAK,EAAC,SAAS,GAAG,IACnC,EAGP,KAAC,UAAU,IAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAI,EAG3C,KAAC,UAAU,IAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAI,EAG5C,KAAC,UAAU,IAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,GAAI,EAG9C,gBAAM,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAC,eAAe,aAChD,sBAAa,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAI,EAChC,+BAAsB,KAAK,EAAC,QAAQ,GAAG,IAClC,IACY,CACtB,CAAA;AACH,CAAC"}
|