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
- { value: 'hull', label: 'Hull (convex)' },
75
- { value: 'trimesh', label: 'Trimesh (exact)' },
76
- { value: 'cuboid', label: 'Cuboid (box)' },
77
- { value: 'ball', label: 'Ball (sphere)' },
78
- { value: 'capsule', label: 'Capsule' },
79
- ] }), 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, _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: [
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 usesManualCapsuleCollider = colliderType === 'capsule';
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: usesManualCapsuleCollider ? false : colliderType, position,
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: [usesManualCapsuleCollider ? _jsx(CapsuleCollider, { args: [capsuleHalfHeight, capsuleRadius], sensor: sensor }) : null, children] }), rbKey));
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-three-game",
3
- "version": "0.0.88",
3
+ "version": "0.0.90",
4
4
  "description": "high performance 3D game engine built in React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",