react-three-game 0.0.88 → 0.0.90
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.
|
@@ -370,7 +370,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
|
|
|
370
370
|
}
|
|
371
371
|
(_d = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed) === null || _d === void 0 ? void 0 : _d.call(canvasProps, event);
|
|
372
372
|
}
|
|
373
|
-
: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [physics ? (_jsx(Physics, { debug: isEditMode, paused: isEditMode, children: content })) : content, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), transformObject && (_jsx(TransformControls, { object: transformObject, mode: transformMode, space: "local", onObjectChange: handleTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: scaleSnap > 0 ? scaleSnap : undefined }, `transform-${selectedId}-${transformMode}-${positionSnap}-${rotationSnap}-${scaleSnap}`))] }))] })), showUI && (_jsxs(_Fragment, { children: [_jsxs("div", { style: toolbar.panel, children: [_jsx("button", { style: base.btn, onClick: toggleMode, children: isEditMode ? "▶" : "⏸" }), uiPlugins] }), isEditMode && (_jsx(EditorUI, { selectedId: selectedId, setSelectedId: setSelection, getPrefab: getPrefab, onReplacePrefab: (prefab) => loadPrefab(prefab, { resetHistory: true }), onImportPrefab: importPrefab, basePath: basePath, onUndo: undo, onRedo: redo, canUndo: historyIndex > 0, canRedo: historyIndex < history.length - 1 }))] }))] }) });
|
|
373
|
+
: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [physics ? (_jsx(Physics, { colliders: false, debug: isEditMode, paused: isEditMode, children: content })) : content, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), transformObject && (_jsx(TransformControls, { object: transformObject, mode: transformMode, space: "local", onObjectChange: handleTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: scaleSnap > 0 ? scaleSnap : undefined }, `transform-${selectedId}-${transformMode}-${positionSnap}-${rotationSnap}-${scaleSnap}`))] }))] })), showUI && (_jsxs(_Fragment, { children: [_jsxs("div", { style: toolbar.panel, children: [_jsx("button", { style: base.btn, onClick: toggleMode, children: isEditMode ? "▶" : "⏸" }), uiPlugins] }), isEditMode && (_jsx(EditorUI, { selectedId: selectedId, setSelectedId: setSelection, getPrefab: getPrefab, onReplacePrefab: (prefab) => loadPrefab(prefab, { resetHistory: true }), onImportPrefab: importPrefab, basePath: basePath, onUndo: undo, onRedo: redo, canUndo: historyIndex > 0, canRedo: historyIndex < history.length - 1 }))] }))] }) });
|
|
374
374
|
});
|
|
375
375
|
PrefabEditor.displayName = "PrefabEditor";
|
|
376
376
|
export default PrefabEditor;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { RigidBodyOptions } from "@react-three/rapier";
|
|
2
2
|
import { Component } from "./ComponentRegistry";
|
|
3
3
|
type PhysicsColliderType = NonNullable<RigidBodyOptions['colliders']> | 'capsule';
|
|
4
|
+
type ManualColliderShape = 'cuboid' | 'ball' | 'capsule';
|
|
4
5
|
export type PhysicsProps = Omit<RigidBodyOptions, 'colliders'> & {
|
|
5
6
|
colliders?: PhysicsColliderType;
|
|
7
|
+
manualColliderShape?: ManualColliderShape;
|
|
6
8
|
activeCollisionTypes?: 'all' | undefined;
|
|
7
9
|
linearVelocity?: [number, number, number];
|
|
8
10
|
angularVelocity?: [number, number, number];
|
|
11
|
+
colliderSize?: [number, number, number];
|
|
12
|
+
colliderRadius?: number;
|
|
9
13
|
capsuleRadius?: number;
|
|
10
14
|
capsuleHalfHeight?: number;
|
|
11
15
|
emitSensorEnterEvent?: boolean;
|
|
@@ -10,20 +10,57 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
-
import { CapsuleCollider, RigidBody, useRapier } from "@react-three/rapier";
|
|
13
|
+
import { BallCollider, CapsuleCollider, CuboidCollider, RigidBody, useRapier } from "@react-three/rapier";
|
|
14
14
|
import { useCallback, useEffect, useRef } from 'react';
|
|
15
15
|
import { useAssetRuntime, useEntityRuntime } from "../assetRuntime";
|
|
16
16
|
import { gameEvents, getEntityIdFromRigidBody } from "../GameEvents";
|
|
17
|
-
import { usePrefabNode } from "../prefabStore";
|
|
17
|
+
import { usePrefabNode, usePrefabStore } from "../prefabStore";
|
|
18
18
|
import { BooleanField, FieldGroup, NumberField, SelectField, StringField, Vector3Field } from "./Input";
|
|
19
|
-
import { getNodeUserData } from "../types";
|
|
19
|
+
import { findComponent, getNodeUserData } from "../types";
|
|
20
20
|
import { colors } from "../styles";
|
|
21
21
|
export function isPhysicsProps(v) {
|
|
22
22
|
return (v === null || v === void 0 ? void 0 : v.type) === "fixed" || (v === null || v === void 0 ? void 0 : v.type) === "dynamic" || (v === null || v === void 0 ? void 0 : v.type) === "kinematicPosition" || (v === null || v === void 0 ? void 0 : v.type) === "kinematicVelocity";
|
|
23
23
|
}
|
|
24
24
|
const enabledAxesFallback = [true, true, true];
|
|
25
|
+
const manualColliderShapeFallback = 'cuboid';
|
|
26
|
+
const colliderSizeFallback = [1, 1, 1];
|
|
27
|
+
const colliderRadiusFallback = 0.5;
|
|
25
28
|
const capsuleRadiusFallback = 0.35;
|
|
26
29
|
const capsuleHalfHeightFallback = 0.45;
|
|
30
|
+
function isManualColliderShape(value) {
|
|
31
|
+
return value === 'cuboid' || value === 'ball' || value === 'capsule';
|
|
32
|
+
}
|
|
33
|
+
function hasNodeColliderSource(node) {
|
|
34
|
+
return Boolean(findComponent(node, 'Geometry')
|
|
35
|
+
|| findComponent(node, 'BufferGeometry')
|
|
36
|
+
|| findComponent(node, 'Model'));
|
|
37
|
+
}
|
|
38
|
+
function subtreeHasColliderSource(nodeId, nodesById, childIdsById) {
|
|
39
|
+
var _a;
|
|
40
|
+
if (!nodeId)
|
|
41
|
+
return false;
|
|
42
|
+
const pending = [nodeId];
|
|
43
|
+
while (pending.length > 0) {
|
|
44
|
+
const currentId = pending.pop();
|
|
45
|
+
if (!currentId)
|
|
46
|
+
continue;
|
|
47
|
+
const currentNode = nodesById[currentId];
|
|
48
|
+
if (hasNodeColliderSource(currentNode)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
pending.push(...((_a = childIdsById[currentId]) !== null && _a !== void 0 ? _a : []));
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
function renderManualCollider({ shape, sensor, colliderSize, colliderRadius, capsuleRadius, capsuleHalfHeight, }) {
|
|
56
|
+
if (shape === 'ball') {
|
|
57
|
+
return _jsx(BallCollider, { args: [colliderRadius], sensor: sensor });
|
|
58
|
+
}
|
|
59
|
+
if (shape === 'capsule') {
|
|
60
|
+
return _jsx(CapsuleCollider, { args: [capsuleHalfHeight, capsuleRadius], sensor: sensor });
|
|
61
|
+
}
|
|
62
|
+
return _jsx(CuboidCollider, { args: colliderSize.map(value => value / 2), sensor: sensor });
|
|
63
|
+
}
|
|
27
64
|
function LockedAxisField({ label, name, values, onChange, }) {
|
|
28
65
|
const enabledAxes = Array.isArray(values[name])
|
|
29
66
|
? values[name]
|
|
@@ -64,19 +101,28 @@ function LockedAxisField({ label, name, values, onChange, }) {
|
|
|
64
101
|
}, children: axisLabel }, axisLabel));
|
|
65
102
|
}) })] }));
|
|
66
103
|
}
|
|
67
|
-
function PhysicsComponentEditor({ component, onUpdate }) {
|
|
104
|
+
function PhysicsComponentEditor({ node, component, onUpdate }) {
|
|
105
|
+
const nodeId = node === null || node === void 0 ? void 0 : node.id;
|
|
106
|
+
const hasAutomaticColliderSource = usePrefabStore(state => subtreeHasColliderSource(nodeId, state.nodesById, state.childIdsById));
|
|
107
|
+
const manualColliderShape = isManualColliderShape(component.properties.manualColliderShape)
|
|
108
|
+
? component.properties.manualColliderShape
|
|
109
|
+
: manualColliderShapeFallback;
|
|
68
110
|
return (_jsxs(FieldGroup, { children: [_jsx(SelectField, { name: "type", label: "Type", values: component.properties, onChange: onUpdate, options: [
|
|
69
111
|
{ value: 'dynamic', label: 'Dynamic' },
|
|
70
112
|
{ value: 'fixed', label: 'Fixed' },
|
|
71
113
|
{ value: 'kinematicPosition', label: 'Kinematic Position' },
|
|
72
114
|
{ value: 'kinematicVelocity', label: 'Kinematic Velocity' },
|
|
73
|
-
] }), _jsx(SelectField, { name: "colliders", label: "Collider", values: component.properties, onChange: onUpdate, options: [
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
115
|
+
] }), hasAutomaticColliderSource ? (_jsxs(_Fragment, { children: [_jsx(SelectField, { name: "colliders", label: "Collider", values: component.properties, onChange: onUpdate, options: [
|
|
116
|
+
{ value: 'hull', label: 'Hull (convex)' },
|
|
117
|
+
{ value: 'trimesh', label: 'Trimesh (exact)' },
|
|
118
|
+
{ value: 'cuboid', label: 'Cuboid (box)' },
|
|
119
|
+
{ value: 'ball', label: 'Ball (sphere)' },
|
|
120
|
+
{ value: 'capsule', label: 'Capsule' },
|
|
121
|
+
] }), component.properties.colliders === 'capsule' ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "capsuleRadius", label: "Capsule Radius", values: component.properties, onChange: onUpdate, fallback: capsuleRadiusFallback, min: 0.01, step: 0.01 }), _jsx(NumberField, { name: "capsuleHalfHeight", label: "Capsule Half Height", values: component.properties, onChange: onUpdate, fallback: capsuleHalfHeightFallback, min: 0.01, step: 0.01 })] })) : null] })) : (_jsxs(_Fragment, { children: [_jsx(SelectField, { name: "manualColliderShape", label: "Shape", values: Object.assign(Object.assign({}, component.properties), { manualColliderShape }), onChange: onUpdate, options: [
|
|
122
|
+
{ value: 'cuboid', label: 'Cuboid (box)' },
|
|
123
|
+
{ value: 'ball', label: 'Ball (sphere)' },
|
|
124
|
+
{ value: 'capsule', label: 'Capsule' },
|
|
125
|
+
] }), manualColliderShape === 'cuboid' ? (_jsx(Vector3Field, { name: "colliderSize", label: "Collider Size", values: component.properties, onChange: onUpdate, fallback: colliderSizeFallback })) : null, manualColliderShape === 'ball' ? (_jsx(NumberField, { name: "colliderRadius", label: "Collider Radius", values: component.properties, onChange: onUpdate, fallback: colliderRadiusFallback, min: 0.01, step: 0.01 })) : null, manualColliderShape === 'capsule' ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "capsuleRadius", label: "Capsule Radius", values: component.properties, onChange: onUpdate, fallback: capsuleRadiusFallback, min: 0.01, step: 0.01 }), _jsx(NumberField, { name: "capsuleHalfHeight", label: "Capsule Half Height", values: component.properties, onChange: onUpdate, fallback: capsuleHalfHeightFallback, min: 0.01, step: 0.01 })] })) : null] })), _jsx(NumberField, { name: "mass", label: "Mass", values: component.properties, onChange: onUpdate, fallback: 1, step: 0.1, min: 0 }), _jsx(NumberField, { name: "restitution", label: "Restitution (Bounciness)", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, max: 1, step: 0.1 }), _jsx(NumberField, { name: "friction", label: "Friction", values: component.properties, onChange: onUpdate, fallback: 0.5, min: 0, step: 0.1 }), _jsx(NumberField, { name: "linearDamping", label: "Linear Damping", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, step: 0.1 }), _jsx(NumberField, { name: "angularDamping", label: "Angular Damping", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, step: 0.1 }), _jsx(NumberField, { name: "gravityScale", label: "Gravity Scale", values: component.properties, onChange: onUpdate, fallback: 1, step: 0.1 }), _jsx(Vector3Field, { name: "linearVelocity", label: "Linear Velocity", values: component.properties, onChange: onUpdate, fallback: [0, 0, 0] }), _jsx(Vector3Field, { name: "angularVelocity", label: "Angular Velocity", values: component.properties, onChange: onUpdate, fallback: [0, 0, 0] }), _jsx(LockedAxisField, { label: "Lock Movement", name: "enabledTranslations", values: component.properties, onChange: onUpdate }), _jsx(LockedAxisField, { label: "Lock Rotations", name: "enabledRotations", values: component.properties, onChange: onUpdate }), _jsx(BooleanField, { name: "sensor", label: "Sensor (Trigger Only)", values: component.properties, onChange: onUpdate, fallback: false }), _jsx(BooleanField, { name: "emitCollisionEnterEvent", label: "Emit Collision Enter", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitCollisionEnterEvent ? (_jsx(StringField, { name: "collisionEnterEventName", label: "Collision Enter Event", values: component.properties, onChange: onUpdate, placeholder: "target:hit" })) : null, _jsx(BooleanField, { name: "emitCollisionExitEvent", label: "Emit Collision Exit", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitCollisionExitEvent ? (_jsx(StringField, { name: "collisionExitEventName", label: "Collision Exit Event", values: component.properties, onChange: onUpdate, placeholder: "target:reset" })) : null, _jsx(BooleanField, { name: "emitSensorEnterEvent", label: "Emit Sensor Enter", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitSensorEnterEvent ? (_jsx(StringField, { name: "sensorEnterEventName", label: "Sensor Enter Event", values: component.properties, onChange: onUpdate, placeholder: "sensor:enter" })) : null, _jsx(BooleanField, { name: "emitSensorExitEvent", label: "Emit Sensor Exit", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitSensorExitEvent ? (_jsx(StringField, { name: "sensorExitEventName", label: "Sensor Exit Event", values: component.properties, onChange: onUpdate, placeholder: "sensor:exit" })) : null, _jsx(SelectField, { name: "activeCollisionTypes", label: "Collision Detection", values: component.properties, onChange: onUpdate, options: [
|
|
80
126
|
{ value: '', label: 'Default (Dynamic only)' },
|
|
81
127
|
{ value: 'all', label: 'All (includes kinematic & fixed)' },
|
|
82
128
|
] })] }));
|
|
@@ -86,17 +132,24 @@ function PhysicsComponentView({ properties, children, position, rotation, scale
|
|
|
86
132
|
const { registerRigidBodyRef } = useAssetRuntime();
|
|
87
133
|
const { editMode, nodeId, getObject } = useEntityRuntime();
|
|
88
134
|
const gameObject = usePrefabNode(nodeId);
|
|
135
|
+
const hasAutomaticColliderSource = usePrefabStore(state => subtreeHasColliderSource(nodeId, state.nodesById, state.childIdsById));
|
|
89
136
|
const nodeName = (_b = (_a = gameObject === null || gameObject === void 0 ? void 0 : gameObject.name) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
|
|
90
137
|
const userData = Object.assign(Object.assign({ prefabNodeId: (_c = gameObject === null || gameObject === void 0 ? void 0 : gameObject.id) !== null && _c !== void 0 ? _c : nodeId }, (nodeName ? { prefabNodeName: nodeName } : {})), getNodeUserData(gameObject));
|
|
91
|
-
const { type, colliders, sensor, activeCollisionTypes, linearVelocity = [0, 0, 0], angularVelocity = [0, 0, 0], capsuleRadius = capsuleRadiusFallback, capsuleHalfHeight = capsuleHalfHeightFallback, emitSensorEnterEvent = false, sensorEnterEventName, emitSensorExitEvent = false, sensorExitEventName, emitCollisionEnterEvent = false, collisionEnterEventName, emitCollisionExitEvent = false, collisionExitEventName, enabledTranslations = enabledAxesFallback, enabledRotations = enabledAxesFallback } = properties, otherProps = __rest(properties, ["type", "colliders", "sensor", "activeCollisionTypes", "linearVelocity", "angularVelocity", "capsuleRadius", "capsuleHalfHeight", "emitSensorEnterEvent", "sensorEnterEventName", "emitSensorExitEvent", "sensorExitEventName", "emitCollisionEnterEvent", "collisionEnterEventName", "emitCollisionExitEvent", "collisionExitEventName", "enabledTranslations", "enabledRotations"]);
|
|
138
|
+
const { type, colliders, sensor, manualColliderShape = manualColliderShapeFallback, activeCollisionTypes, linearVelocity = [0, 0, 0], angularVelocity = [0, 0, 0], colliderSize = colliderSizeFallback, colliderRadius = colliderRadiusFallback, capsuleRadius = capsuleRadiusFallback, capsuleHalfHeight = capsuleHalfHeightFallback, emitSensorEnterEvent = false, sensorEnterEventName, emitSensorExitEvent = false, sensorExitEventName, emitCollisionEnterEvent = false, collisionEnterEventName, emitCollisionExitEvent = false, collisionExitEventName, enabledTranslations = enabledAxesFallback, enabledRotations = enabledAxesFallback } = properties, otherProps = __rest(properties, ["type", "colliders", "sensor", "manualColliderShape", "activeCollisionTypes", "linearVelocity", "angularVelocity", "colliderSize", "colliderRadius", "capsuleRadius", "capsuleHalfHeight", "emitSensorEnterEvent", "sensorEnterEventName", "emitSensorExitEvent", "sensorExitEventName", "emitCollisionEnterEvent", "collisionEnterEventName", "emitCollisionExitEvent", "collisionExitEventName", "enabledTranslations", "enabledRotations"]);
|
|
92
139
|
const colliderType = colliders || (type === 'fixed' ? 'trimesh' : 'hull');
|
|
93
|
-
const
|
|
140
|
+
const resolvedManualColliderShape = isManualColliderShape(manualColliderShape)
|
|
141
|
+
? manualColliderShape
|
|
142
|
+
: manualColliderShapeFallback;
|
|
143
|
+
const usesAutomaticColliderSource = hasAutomaticColliderSource && colliderType !== 'capsule';
|
|
144
|
+
const manualColliderShapeToRender = hasAutomaticColliderSource
|
|
145
|
+
? 'capsule'
|
|
146
|
+
: resolvedManualColliderShape;
|
|
94
147
|
const rigidBodyRef = useRef(null);
|
|
95
148
|
const linearVelocityKey = linearVelocity.join(',');
|
|
96
149
|
const angularVelocityKey = angularVelocity.join(',');
|
|
97
150
|
const rbKey = editMode
|
|
98
|
-
? `${type || 'dynamic'}_${colliderType}_${capsuleRadius}_${capsuleHalfHeight}_${position === null || position === void 0 ? void 0 : position.join(',')}_${rotation === null || rotation === void 0 ? void 0 : rotation.join(',')}`
|
|
99
|
-
: `${type || 'dynamic'}_${colliderType}_${capsuleRadius}_${capsuleHalfHeight}`;
|
|
151
|
+
? `${type || 'dynamic'}_${colliderType}_${resolvedManualColliderShape}_${colliderSize.join(',')}_${colliderRadius}_${capsuleRadius}_${capsuleHalfHeight}_${position === null || position === void 0 ? void 0 : position.join(',')}_${rotation === null || rotation === void 0 ? void 0 : rotation.join(',')}`
|
|
152
|
+
: `${type || 'dynamic'}_${colliderType}_${resolvedManualColliderShape}_${colliderSize.join(',')}_${colliderRadius}_${capsuleRadius}_${capsuleHalfHeight}`;
|
|
100
153
|
const handleRigidBodyRef = useCallback((rigidBody) => {
|
|
101
154
|
rigidBodyRef.current = rigidBody;
|
|
102
155
|
if (!nodeId)
|
|
@@ -184,13 +237,20 @@ function PhysicsComponentView({ properties, children, position, rotation, scale
|
|
|
184
237
|
return;
|
|
185
238
|
dispatchPhysicsEvent(collisionExitEventName, payload);
|
|
186
239
|
}, [collisionExitEventName, dispatchPhysicsEvent, emitCollisionExitEvent]);
|
|
187
|
-
const rigidBodyProps = Object.assign({ ref: handleRigidBodyRef, type, colliders:
|
|
240
|
+
const rigidBodyProps = Object.assign({ ref: handleRigidBodyRef, type, colliders: usesAutomaticColliderSource ? colliderType : false, position,
|
|
188
241
|
rotation,
|
|
189
242
|
scale,
|
|
190
243
|
sensor,
|
|
191
244
|
enabledTranslations,
|
|
192
245
|
enabledRotations, name: nodeName, userData: Object.assign({ entityId: nodeId }, userData), onIntersectionEnter: emitSensorEnterEvent ? handleIntersectionEnter : undefined, onIntersectionExit: emitSensorExitEvent ? handleIntersectionExit : undefined, onCollisionEnter: emitCollisionEnterEvent ? handleCollisionEnter : undefined, onCollisionExit: emitCollisionExitEvent ? handleCollisionExit : undefined }, otherProps);
|
|
193
|
-
return (_jsxs(RigidBody, Object.assign({}, rigidBodyProps, { children: [
|
|
246
|
+
return (_jsxs(RigidBody, Object.assign({}, rigidBodyProps, { children: [!usesAutomaticColliderSource ? renderManualCollider({
|
|
247
|
+
shape: manualColliderShapeToRender,
|
|
248
|
+
sensor,
|
|
249
|
+
colliderSize,
|
|
250
|
+
colliderRadius,
|
|
251
|
+
capsuleRadius,
|
|
252
|
+
capsuleHalfHeight,
|
|
253
|
+
}) : null, children] }), rbKey));
|
|
194
254
|
}
|
|
195
255
|
const PhysicsComponent = {
|
|
196
256
|
name: 'Physics',
|
|
@@ -199,6 +259,9 @@ const PhysicsComponent = {
|
|
|
199
259
|
defaultProperties: {
|
|
200
260
|
type: 'dynamic',
|
|
201
261
|
colliders: 'hull',
|
|
262
|
+
manualColliderShape: manualColliderShapeFallback,
|
|
263
|
+
colliderSize: colliderSizeFallback,
|
|
264
|
+
colliderRadius: colliderRadiusFallback,
|
|
202
265
|
capsuleRadius: capsuleRadiusFallback,
|
|
203
266
|
capsuleHalfHeight: capsuleHalfHeightFallback,
|
|
204
267
|
linearVelocity: [0, 0, 0],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { useThree } from '@react-three/fiber';
|
|
3
4
|
import { SoundPicker } from '../../assetviewer/page';
|
|
4
5
|
import { useAssetRuntime, useEntityRuntime } from '../assetRuntime';
|
|
5
6
|
import { gameEvents } from '../GameEvents';
|
|
@@ -142,6 +143,7 @@ function SoundComponentEditor({ component, onUpdate, basePath = '' }) {
|
|
|
142
143
|
function SoundComponentView({ properties, children }) {
|
|
143
144
|
const { getSound } = useAssetRuntime();
|
|
144
145
|
const { editMode, nodeId } = useEntityRuntime();
|
|
146
|
+
const { camera } = useThree();
|
|
145
147
|
const { eventName, autoplay = false, positional = false, refDistance = 1, maxDistance = 24, rolloffFactor = 1, distanceModel = 'inverse' } = properties;
|
|
146
148
|
const sequenceIndexRef = useRef(0);
|
|
147
149
|
const listenerRef = useRef(null);
|
|
@@ -150,6 +152,22 @@ function SoundComponentView({ properties, children }) {
|
|
|
150
152
|
if (!listenerRef.current) {
|
|
151
153
|
listenerRef.current = getSharedAudioListener();
|
|
152
154
|
}
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
var _a;
|
|
157
|
+
const listener = listenerRef.current;
|
|
158
|
+
if (!listener) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (listener.parent !== camera) {
|
|
162
|
+
(_a = listener.parent) === null || _a === void 0 ? void 0 : _a.remove(listener);
|
|
163
|
+
camera.add(listener);
|
|
164
|
+
}
|
|
165
|
+
return () => {
|
|
166
|
+
if (listener.parent === camera) {
|
|
167
|
+
camera.remove(listener);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}, [camera]);
|
|
153
171
|
useEffect(() => {
|
|
154
172
|
const audio = positionalAudioRef.current;
|
|
155
173
|
if (!audio) {
|