@relu-interactives/spatial-ecs 0.2.12 → 0.2.14
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/dist/{System-CHCucemW.d.cts → System-BeuJ1xt5.d.cts} +291 -2
- package/dist/{System-CHCucemW.d.ts → System-BeuJ1xt5.d.ts} +291 -2
- package/dist/{Video-B9ZKmBIT.d.ts → Video-Cym2C52L.d.ts} +2 -241
- package/dist/{Video-ACTSfWjH.d.cts → Video-D4B-z74P.d.cts} +2 -241
- package/dist/{chunk-PH43YHUT.js → chunk-27RBPOVO.js} +3 -3
- package/dist/{chunk-PH43YHUT.js.map → chunk-27RBPOVO.js.map} +1 -1
- package/dist/{chunk-ZCEMOTH4.js → chunk-7QBONTBW.js} +4 -4
- package/dist/{chunk-ZCEMOTH4.js.map → chunk-7QBONTBW.js.map} +1 -1
- package/dist/{chunk-XPCVEXMY.js → chunk-FTIQQK62.js} +2 -2
- package/dist/chunk-FTIQQK62.js.map +1 -0
- package/dist/{chunk-ON4E5E5O.js → chunk-KDZ6VBRO.js} +4 -4
- package/dist/{chunk-ON4E5E5O.js.map → chunk-KDZ6VBRO.js.map} +1 -1
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +1 -1
- package/dist/docs/api/Behaviour/classes/Behaviour.md +29 -29
- package/dist/docs/api/Component/classes/Component.md +1 -1
- package/dist/docs/api/components/classes/AnimationComponent.md +26 -26
- package/dist/docs/api/components/classes/AudioComponent.md +19 -19
- package/dist/docs/api/components/classes/CameraComponent.md +14 -14
- package/dist/docs/api/components/classes/EntityType.md +3 -3
- package/dist/docs/api/components/classes/Environment.md +7 -3
- package/dist/docs/api/components/classes/ImageComponent.md +7 -7
- package/dist/docs/api/components/classes/ImageTarget.md +7 -7
- package/dist/docs/api/components/classes/ImageTargetAnchor.md +4 -4
- package/dist/docs/api/components/classes/InstanceSlotComponent.md +4 -4
- package/dist/docs/api/components/classes/InstancedMeshComponent.md +10 -10
- package/dist/docs/api/components/classes/LightComponent.md +6 -6
- package/dist/docs/api/components/classes/MaterialComponent.md +11 -11
- package/dist/docs/api/components/classes/MeshComponent.md +3 -3
- package/dist/docs/api/components/classes/MeshGeometryComponent.md +9 -9
- package/dist/docs/api/components/classes/ModelComponent.md +4 -4
- package/dist/docs/api/components/classes/Name.md +3 -3
- package/dist/docs/api/components/classes/Object3DRef.md +4 -4
- package/dist/docs/api/components/classes/ParentId.md +3 -3
- package/dist/docs/api/components/classes/PhysicsComponent.md +6 -6
- package/dist/docs/api/components/classes/Postprocessing.md +7 -3
- package/dist/docs/api/components/classes/ScriptComponent.md +5 -5
- package/dist/docs/api/components/classes/Selectable.md +3 -3
- package/dist/docs/api/components/classes/SelectionTransformState.md +5 -5
- package/dist/docs/api/components/classes/SpriteComponent.md +7 -7
- package/dist/docs/api/components/classes/TransformComponent.md +12 -12
- package/dist/docs/api/components/classes/VideoComponent.md +28 -28
- package/dist/docs/api/components/functions/normalizePhysicsState.md +1 -1
- package/dist/docs/api/components/index.md +1 -1
- package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +9 -9
- package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +13 -13
- package/dist/docs/api/components/type-aliases/CameraProjection.md +1 -1
- package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +1 -1
- package/dist/docs/api/components/type-aliases/ColliderShape.md +1 -1
- package/dist/docs/api/components/type-aliases/ColliderState.md +20 -20
- package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +4 -4
- package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +8 -8
- package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +7 -7
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentState.md +5 -5
- package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +3 -3
- package/dist/docs/api/components/type-aliases/ImageTargetReference.md +7 -7
- package/dist/docs/api/components/type-aliases/InstanceTransform.md +13 -13
- package/dist/docs/api/components/type-aliases/InstancedMeshKind.md +1 -1
- package/dist/docs/api/components/type-aliases/LightValueState.md +11 -11
- package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +1 -1
- package/dist/docs/api/components/type-aliases/MaterialValueState.md +28 -28
- package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +1 -1
- package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +7 -7
- package/dist/docs/api/components/type-aliases/PhysicsState.md +3 -3
- package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +3 -3
- package/dist/docs/api/components/type-aliases/PostprocessingState.md +62 -62
- package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +3 -3
- package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +2 -2
- package/dist/docs/api/components/type-aliases/RigidbodyState.md +17 -17
- package/dist/docs/api/components/type-aliases/RigidbodyType.md +1 -1
- package/dist/docs/api/components/type-aliases/ScriptEntry.md +9 -9
- package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +1 -1
- package/dist/docs/api/components/type-aliases/TransformData.md +4 -4
- package/dist/docs/api/components/type-aliases/TransformModeValue.md +1 -1
- package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +1 -1
- package/dist/docs/api/components/type-aliases/Vec3.md +4 -4
- package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_INSTANCED_MESH_PARAMETERS.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_INSTANCE_TRANSFORM.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +1 -1
- package/dist/docs/api/index/classes/AnimationStateMachine.md +16 -16
- package/dist/docs/api/index/classes/AnimationStateManager.md +13 -13
- package/dist/docs/api/index/classes/AnimationSystem.md +3 -3
- package/dist/docs/api/index/classes/AudioSystem.md +4 -4
- package/dist/docs/api/index/classes/CameraSyncSystem.md +2 -2
- package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +4 -4
- package/dist/docs/api/index/classes/InputSystem.md +33 -33
- package/dist/docs/api/index/classes/InstancedMeshSystem.md +2 -2
- package/dist/docs/api/index/classes/LightSyncSystem.md +2 -2
- package/dist/docs/api/index/classes/MaterialSyncSystem.md +3 -3
- package/dist/docs/api/index/classes/MeshGeometrySystem.md +2 -2
- package/dist/docs/api/index/classes/ObjectManagementSystem.md +14 -14
- package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +2 -2
- package/dist/docs/api/index/classes/PhysicsSyncSystem.md +4 -4
- package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +4 -4
- package/dist/docs/api/index/classes/RenderSystem.md +3 -3
- package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +4 -4
- package/dist/docs/api/index/classes/TransformSyncSystem.md +2 -2
- package/dist/docs/api/index/classes/VideoSystem.md +4 -4
- package/dist/docs/api/index/classes/World.md +186 -82
- package/dist/docs/api/index/functions/createAnimationComponent.md +1 -1
- package/dist/docs/api/index/functions/createAudioComponent.md +1 -1
- package/dist/docs/api/index/functions/createCameraComponent.md +1 -1
- package/dist/docs/api/index/functions/createEntityTypeComponent.md +1 -1
- package/dist/docs/api/index/functions/createEnvironmentComponent.md +1 -1
- package/dist/docs/api/index/functions/createImageComponent.md +1 -1
- package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +1 -1
- package/dist/docs/api/index/functions/createImageTargetComponent.md +1 -1
- package/dist/docs/api/index/functions/createInstanceSlotComponent.md +1 -1
- package/dist/docs/api/index/functions/createInstancedMeshComponent.md +1 -1
- package/dist/docs/api/index/functions/createLightComponent.md +1 -1
- package/dist/docs/api/index/functions/createMaterialComponent.md +1 -1
- package/dist/docs/api/index/functions/createMeshComponent.md +1 -1
- package/dist/docs/api/index/functions/createMeshGeometryComponent.md +1 -1
- package/dist/docs/api/index/functions/createModelComponent.md +1 -1
- package/dist/docs/api/index/functions/createNameComponent.md +1 -1
- package/dist/docs/api/index/functions/createObject3DRefComponent.md +1 -1
- package/dist/docs/api/index/functions/createParentIdComponent.md +1 -1
- package/dist/docs/api/index/functions/createPhysicsComponent.md +1 -1
- package/dist/docs/api/index/functions/createPostprocessingComponent.md +1 -1
- package/dist/docs/api/index/functions/createScriptComponent.md +1 -1
- package/dist/docs/api/index/functions/createSelectableComponent.md +1 -1
- package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +1 -1
- package/dist/docs/api/index/functions/createSpriteComponent.md +1 -1
- package/dist/docs/api/index/functions/createTransformComponent.md +1 -1
- package/dist/docs/api/index/functions/createVideoComponent.md +1 -1
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +1 -1
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +1 -1
- package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +1 -1
- package/dist/docs/api/index/functions/registerDefaultFactories.md +1 -1
- package/dist/docs/api/index/interfaces/EcsSystem.md +3 -3
- package/dist/docs/api/index/interfaces/StateMachine.md +13 -13
- package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +4 -4
- package/dist/docs/api/index/type-aliases/ComponentFactory.md +1 -1
- package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +1 -1
- package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +3 -3
- package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +4 -4
- package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +3 -3
- package/dist/docs/api/index/type-aliases/KeyboardKey.md +1 -1
- package/dist/docs/api/index/type-aliases/MouseButton.md +1 -1
- package/dist/docs/api/index/type-aliases/SelectionContext.md +4 -4
- package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +1 -1
- package/dist/docs/api/index/variables/KeyboardKeys.md +89 -89
- package/dist/docs/api/types/type-aliases/AssetInput.md +3 -3
- package/dist/docs/api/types/type-aliases/CheckboxInput.md +12 -2
- package/dist/docs/api/types/type-aliases/ColorInput.md +1 -1
- package/dist/docs/api/types/type-aliases/ComponentInput.md +4 -4
- package/dist/docs/api/types/type-aliases/ComponentKind.md +1 -1
- package/dist/docs/api/types/type-aliases/DropdownInput.md +3 -3
- package/dist/docs/api/types/type-aliases/DropdownOption.md +3 -3
- package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +1 -1
- package/dist/docs/api/types/type-aliases/EcsEntityKind.md +1 -1
- package/dist/docs/api/types/type-aliases/EntityId.md +1 -1
- package/dist/docs/api/types/type-aliases/EntityInput.md +3 -3
- package/dist/docs/api/types/type-aliases/FloatInput.md +1 -1
- package/dist/docs/api/types/type-aliases/IntersectionResult.md +3 -3
- package/dist/docs/api/types/type-aliases/ParentLookup.md +3 -3
- package/dist/docs/api/types/type-aliases/SelectionListener.md +1 -1
- package/dist/docs/api/types/type-aliases/SliderInput.md +5 -5
- package/dist/docs/api/types/type-aliases/TextInput.md +1 -1
- package/dist/docs/api/types/type-aliases/ToggleInput.md +1 -1
- package/dist/docs/api/types/type-aliases/Vec3.md +1 -1
- package/dist/docs/api/types/type-aliases/Vector2Input.md +3 -3
- package/dist/docs/api/types/type-aliases/Vector3Input.md +4 -4
- package/dist/docs/api/types/type-aliases/WorldEntityView.md +1 -1
- package/dist/docs/guide/accessing-components.md +135 -1
- package/dist/docs/guide/authoring-a-behaviour.md +1 -1
- package/dist/docs/guide/behaviour-data-binding/asset-input.md +54 -0
- package/dist/docs/guide/behaviour-data-binding/checkbox-input.md +38 -0
- package/dist/docs/guide/behaviour-data-binding/color-input.md +38 -0
- package/dist/docs/guide/behaviour-data-binding/component-input.md +79 -0
- package/dist/docs/guide/behaviour-data-binding/dropdown-input.md +53 -0
- package/dist/docs/guide/behaviour-data-binding/entity-input.md +100 -0
- package/dist/docs/guide/behaviour-data-binding/float-input.md +35 -0
- package/dist/docs/guide/behaviour-data-binding/index.md +158 -0
- package/dist/docs/guide/behaviour-data-binding/slider-input.md +37 -0
- package/dist/docs/guide/behaviour-data-binding/text-input.md +35 -0
- package/dist/docs/guide/behaviour-data-binding/toggle-input.md +36 -0
- package/dist/docs/guide/behaviour-data-binding/vector2-input.md +36 -0
- package/dist/docs/guide/behaviour-data-binding/vector3-input.md +41 -0
- package/dist/docs/guide/components/parent-id.md +25 -0
- package/dist/docs/guide/runtime-entity-management.md +302 -0
- package/dist/docs/guide/scene/environment.md +5 -6
- package/dist/docs/guide/scene/index.md +5 -10
- package/dist/docs/guide/scene/postprocessing.md +5 -6
- package/dist/docs/guide/systems/object-management-system.md +61 -0
- package/dist/docs/guide/world-api.md +37 -1
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +2 -2
- package/dist/factories/index.d.ts +2 -2
- package/dist/factories/index.js +3 -3
- package/dist/{index-B5JcGMJ5.d.ts → index-BfoOC2CG.d.cts} +2 -2
- package/dist/{index-kx5O2mVU.d.cts → index-BoJ3_6a3.d.ts} +2 -2
- package/dist/index.cjs +65 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +73 -8
- package/dist/index.js.map +1 -1
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +2 -2
- package/dist/systems/index.d.ts +2 -2
- package/dist/systems/index.js +3 -3
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/worldSnapshotUtils.d.cts +1 -1
- package/dist/worldSnapshotUtils.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-XPCVEXMY.js.map +0 -1
- package/dist/docs/guide/inspector-data-binding.md +0 -367
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
type WorldEntityView = NonNullable<ReturnType<World["getEntityById"]>>;
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Defined in: [types.ts:126](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/
|
|
13
|
+
Defined in: [types.ts:126](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/f4080487315dc2ea88332b3160fc071e7828b385/core/types.ts#L126)
|
|
14
14
|
|
|
15
15
|
Lightweight, read-only view of an entity returned by `World.getEntityById`.
|
|
16
16
|
Contains the entity id and its current component list at the moment of the
|
|
@@ -392,8 +392,142 @@ See [World API](./world-api) for the full set of entity and component query meth
|
|
|
392
392
|
|
|
393
393
|
---
|
|
394
394
|
|
|
395
|
+
## Adding and removing components at runtime
|
|
396
|
+
|
|
397
|
+
You can add or remove components on any entity from a Behaviour script at runtime using `this.world` or through `ObjectManagementSystem`.
|
|
398
|
+
|
|
399
|
+
### `world.addComponent` — attach a data component
|
|
400
|
+
|
|
401
|
+
Use `world.addComponent` to attach a simple, data-only component that carries no runtime handles:
|
|
402
|
+
|
|
403
|
+
```ts
|
|
404
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
405
|
+
import { Name } from "@relu-interactives/spatial-ecs/components";
|
|
406
|
+
|
|
407
|
+
export default class Tagger extends Behaviour {
|
|
408
|
+
protected init() {
|
|
409
|
+
const entity = this.world.getEntityByName("Target");
|
|
410
|
+
if (!entity) return;
|
|
411
|
+
|
|
412
|
+
// Give the entity a display name
|
|
413
|
+
this.world.addComponent(entity.entityId, new Name({ value: "Tagged" }));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### `world.removeComponent` — detach a component by class
|
|
419
|
+
|
|
420
|
+
```ts
|
|
421
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
422
|
+
import { PhysicsComponent } from "@relu-interactives/spatial-ecs/components";
|
|
423
|
+
|
|
424
|
+
export default class Freezer extends Behaviour {
|
|
425
|
+
protected init() {
|
|
426
|
+
// Remove physics from this entity to freeze it in place
|
|
427
|
+
this.world.removeComponent(this.entityId, PhysicsComponent);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### `oms.createComponentNow` — factory-initialized components
|
|
433
|
+
|
|
434
|
+
For components that require full runtime setup — Rapier physics bodies, Web Audio nodes, Three.js material instances, animation clip catalogs — use `createComponentNow` on `ObjectManagementSystem`. It calls the same registered factory used during scene construction, ensuring all runtime handles are correctly wired:
|
|
435
|
+
|
|
436
|
+
```ts
|
|
437
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
438
|
+
|
|
439
|
+
export default class DynamicPhysics extends Behaviour {
|
|
440
|
+
protected init() {
|
|
441
|
+
const oms = this.world.getObjectManagementSystem();
|
|
442
|
+
if (!oms) return;
|
|
443
|
+
|
|
444
|
+
// Add a physics component with full Rapier rigidbody and collider setup
|
|
445
|
+
oms.createComponentNow("physics", this.world, this.entityId, {
|
|
446
|
+
rigidbody: { type: "dynamic", mass: 1, gravityScale: 1 },
|
|
447
|
+
collider: { shape: "box" },
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Registered component factory kinds:**
|
|
454
|
+
|
|
455
|
+
| Kind | Component |
|
|
456
|
+
|------|-----------|
|
|
457
|
+
| `"animation"` | AnimationComponent |
|
|
458
|
+
| `"audio"` | AudioComponent |
|
|
459
|
+
| `"camera"` | CameraComponent |
|
|
460
|
+
| `"physics"` | PhysicsComponent |
|
|
461
|
+
| `"environment"` | EnvironmentComponent |
|
|
462
|
+
| `"entityType"` | EntityTypeComponent |
|
|
463
|
+
| `"image"` | ImageComponent |
|
|
464
|
+
| `"imageTarget"` | ImageTargetComponent |
|
|
465
|
+
| `"imageTargetAnchor"` | ImageTargetAnchorComponent |
|
|
466
|
+
| `"light"` | LightComponent |
|
|
467
|
+
| `"material"` | MaterialComponent |
|
|
468
|
+
| `"mesh"` | MeshComponent |
|
|
469
|
+
| `"meshGeometry"` | MeshGeometryComponent |
|
|
470
|
+
| `"model"` | ModelComponent |
|
|
471
|
+
| `"name"` | Name |
|
|
472
|
+
| `"object3DRef"` | Object3DRef |
|
|
473
|
+
| `"parentId"` | ParentId |
|
|
474
|
+
| `"postprocessing"` | PostprocessingComponent |
|
|
475
|
+
| `"script"` | ScriptComponent |
|
|
476
|
+
| `"sprite"` | SpriteComponent |
|
|
477
|
+
| `"transform"` | TransformComponent |
|
|
478
|
+
| `"video"` | VideoComponent |
|
|
479
|
+
| `"instancedMesh"` | InstancedMeshComponent |
|
|
480
|
+
|
|
481
|
+
**Decision guide:**
|
|
482
|
+
|
|
483
|
+
| Scenario | Use |
|
|
484
|
+
|----------|-----|
|
|
485
|
+
| Tagging with name, type, or other pure-data component | `world.addComponent(id, new ComponentClass(...))` |
|
|
486
|
+
| Adding physics with Rapier body/collider | `oms.createComponentNow("physics", world, id, config)` |
|
|
487
|
+
| Adding audio with Web Audio node | `oms.createComponentNow("audio", world, id, path, options, ctx)` |
|
|
488
|
+
| Adding a material with Three.js material instance | `oms.createComponentNow("material", world, id, values)` |
|
|
489
|
+
| Detaching any component | `world.removeComponent(id, ComponentClass)` |
|
|
490
|
+
|
|
491
|
+
### Post-spawn example: add physics to a spawned cube
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
495
|
+
|
|
496
|
+
export default class PhysicsCube extends Behaviour {
|
|
497
|
+
private spawnedId: number | null = null;
|
|
498
|
+
|
|
499
|
+
protected init() {
|
|
500
|
+
const oms = this.world.getObjectManagementSystem();
|
|
501
|
+
if (!oms) return;
|
|
502
|
+
|
|
503
|
+
oms.requestCreate("cube", {
|
|
504
|
+
name: "PhysicsCube",
|
|
505
|
+
transform: { position: { x: 0, y: 3, z: 0 } },
|
|
506
|
+
}, (entityId) => {
|
|
507
|
+
this.spawnedId = entityId;
|
|
508
|
+
// Physics factory wires up Rapier body + collider automatically
|
|
509
|
+
oms.createComponentNow("physics", this.world, entityId, {
|
|
510
|
+
rigidbody: { type: "dynamic", mass: 1, gravityScale: 1 },
|
|
511
|
+
collider: { shape: "box" },
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
dispose(world: any) {
|
|
517
|
+
if (this.spawnedId !== null) {
|
|
518
|
+
this.world.getObjectManagementSystem()?.deleteEntity(this.world, this.spawnedId, true);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
For the full guide covering `setParent`, async loading patterns, and complete worked examples, see [Runtime Entity Management](./runtime-entity-management).
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
395
528
|
## See also
|
|
396
529
|
|
|
397
530
|
- [Custom Behaviours](./authoring-a-behaviour) — script anatomy and lifecycle
|
|
398
|
-
- [
|
|
531
|
+
- [Behaviour Data Binding](./behaviour-data-binding/) — exposing fields to the inspector
|
|
399
532
|
- [World API](./world-api) — querying entities and components across the scene
|
|
533
|
+
- [Runtime Entity Management](./runtime-entity-management) — addComponent, createComponentNow, setParent, deleteEntity
|
|
@@ -116,7 +116,7 @@ export default class Spinner extends Behaviour {
|
|
|
116
116
|
}
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
See [
|
|
119
|
+
See [Behaviour Data Binding](./behaviour-data-binding/) for the full reference of all input types (`TextInput`, `ColorInput`, `Vector2Input`, `Vector3Input`, `SliderInput`, `CheckboxInput`, `ToggleInput`, `AssetInput`, and more).
|
|
120
120
|
|
|
121
121
|
See [Accessing Components](./accessing-components) to read and mutate built-in components such as `PhysicsComponent`, `AudioComponent`, `AnimationComponent`, `LightComponent`, and `MaterialComponent` from script.
|
|
122
122
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# AssetInput
|
|
2
|
+
|
|
3
|
+
A file picker that lets the user select an asset from the project's `assets/` folder. The inspector renders a file browser button showing the selected filename.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ path: string; type: string }` — read `field.path`.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
Provide the `type` string to categorize the asset. Set `path` to an empty string for "no file selected".
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { Behaviour, type AssetInput } from "@relu-interactives/spatial-ecs";
|
|
15
|
+
|
|
16
|
+
export default class Demo extends Behaviour {
|
|
17
|
+
data = {
|
|
18
|
+
clip: { path: "", type: "audio" } as AssetInput,
|
|
19
|
+
model: { path: "", type: "model" } as AssetInput,
|
|
20
|
+
video: { path: "", type: "video" } as AssetInput,
|
|
21
|
+
texture: { path: "", type: "image" } as AssetInput,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> [!IMPORTANT]
|
|
27
|
+
> Do **not** use `type: "texture"` or `type: "texturemap"` — the inspector treats those as a legacy URL text field rather than the asset file picker. Use `"image"` instead for image/texture assets.
|
|
28
|
+
|
|
29
|
+
## Runtime usage
|
|
30
|
+
|
|
31
|
+
Read the `.path` property. Guard for an empty string (no file selected):
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
init() {
|
|
35
|
+
const path = this.data.clip.path;
|
|
36
|
+
if (!path) return; // no file selected in the inspector
|
|
37
|
+
console.log(path); // e.g. "./assets/sounds/click.mp3"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Common `type` values
|
|
42
|
+
|
|
43
|
+
| `type` | Asset kind |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `"audio"` | Audio files (mp3, wav, ogg, …) |
|
|
46
|
+
| `"image"` | Image files (png, jpg, webp, …) |
|
|
47
|
+
| `"model"` | 3D model files (glb, gltf, …) |
|
|
48
|
+
| `"video"` | Video files (mp4, webm, …) |
|
|
49
|
+
|
|
50
|
+
## Notes
|
|
51
|
+
|
|
52
|
+
- The `type` string is for categorization only — it has no effect at runtime.
|
|
53
|
+
- `path` is relative to the project root (e.g. `"./assets/audio/click.mp3"`).
|
|
54
|
+
- `AssetInput` provides the path only. Load the asset yourself at runtime if needed.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# CheckboxInput
|
|
2
|
+
|
|
3
|
+
A checkbox. The inspector renders a standard checkbox control.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ type: "checkbox"; value: boolean }` — read `.value`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
Declare with a `type: "checkbox"` envelope and an initial `value`:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { Behaviour, type CheckboxInput } from "@relu-interactives/spatial-ecs";
|
|
15
|
+
|
|
16
|
+
export default class Demo extends Behaviour {
|
|
17
|
+
data = {
|
|
18
|
+
visible: { type: "checkbox", value: true } as CheckboxInput,
|
|
19
|
+
castShadow: { type: "checkbox", value: false } as CheckboxInput,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Runtime usage
|
|
25
|
+
|
|
26
|
+
Read the `.value` property:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
onUpdate() {
|
|
30
|
+
if (!this.data.visible.value) return;
|
|
31
|
+
// ... rest of update logic
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Notes
|
|
36
|
+
|
|
37
|
+
- Use `CheckboxInput` for property-style options (e.g. "Cast shadow", "Visible") and [`ToggleInput`](./toggle-input) for simple on/off feature flags.
|
|
38
|
+
- `ToggleInput` is a plain `boolean` and requires no envelope — use it when you don't need the checkbox visual.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# ColorInput
|
|
2
|
+
|
|
3
|
+
A color picker field. The inspector renders a swatch that opens a full color picker on click.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `string` (hex, e.g. `"#ff0000"`)
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Behaviour, type ColorInput } from "@relu-interactives/spatial-ecs";
|
|
13
|
+
|
|
14
|
+
export default class Demo extends Behaviour {
|
|
15
|
+
data = {
|
|
16
|
+
tint: "#ffffff" as ColorInput,
|
|
17
|
+
emissive: "#000000" as ColorInput,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Runtime usage
|
|
23
|
+
|
|
24
|
+
Use the value directly as a hex string:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import * as THREE from "three";
|
|
28
|
+
|
|
29
|
+
init() {
|
|
30
|
+
const color = new THREE.Color(this.data.tint);
|
|
31
|
+
// apply to a material, light, etc.
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Notes
|
|
36
|
+
|
|
37
|
+
- Value must be a valid hex color string (`#rgb`, `#rrggbb`, or `#rrggbbaa`) — the inspector detects the format automatically and renders the color picker.
|
|
38
|
+
- Alpha is not included in the default 6-digit form — use a separate `FloatInput` if you need opacity control.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# ComponentInput
|
|
2
|
+
|
|
3
|
+
An entity + component picker. The inspector renders an entity dropdown and, once an entity is selected, a component-kind filter. Use this when you need direct access to a specific component on another entity.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ type: "component"; componentKind?: ComponentKind; value: Component | null }` — read `field.value`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
Set `componentKind` to pre-filter the picker to a specific component type. Omit it to allow any component.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { Behaviour, type ComponentInput } from "@relu-interactives/spatial-ecs";
|
|
15
|
+
|
|
16
|
+
export default class Demo extends Behaviour {
|
|
17
|
+
data = {
|
|
18
|
+
cam: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
|
|
19
|
+
audio: { type: "component", componentKind: "AudioComponent", value: null } as ComponentInput,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Runtime usage
|
|
25
|
+
|
|
26
|
+
At runtime, `.value` is resolved to the **live component instance**. Cast to the concrete class for full TypeScript autocompletion. Always guard for `null`:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import {
|
|
30
|
+
Behaviour,
|
|
31
|
+
CameraComponent,
|
|
32
|
+
type ComponentInput,
|
|
33
|
+
} from "@relu-interactives/spatial-ecs";
|
|
34
|
+
|
|
35
|
+
export default class FovReader extends Behaviour {
|
|
36
|
+
data = {
|
|
37
|
+
camera: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
onUpdate() {
|
|
41
|
+
const cam = this.data.camera.value as CameraComponent | null;
|
|
42
|
+
if (!cam) return; // no component assigned
|
|
43
|
+
|
|
44
|
+
console.log(cam.fov); // current field of view in degrees
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Mutating the component
|
|
50
|
+
|
|
51
|
+
Mutate the instance directly — the system that owns the component picks up changes next frame:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import {
|
|
55
|
+
Behaviour,
|
|
56
|
+
CameraComponent,
|
|
57
|
+
type ComponentInput,
|
|
58
|
+
type FloatInput,
|
|
59
|
+
} from "@relu-interactives/spatial-ecs";
|
|
60
|
+
|
|
61
|
+
export default class FovAnimator extends Behaviour {
|
|
62
|
+
data = {
|
|
63
|
+
camera: { type: "component", componentKind: "CameraComponent", value: null } as ComponentInput,
|
|
64
|
+
targetFov: 90 as FloatInput,
|
|
65
|
+
speed: 30 as FloatInput,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
onUpdate() {
|
|
69
|
+
const cam = this.data.camera.value as CameraComponent | null;
|
|
70
|
+
if (!cam) return;
|
|
71
|
+
|
|
72
|
+
// Lerp the field of view toward targetFov
|
|
73
|
+
cam.fov += (this.data.targetFov - cam.fov) * this.data.speed * this.deltaTime;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> [!TIP]
|
|
79
|
+
> Always cast to the concrete component type (e.g. `as CameraComponent | null`) for full autocompletion and always guard the null case — the field is `null` until the user picks both an entity and a component in the inspector.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# DropdownInput
|
|
2
|
+
|
|
3
|
+
A select dropdown. The inspector renders a menu populated from the `options` array.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ options: DropdownOption[]; value: string }` — read `field.value`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
Provide the full object including `options` and the initial selected `value`. The editor reads `options` to build the dropdown.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { Behaviour, type DropdownInput } from "@relu-interactives/spatial-ecs";
|
|
15
|
+
|
|
16
|
+
export default class Demo extends Behaviour {
|
|
17
|
+
data = {
|
|
18
|
+
axis: {
|
|
19
|
+
value: "y",
|
|
20
|
+
options: [
|
|
21
|
+
{ label: "X", value: "x" },
|
|
22
|
+
{ label: "Y", value: "y" },
|
|
23
|
+
{ label: "Z", value: "z" },
|
|
24
|
+
],
|
|
25
|
+
} as DropdownInput,
|
|
26
|
+
blendMode: {
|
|
27
|
+
value: "normal",
|
|
28
|
+
options: [
|
|
29
|
+
{ label: "Normal", value: "normal" },
|
|
30
|
+
{ label: "Additive", value: "additive" },
|
|
31
|
+
{ label: "Multiply", value: "multiply" },
|
|
32
|
+
],
|
|
33
|
+
} as DropdownInput,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Runtime usage
|
|
39
|
+
|
|
40
|
+
Read the `.value` property. Cast to a union type for TypeScript narrowing:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
onUpdate() {
|
|
44
|
+
const axis = this.data.axis.value as "x" | "y" | "z";
|
|
45
|
+
this.transform.rotation[axis] += 0.01;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Notes
|
|
50
|
+
|
|
51
|
+
- Always include the full `options` array in the inline default — the editor needs it to render the dropdown.
|
|
52
|
+
- `label` is what the user sees; `value` is what you read at runtime.
|
|
53
|
+
- The initial `value` must match one of the option `value` strings.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# EntityInput
|
|
2
|
+
|
|
3
|
+
An entity picker. The inspector renders a dropdown populated with all named entities in the scene.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ type: "entity"; value: WorldEntityView | null }` — read `field.value`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Behaviour, type EntityInput } from "@relu-interactives/spatial-ecs";
|
|
13
|
+
|
|
14
|
+
export default class Demo extends Behaviour {
|
|
15
|
+
data = {
|
|
16
|
+
target: { type: "entity", value: null } as EntityInput,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Runtime usage
|
|
22
|
+
|
|
23
|
+
At runtime, `.value` is resolved to a **`WorldEntityView`** — not a raw ID. Always guard for `null` (no entity selected):
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { type WorldEntityView } from "@relu-interactives/spatial-ecs";
|
|
27
|
+
|
|
28
|
+
onUpdate() {
|
|
29
|
+
const target = this.data.target.value as WorldEntityView | null;
|
|
30
|
+
if (!target) return; // no entity assigned in the inspector
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## WorldEntityView shape
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
type WorldEntityView = {
|
|
38
|
+
name: string; // entity name from NameComponent
|
|
39
|
+
entityId: number; // runtime entity ID
|
|
40
|
+
type: string; // entity type ("mesh", "camera", "light", …)
|
|
41
|
+
object: THREE.Object3D | null; // live three.js scene object
|
|
42
|
+
components: Component[]; // all components attached to this entity
|
|
43
|
+
};
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Reading entity data
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
onUpdate() {
|
|
50
|
+
const target = this.data.target.value as WorldEntityView | null;
|
|
51
|
+
if (!target) return;
|
|
52
|
+
|
|
53
|
+
// Name and ID
|
|
54
|
+
console.log(target.name); // e.g. "Camera"
|
|
55
|
+
console.log(target.entityId); // runtime numeric ID
|
|
56
|
+
|
|
57
|
+
// Access the three.js object directly
|
|
58
|
+
const obj = target.object;
|
|
59
|
+
if (obj) {
|
|
60
|
+
console.log(obj.position); // THREE.Vector3
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Moving another entity from a script
|
|
66
|
+
|
|
67
|
+
Use the entity's `components` array to find and mutate a specific component:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import {
|
|
71
|
+
Behaviour,
|
|
72
|
+
TransformComponent,
|
|
73
|
+
type EntityInput,
|
|
74
|
+
type WorldEntityView,
|
|
75
|
+
type FloatInput,
|
|
76
|
+
} from "@relu-interactives/spatial-ecs";
|
|
77
|
+
|
|
78
|
+
export default class Mover extends Behaviour {
|
|
79
|
+
data = {
|
|
80
|
+
target: { type: "entity", value: null } as EntityInput,
|
|
81
|
+
speed: 5 as FloatInput,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
onUpdate() {
|
|
85
|
+
const target = this.data.target.value as WorldEntityView | null;
|
|
86
|
+
if (!target) return;
|
|
87
|
+
|
|
88
|
+
const transform = target.components.find(
|
|
89
|
+
(c) => c instanceof TransformComponent,
|
|
90
|
+
) as TransformComponent | undefined;
|
|
91
|
+
|
|
92
|
+
if (transform) {
|
|
93
|
+
transform.position.x += this.data.speed * this.deltaTime;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
> [!TIP]
|
|
100
|
+
> Always guard with `if (!target) return;` — the field is `null` until the user picks an entity in the inspector, and may be `null` in freshly opened scenes.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# FloatInput
|
|
2
|
+
|
|
3
|
+
A numeric input field. The inspector renders a number input that the user can type into or scrub with a drag.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `number`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Behaviour, type FloatInput } from "@relu-interactives/spatial-ecs";
|
|
13
|
+
|
|
14
|
+
export default class Demo extends Behaviour {
|
|
15
|
+
data = {
|
|
16
|
+
speed: 1 as FloatInput,
|
|
17
|
+
mass: 0.5 as FloatInput,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Runtime usage
|
|
23
|
+
|
|
24
|
+
Use the value directly as a `number`:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
onUpdate() {
|
|
28
|
+
this.transform.rotation.y += this.data.speed * this.deltaTime;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Notes
|
|
33
|
+
|
|
34
|
+
- Supports any finite `number` — positive, negative, or fractional.
|
|
35
|
+
- Use [`SliderInput`](./slider-input) when you want to clamp the value to a min/max range.
|