@relu-interactives/spatial-ecs 0.2.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 +125 -0
- package/dist/System-rXAmagXA.d.cts +659 -0
- package/dist/System-rXAmagXA.d.ts +659 -0
- package/dist/Video-CDemv74U.d.cts +1261 -0
- package/dist/Video-ChKV1UI7.d.ts +1261 -0
- package/dist/assets/draco/draco_decoder.js +34 -0
- package/dist/assets/draco/draco_decoder.wasm +0 -0
- package/dist/assets/draco/draco_wasm_wrapper.js +117 -0
- package/dist/chunk-AYEF3X2P.js +223 -0
- package/dist/chunk-AYEF3X2P.js.map +1 -0
- package/dist/chunk-MAWBTMCG.js +1722 -0
- package/dist/chunk-MAWBTMCG.js.map +1 -0
- package/dist/chunk-NFDTIYR4.js +248 -0
- package/dist/chunk-NFDTIYR4.js.map +1 -0
- package/dist/chunk-OY7ZODZP.js +16 -0
- package/dist/chunk-OY7ZODZP.js.map +1 -0
- package/dist/chunk-P2YDX5DB.js +3304 -0
- package/dist/chunk-P2YDX5DB.js.map +1 -0
- package/dist/chunk-QHILSPT4.js +3 -0
- package/dist/chunk-QHILSPT4.js.map +1 -0
- package/dist/chunk-XWIEEJ7Z.js +1315 -0
- package/dist/chunk-XWIEEJ7Z.js.map +1 -0
- package/dist/components/index.cjs +1745 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +4 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +4 -0
- package/dist/components/index.js.map +1 -0
- package/dist/docs/api/Behaviour/classes/Behaviour.md +554 -0
- package/dist/docs/api/Behaviour/index.md +15 -0
- package/dist/docs/api/Component/classes/Component.md +57 -0
- package/dist/docs/api/Component/index.md +15 -0
- package/dist/docs/api/components/classes/AnimationComponent.md +318 -0
- package/dist/docs/api/components/classes/AudioComponent.md +114 -0
- package/dist/docs/api/components/classes/CameraComponent.md +59 -0
- package/dist/docs/api/components/classes/EntityType.md +48 -0
- package/dist/docs/api/components/classes/Environment.md +47 -0
- package/dist/docs/api/components/classes/ImageComponent.md +57 -0
- package/dist/docs/api/components/classes/ImageTarget.md +60 -0
- package/dist/docs/api/components/classes/ImageTargetAnchor.md +48 -0
- package/dist/docs/api/components/classes/LightComponent.md +70 -0
- package/dist/docs/api/components/classes/MaterialComponent.md +181 -0
- package/dist/docs/api/components/classes/MeshComponent.md +48 -0
- package/dist/docs/api/components/classes/MeshGeometryComponent.md +64 -0
- package/dist/docs/api/components/classes/ModelComponent.md +49 -0
- package/dist/docs/api/components/classes/Name.md +46 -0
- package/dist/docs/api/components/classes/Object3DRef.md +54 -0
- package/dist/docs/api/components/classes/ParentId.md +47 -0
- package/dist/docs/api/components/classes/PhysicsComponent.md +82 -0
- package/dist/docs/api/components/classes/Postprocessing.md +49 -0
- package/dist/docs/api/components/classes/ScriptComponent.md +54 -0
- package/dist/docs/api/components/classes/Selectable.md +46 -0
- package/dist/docs/api/components/classes/SelectionTransformState.md +54 -0
- package/dist/docs/api/components/classes/SpriteComponent.md +55 -0
- package/dist/docs/api/components/classes/TransformComponent.md +197 -0
- package/dist/docs/api/components/classes/VideoComponent.md +123 -0
- package/dist/docs/api/components/functions/normalizePhysicsState.md +23 -0
- package/dist/docs/api/components/index.md +94 -0
- package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +42 -0
- package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +45 -0
- package/dist/docs/api/components/type-aliases/CameraProjection.md +15 -0
- package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +15 -0
- package/dist/docs/api/components/type-aliases/ColliderShape.md +15 -0
- package/dist/docs/api/components/type-aliases/ColliderState.md +62 -0
- package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +27 -0
- package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +37 -0
- package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +34 -0
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentState.md +29 -0
- package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +25 -0
- package/dist/docs/api/components/type-aliases/ImageTargetReference.md +33 -0
- package/dist/docs/api/components/type-aliases/LightValueState.md +41 -0
- package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +15 -0
- package/dist/docs/api/components/type-aliases/MaterialValueState.md +75 -0
- package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +13 -0
- package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +33 -0
- package/dist/docs/api/components/type-aliases/PhysicsState.md +25 -0
- package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +25 -0
- package/dist/docs/api/components/type-aliases/PostprocessingState.md +164 -0
- package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +25 -0
- package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +23 -0
- package/dist/docs/api/components/type-aliases/RigidbodyState.md +53 -0
- package/dist/docs/api/components/type-aliases/RigidbodyType.md +19 -0
- package/dist/docs/api/components/type-aliases/ScriptEntry.md +38 -0
- package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +15 -0
- package/dist/docs/api/components/type-aliases/TransformData.md +27 -0
- package/dist/docs/api/components/type-aliases/TransformModeValue.md +15 -0
- package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +15 -0
- package/dist/docs/api/components/type-aliases/Vec3.md +27 -0
- package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +13 -0
- package/dist/docs/api/index/classes/AnimationStateMachine.md +201 -0
- package/dist/docs/api/index/classes/AnimationStateManager.md +253 -0
- package/dist/docs/api/index/classes/AnimationSystem.md +68 -0
- package/dist/docs/api/index/classes/AudioSystem.md +98 -0
- package/dist/docs/api/index/classes/CameraSyncSystem.md +49 -0
- package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +75 -0
- package/dist/docs/api/index/classes/InputSystem.md +449 -0
- package/dist/docs/api/index/classes/LightSyncSystem.md +49 -0
- package/dist/docs/api/index/classes/MaterialSyncSystem.md +67 -0
- package/dist/docs/api/index/classes/MeshGeometrySystem.md +49 -0
- package/dist/docs/api/index/classes/ObjectManagementSystem.md +298 -0
- package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +49 -0
- package/dist/docs/api/index/classes/PhysicsSyncSystem.md +83 -0
- package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +80 -0
- package/dist/docs/api/index/classes/RenderSystem.md +64 -0
- package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +83 -0
- package/dist/docs/api/index/classes/TransformSyncSystem.md +49 -0
- package/dist/docs/api/index/classes/VideoSystem.md +97 -0
- package/dist/docs/api/index/classes/World.md +1405 -0
- package/dist/docs/api/index/functions/createAnimationComponent.md +28 -0
- package/dist/docs/api/index/functions/createAudioComponent.md +32 -0
- package/dist/docs/api/index/functions/createCameraComponent.md +28 -0
- package/dist/docs/api/index/functions/createEntityTypeComponent.md +28 -0
- package/dist/docs/api/index/functions/createEnvironmentComponent.md +28 -0
- package/dist/docs/api/index/functions/createImageComponent.md +28 -0
- package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +28 -0
- package/dist/docs/api/index/functions/createImageTargetComponent.md +28 -0
- package/dist/docs/api/index/functions/createLightComponent.md +28 -0
- package/dist/docs/api/index/functions/createMaterialComponent.md +28 -0
- package/dist/docs/api/index/functions/createMeshComponent.md +28 -0
- package/dist/docs/api/index/functions/createMeshGeometryComponent.md +28 -0
- package/dist/docs/api/index/functions/createModelComponent.md +28 -0
- package/dist/docs/api/index/functions/createNameComponent.md +28 -0
- package/dist/docs/api/index/functions/createObject3DRefComponent.md +28 -0
- package/dist/docs/api/index/functions/createParentIdComponent.md +28 -0
- package/dist/docs/api/index/functions/createPhysicsComponent.md +30 -0
- package/dist/docs/api/index/functions/createPostprocessingComponent.md +28 -0
- package/dist/docs/api/index/functions/createScriptComponent.md +28 -0
- package/dist/docs/api/index/functions/createSelectableComponent.md +28 -0
- package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +28 -0
- package/dist/docs/api/index/functions/createSpriteComponent.md +28 -0
- package/dist/docs/api/index/functions/createTransformComponent.md +28 -0
- package/dist/docs/api/index/functions/createVideoComponent.md +28 -0
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +28 -0
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +28 -0
- package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +23 -0
- package/dist/docs/api/index/functions/registerDefaultFactories.md +23 -0
- package/dist/docs/api/index/index.md +249 -0
- package/dist/docs/api/index/interfaces/EcsSystem.md +50 -0
- package/dist/docs/api/index/interfaces/StateMachine.md +26 -0
- package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +25 -0
- package/dist/docs/api/index/type-aliases/ComponentFactory.md +25 -0
- package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +37 -0
- package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +26 -0
- package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +25 -0
- package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +23 -0
- package/dist/docs/api/index/type-aliases/KeyboardKey.md +13 -0
- package/dist/docs/api/index/type-aliases/MouseButton.md +13 -0
- package/dist/docs/api/index/type-aliases/SelectionContext.md +31 -0
- package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +13 -0
- package/dist/docs/api/index/variables/KeyboardKeys.md +195 -0
- package/dist/docs/api/index.md +15 -0
- package/dist/docs/api/typedoc-sidebar.json +1 -0
- package/dist/docs/api/types/index.md +34 -0
- package/dist/docs/api/types/type-aliases/AssetInput.md +23 -0
- package/dist/docs/api/types/type-aliases/CheckboxInput.md +13 -0
- package/dist/docs/api/types/type-aliases/ColorInput.md +13 -0
- package/dist/docs/api/types/type-aliases/ComponentInput.md +52 -0
- package/dist/docs/api/types/type-aliases/ComponentKind.md +37 -0
- package/dist/docs/api/types/type-aliases/DropdownInput.md +23 -0
- package/dist/docs/api/types/type-aliases/DropdownOption.md +23 -0
- package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +15 -0
- package/dist/docs/api/types/type-aliases/EcsEntityKind.md +35 -0
- package/dist/docs/api/types/type-aliases/EntityId.md +16 -0
- package/dist/docs/api/types/type-aliases/EntityInput.md +23 -0
- package/dist/docs/api/types/type-aliases/FloatInput.md +13 -0
- package/dist/docs/api/types/type-aliases/IntersectionResult.md +29 -0
- package/dist/docs/api/types/type-aliases/ParentLookup.md +26 -0
- package/dist/docs/api/types/type-aliases/SelectionListener.md +25 -0
- package/dist/docs/api/types/type-aliases/SliderInput.md +27 -0
- package/dist/docs/api/types/type-aliases/TextInput.md +13 -0
- package/dist/docs/api/types/type-aliases/ToggleInput.md +13 -0
- package/dist/docs/api/types/type-aliases/Vec3.md +23 -0
- package/dist/docs/api/types/type-aliases/Vector2Input.md +23 -0
- package/dist/docs/api/types/type-aliases/Vector3Input.md +25 -0
- package/dist/docs/api/types/type-aliases/WorldEntityView.md +17 -0
- package/dist/docs/guide/accessing-components.md +399 -0
- package/dist/docs/guide/authoring-a-behaviour.md +166 -0
- package/dist/docs/guide/behaviour-lifecycle.md +43 -0
- package/dist/docs/guide/component-catalog.md +59 -0
- package/dist/docs/guide/components/_sidebar.json +78 -0
- package/dist/docs/guide/components/animation.md +171 -0
- package/dist/docs/guide/components/audio.md +181 -0
- package/dist/docs/guide/components/camera.md +179 -0
- package/dist/docs/guide/components/entity-type.md +141 -0
- package/dist/docs/guide/components/image-target-anchor.md +103 -0
- package/dist/docs/guide/components/image-target.md +122 -0
- package/dist/docs/guide/components/image.md +146 -0
- package/dist/docs/guide/components/light.md +157 -0
- package/dist/docs/guide/components/material.md +161 -0
- package/dist/docs/guide/components/mesh-geometry.md +153 -0
- package/dist/docs/guide/components/mesh.md +151 -0
- package/dist/docs/guide/components/model.md +96 -0
- package/dist/docs/guide/components/name.md +121 -0
- package/dist/docs/guide/components/object3d-ref.md +115 -0
- package/dist/docs/guide/components/parent-id.md +108 -0
- package/dist/docs/guide/components/physics.md +163 -0
- package/dist/docs/guide/components/script.md +142 -0
- package/dist/docs/guide/components/sprite.md +155 -0
- package/dist/docs/guide/components/transform.md +155 -0
- package/dist/docs/guide/components/video.md +153 -0
- package/dist/docs/guide/concepts.md +34 -0
- package/dist/docs/guide/getting-started/creating-objects.md +50 -0
- package/dist/docs/guide/getting-started/editing-objects.md +62 -0
- package/dist/docs/guide/getting-started/editor/assets-browser.md +55 -0
- package/dist/docs/guide/getting-started/editor/hierarchy.md +47 -0
- package/dist/docs/guide/getting-started/editor/index.md +16 -0
- package/dist/docs/guide/getting-started/editor/inspector.md +36 -0
- package/dist/docs/guide/getting-started/editor/modules.md +35 -0
- package/dist/docs/guide/getting-started/editor/scene-inspector.md +64 -0
- package/dist/docs/guide/getting-started/editor/toolbar.md +39 -0
- package/dist/docs/guide/getting-started/editor/viewport.md +43 -0
- package/dist/docs/guide/getting-started/first-launch.md +17 -0
- package/dist/docs/guide/getting-started/index.md +37 -0
- package/dist/docs/guide/getting-started/installation.md +59 -0
- package/dist/docs/guide/getting-started/preview-and-test.md +55 -0
- package/dist/docs/guide/getting-started/project-types/3d.md +30 -0
- package/dist/docs/guide/getting-started/project-types/ar.md +6 -0
- package/dist/docs/guide/getting-started/project-types/face-tracking.md +6 -0
- package/dist/docs/guide/getting-started/project-types/image-tracking.md +42 -0
- package/dist/docs/guide/getting-started/project-types/index.md +25 -0
- package/dist/docs/guide/getting-started/project-types/vr.md +6 -0
- package/dist/docs/guide/getting-started/projects.md +53 -0
- package/dist/docs/guide/getting-started/shortcuts.md +43 -0
- package/dist/docs/guide/inspector-data-binding.md +367 -0
- package/dist/docs/guide/reading-input.md +202 -0
- package/dist/docs/guide/scene/environment.md +101 -0
- package/dist/docs/guide/scene/index.md +36 -0
- package/dist/docs/guide/scene/postprocessing.md +108 -0
- package/dist/docs/guide/spawning/ambient-light.md +28 -0
- package/dist/docs/guide/spawning/area-light.md +32 -0
- package/dist/docs/guide/spawning/audio.md +42 -0
- package/dist/docs/guide/spawning/camera.md +50 -0
- package/dist/docs/guide/spawning/capsule.md +29 -0
- package/dist/docs/guide/spawning/cube.md +31 -0
- package/dist/docs/guide/spawning/cylinder.md +29 -0
- package/dist/docs/guide/spawning/directional-light.md +32 -0
- package/dist/docs/guide/spawning/empty.md +31 -0
- package/dist/docs/guide/spawning/image-target.md +48 -0
- package/dist/docs/guide/spawning/image.md +33 -0
- package/dist/docs/guide/spawning/index.md +79 -0
- package/dist/docs/guide/spawning/model.md +31 -0
- package/dist/docs/guide/spawning/plane.md +31 -0
- package/dist/docs/guide/spawning/point-light.md +32 -0
- package/dist/docs/guide/spawning/sphere.md +29 -0
- package/dist/docs/guide/spawning/spot-light.md +32 -0
- package/dist/docs/guide/spawning/sprite.md +31 -0
- package/dist/docs/guide/spawning/video.md +53 -0
- package/dist/docs/guide/system-overview.md +73 -0
- package/dist/docs/guide/systems/_sidebar.json +66 -0
- package/dist/docs/guide/systems/animation-system.md +32 -0
- package/dist/docs/guide/systems/audio-system.md +28 -0
- package/dist/docs/guide/systems/camera-sync-system.md +31 -0
- package/dist/docs/guide/systems/environment-sync-system.md +31 -0
- package/dist/docs/guide/systems/input-system.md +217 -0
- package/dist/docs/guide/systems/light-sync-system.md +29 -0
- package/dist/docs/guide/systems/material-sync-system.md +32 -0
- package/dist/docs/guide/systems/mesh-geometry-system.md +40 -0
- package/dist/docs/guide/systems/object-management-system.md +38 -0
- package/dist/docs/guide/systems/object-visibility-system.md +26 -0
- package/dist/docs/guide/systems/physics-sync-system.md +56 -0
- package/dist/docs/guide/systems/postprocessing-sync-system.md +43 -0
- package/dist/docs/guide/systems/render-system.md +22 -0
- package/dist/docs/guide/systems/script-behaviour-system.md +59 -0
- package/dist/docs/guide/systems/transform-sync-system.md +29 -0
- package/dist/docs/guide/systems/video-system.md +30 -0
- package/dist/docs/guide/world-api.md +405 -0
- package/dist/factories/index.cjs +3077 -0
- package/dist/factories/index.cjs.map +1 -0
- package/dist/factories/index.d.cts +69 -0
- package/dist/factories/index.d.ts +69 -0
- package/dist/factories/index.js +6 -0
- package/dist/factories/index.js.map +1 -0
- package/dist/index-B4-YyUNR.d.cts +73 -0
- package/dist/index-BZUOKeTO.d.ts +73 -0
- package/dist/index.cjs +8584 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +283 -0
- package/dist/index.d.ts +283 -0
- package/dist/index.js +1729 -0
- package/dist/index.js.map +1 -0
- package/dist/systems/index.cjs +5119 -0
- package/dist/systems/index.cjs.map +1 -0
- package/dist/systems/index.d.cts +200 -0
- package/dist/systems/index.d.ts +200 -0
- package/dist/systems/index.js +6 -0
- package/dist/systems/index.js.map +1 -0
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +3 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/worldSnapshotUtils.cjs +259 -0
- package/dist/worldSnapshotUtils.cjs.map +1 -0
- package/dist/worldSnapshotUtils.d.cts +3 -0
- package/dist/worldSnapshotUtils.d.ts +3 -0
- package/dist/worldSnapshotUtils.js +4 -0
- package/dist/worldSnapshotUtils.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Object3D Reference
|
|
2
|
+
|
|
3
|
+
Wraps the live `THREE.Object3D` for an entity. Almost every entity that renders to the scene carries an `Object3DRef` so transform sync, selection, and parenting systems can manipulate the underlying object. The `object` reference may be replaced when assets finish loading. Read it fresh inside system/script hooks rather than caching it across frames.
|
|
4
|
+
|
|
5
|
+
> **Managed by:** [`ObjectManagementSystem`](../systems/object-management-system) (hierarchy), [`ObjectVisibilitySystem`](../systems/object-visibility-system) (visibility)
|
|
6
|
+
|
|
7
|
+
## Properties
|
|
8
|
+
|
|
9
|
+
| Property | Type | Description |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `object` | `THREE.Object3D` | Live three.js object placed in the scene graph. May be replaced when assets finish loading. |
|
|
12
|
+
| `visibility` | `boolean` | Whether the object is currently visible. Mirrors `object.visible` and is preserved across reloads. |
|
|
13
|
+
|
|
14
|
+
## API reference
|
|
15
|
+
|
|
16
|
+
- Class: [`Object3DRef`](../../api/components/classes/Object3DRef.md)
|
|
17
|
+
- Source: [`core/components/Object3DRef.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Object3DRef.ts)
|
|
18
|
+
|
|
19
|
+
## Scripting examples
|
|
20
|
+
|
|
21
|
+
::: tip Component access patterns
|
|
22
|
+
Use `this.getComponent(X)` to access a component on the **entity this script is attached to**. Use `this.world.getEntityByName` to find another entity by name, then `this.world.getComponent` to read its component:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// Component on the entity this script is on
|
|
26
|
+
const ref = this.getComponent(Object3DRef);
|
|
27
|
+
|
|
28
|
+
// Component on another entity, found by its scene name
|
|
29
|
+
const other = this.world.getEntityByName("Obstacle");
|
|
30
|
+
if (other) {
|
|
31
|
+
const ref = this.world.getComponent(other.entityId, Object3DRef);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
:::
|
|
35
|
+
|
|
36
|
+
### Toggle visibility from the inspector
|
|
37
|
+
|
|
38
|
+
Expose a boolean that shows or hides the entity's scene object at runtime.
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { Behaviour, Object3DRef } from "@relu-interactives/spatial-ecs";
|
|
42
|
+
import type { BooleanInput } from "@relu-interactives/spatial-ecs";
|
|
43
|
+
|
|
44
|
+
export default class VisibilityDriver extends Behaviour {
|
|
45
|
+
data = {
|
|
46
|
+
visible: true as BooleanInput,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
protected onUpdate() {
|
|
50
|
+
const ref = this.getComponent(Object3DRef);
|
|
51
|
+
if (ref) ref.visibility = this.data.visible;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Flash the object on and off
|
|
57
|
+
|
|
58
|
+
Alternate visibility every half-second, useful for damage flashes or blinking pickups.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { Behaviour, Object3DRef } from "@relu-interactives/spatial-ecs";
|
|
62
|
+
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
63
|
+
|
|
64
|
+
export default class ObjectFlash extends Behaviour {
|
|
65
|
+
data = {
|
|
66
|
+
flashRate: 2 as FloatInput, // flashes per second
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
private elapsed = 0;
|
|
70
|
+
|
|
71
|
+
protected onUpdate() {
|
|
72
|
+
this.elapsed += this.deltaTime;
|
|
73
|
+
const ref = this.getComponent(Object3DRef);
|
|
74
|
+
if (!ref) return;
|
|
75
|
+
|
|
76
|
+
// Alternate visibility based on sine wave sign
|
|
77
|
+
ref.visibility = Math.sin(this.elapsed * this.data.flashRate * Math.PI) >= 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Via `EntityInput` in the inspector
|
|
83
|
+
|
|
84
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import {
|
|
88
|
+
Behaviour,
|
|
89
|
+
Object3DRef,
|
|
90
|
+
type EntityInput,
|
|
91
|
+
type WorldEntityView,
|
|
92
|
+
} from "@relu-interactives/spatial-ecs";
|
|
93
|
+
|
|
94
|
+
export default class Example extends Behaviour {
|
|
95
|
+
data = {
|
|
96
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
protected onUpdate() {
|
|
100
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
101
|
+
if (!entity) return;
|
|
102
|
+
|
|
103
|
+
const ref = this.world.getComponent(
|
|
104
|
+
entity.entityId,
|
|
105
|
+
Object3DRef,
|
|
106
|
+
) as Object3DRef | null;
|
|
107
|
+
if (!ref) return;
|
|
108
|
+
// Use the component on the picked entity.
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
::: tip Do not cache the object reference
|
|
114
|
+
The underlying `object` on `Object3DRef` may be replaced when assets finish loading. Always read `ref.object` fresh inside system/script hooks rather than caching it in a class field.
|
|
115
|
+
:::
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Parent
|
|
2
|
+
|
|
3
|
+
Records the parent entity id for hierarchical scene graphs. `null` means the entity is at the world root. The `ObjectManagementSystem` reconciles scene-graph parenting from this component each frame.
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
| Property | Type | Description |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `value` | `EntityId \| null` | Parent entity id, or `null` for root-level entities. |
|
|
10
|
+
|
|
11
|
+
## API reference
|
|
12
|
+
|
|
13
|
+
- Class: [`ParentId`](../../api/components/classes/ParentId.md)
|
|
14
|
+
- Source: [`core/components/ParentId.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/ParentId.ts)
|
|
15
|
+
|
|
16
|
+
## Scripting examples
|
|
17
|
+
|
|
18
|
+
::: tip Component access patterns
|
|
19
|
+
Use `this.getComponent(X)` to access a component on the **entity this script is attached to**. Use `this.world.getEntityByName` to find another entity by name, then `this.world.getComponent` to read its component:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// Component on the entity this script is on
|
|
23
|
+
const parentId = this.getComponent(ParentId);
|
|
24
|
+
|
|
25
|
+
// Component on another entity, found by its scene name
|
|
26
|
+
const other = this.world.getEntityByName("Prop");
|
|
27
|
+
if (other) {
|
|
28
|
+
const parentId = this.world.getComponent(other.entityId, ParentId);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
:::
|
|
33
|
+
|
|
34
|
+
### Detach an entity to the world root on key press
|
|
35
|
+
|
|
36
|
+
Set `ParentId.value` to `null` to reparent the entity to the scene root. The `ObjectManagementSystem` reconciles the actual scene-graph hierarchy every frame.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { Behaviour, ParentId, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
40
|
+
|
|
41
|
+
export default class DetachOnKey extends Behaviour {
|
|
42
|
+
protected onUpdate() {
|
|
43
|
+
if (this.world.getKeyDown(KeyboardKeys.D)) {
|
|
44
|
+
const parent = this.getComponent(ParentId);
|
|
45
|
+
if (parent) parent.value = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Reparent to a specific entity
|
|
52
|
+
|
|
53
|
+
Assign a new parent entity ID to move the entity (and its children) under a different part of the hierarchy at runtime.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { Behaviour, ParentId, Name, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
57
|
+
import type { StringInput } from "@relu-interactives/spatial-ecs";
|
|
58
|
+
|
|
59
|
+
export default class Reparenter extends Behaviour {
|
|
60
|
+
data = {
|
|
61
|
+
newParentName: "Holder" as StringInput,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
protected onUpdate() {
|
|
65
|
+
if (!this.world.getKeyDown(KeyboardKeys.R)) return;
|
|
66
|
+
|
|
67
|
+
// Find the target parent entity by name
|
|
68
|
+
const parentEntity = this.world.getEntityByName(this.data.newParentName);
|
|
69
|
+
const parent = this.getComponent(ParentId);
|
|
70
|
+
if (parent) parent.value = id;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Via `EntityInput` in the inspector
|
|
76
|
+
|
|
77
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import {
|
|
81
|
+
Behaviour,
|
|
82
|
+
ParentId,
|
|
83
|
+
type EntityInput,
|
|
84
|
+
type WorldEntityView,
|
|
85
|
+
} from "@relu-interactives/spatial-ecs";
|
|
86
|
+
|
|
87
|
+
export default class Example extends Behaviour {
|
|
88
|
+
data = {
|
|
89
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
protected onUpdate() {
|
|
93
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
94
|
+
if (!entity) return;
|
|
95
|
+
|
|
96
|
+
const parentId = this.world.getComponent(
|
|
97
|
+
entity.entityId,
|
|
98
|
+
ParentId,
|
|
99
|
+
) as ParentId | null;
|
|
100
|
+
if (!parentId) return;
|
|
101
|
+
// Use the component on the picked entity.
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
::: tip ObjectManagementSystem
|
|
107
|
+
Do not call `THREE.Object3D.add` / `remove` directly to reparent. Write to `ParentId.value` instead — the `ObjectManagementSystem` reads this every frame and reconciles the scene graph. This keeps the ECS hierarchy state consistent with the three.js scene graph.
|
|
108
|
+
:::
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Physics
|
|
2
|
+
|
|
3
|
+
Combined rigid body and collider component backed by Rapier. `values.rigidbody.type` is one of `dynamic`, `fixed`, `kinematicPosition`, or `kinematicVelocity`. Per-axis translation/rotation locks constrain motion (e.g. lock Y rotation for top-down characters). Supported collider shapes: `cuboid`, `ball`, `capsule`, `cylinder`, `trimesh`. Set `values.collider.isSensor` to receive collision events without producing a physical response.
|
|
4
|
+
|
|
5
|
+
> **Managed by:** [`PhysicsSyncSystem`](../systems/physics-sync-system)
|
|
6
|
+
|
|
7
|
+
## Editor inspector
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Properties
|
|
12
|
+
|
|
13
|
+
| Property | Type | Description |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `values` | `PhysicsState` | Authoring state containing `rigidbody` and `collider` sub-states. Saved with the project. |
|
|
16
|
+
| `values.rigidbody` | `RigidbodyState` | Rigid body authoring state (type, gravity scale, locks, etc.). |
|
|
17
|
+
| `values.collider` | `ColliderState` | Collider authoring state (shape, size, sensor flag, etc.). |
|
|
18
|
+
| `rigidBody` | `RapierRigidBody \| null` | Live Rapier rigid body. Recreated when the project loads; `null` until physics is initialized. |
|
|
19
|
+
| `collider` | `RapierCollider \| null` | Live Rapier collider. Recreated when the project loads; `null` until physics is initialized. |
|
|
20
|
+
|
|
21
|
+
## API reference
|
|
22
|
+
|
|
23
|
+
- Class: [`PhysicsComponent`](../../api/components/classes/PhysicsComponent.md)
|
|
24
|
+
- Source: [`core/components/Physics.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Physics.ts)
|
|
25
|
+
|
|
26
|
+
## Scripting examples
|
|
27
|
+
|
|
28
|
+
::: tip Component access patterns
|
|
29
|
+
Use `this.getComponent(X)` to access a component on the **entity this script is attached to**. Use `this.world.getEntityByName` to find another entity by name, then `this.world.getComponent` to read its component:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
// Component on the entity this script is on
|
|
33
|
+
const physics = this.getComponent(PhysicsComponent);
|
|
34
|
+
|
|
35
|
+
// Component on another entity, found by its scene name
|
|
36
|
+
const other = this.world.getEntityByName("Crate");
|
|
37
|
+
if (other) {
|
|
38
|
+
const physics = this.world.getComponent(other.entityId, PhysicsComponent);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
:::
|
|
42
|
+
|
|
43
|
+
### Apply a jump impulse
|
|
44
|
+
|
|
45
|
+
Apply a one-shot upward impulse to a dynamic rigid body when the player presses Space.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { Behaviour, PhysicsComponent, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
49
|
+
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
50
|
+
|
|
51
|
+
export default class Jumper extends Behaviour {
|
|
52
|
+
data = {
|
|
53
|
+
jumpForce: 5 as FloatInput,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
protected onUpdate() {
|
|
57
|
+
const physics = this.getComponent(PhysicsComponent);
|
|
58
|
+
if (!physics?.rigidBody) return;
|
|
59
|
+
|
|
60
|
+
if (this.world.getKeyDown(KeyboardKeys.Space)) {
|
|
61
|
+
physics.rigidBody.applyImpulse({ x: 0, y: this.data.jumpForce, z: 0 }, true);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Move a kinematic body with arrow keys
|
|
68
|
+
|
|
69
|
+
Displace a `kinematicPosition` body each frame using the Rapier `setNextKinematicTranslation` API.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { Behaviour, PhysicsComponent, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
73
|
+
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
74
|
+
|
|
75
|
+
export default class KinematicMover extends Behaviour {
|
|
76
|
+
data = {
|
|
77
|
+
speed: 3 as FloatInput,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
protected onUpdate() {
|
|
81
|
+
const physics = this.getComponent(PhysicsComponent);
|
|
82
|
+
if (!physics?.rigidBody) return;
|
|
83
|
+
|
|
84
|
+
const pos = physics.rigidBody.translation();
|
|
85
|
+
let dx = 0;
|
|
86
|
+
let dz = 0;
|
|
87
|
+
|
|
88
|
+
if (this.world.getKey(KeyboardKeys.ArrowLeft)) dx -= this.data.speed * this.deltaTime;
|
|
89
|
+
if (this.world.getKey(KeyboardKeys.ArrowRight)) dx += this.data.speed * this.deltaTime;
|
|
90
|
+
if (this.world.getKey(KeyboardKeys.ArrowUp)) dz -= this.data.speed * this.deltaTime;
|
|
91
|
+
if (this.world.getKey(KeyboardKeys.ArrowDown)) dz += this.data.speed * this.deltaTime;
|
|
92
|
+
|
|
93
|
+
physics.rigidBody.setNextKinematicTranslation({
|
|
94
|
+
x: pos.x + dx,
|
|
95
|
+
y: pos.y,
|
|
96
|
+
z: pos.z + dz,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Via `ComponentInput` in the inspector
|
|
103
|
+
|
|
104
|
+
You can also pick this component from the inspector using a `ComponentInput` field. Assign any entity in the inspector and the field resolves to the live `PhysicsComponent` instance at runtime.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import {
|
|
108
|
+
Behaviour,
|
|
109
|
+
PhysicsComponent,
|
|
110
|
+
type ComponentInput,
|
|
111
|
+
} from "@relu-interactives/spatial-ecs";
|
|
112
|
+
|
|
113
|
+
export default class Example extends Behaviour {
|
|
114
|
+
data = {
|
|
115
|
+
targetPhysics: {
|
|
116
|
+
type: "component",
|
|
117
|
+
value: null,
|
|
118
|
+
} as unknown as ComponentInput,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
protected onUpdate() {
|
|
122
|
+
const physics = this.data.targetPhysics.value as PhysicsComponent | null;
|
|
123
|
+
if (!physics) return;
|
|
124
|
+
// Use the live component instance.
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Via `EntityInput` in the inspector
|
|
130
|
+
|
|
131
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import {
|
|
135
|
+
Behaviour,
|
|
136
|
+
PhysicsComponent,
|
|
137
|
+
type EntityInput,
|
|
138
|
+
type WorldEntityView,
|
|
139
|
+
} from "@relu-interactives/spatial-ecs";
|
|
140
|
+
|
|
141
|
+
export default class Example extends Behaviour {
|
|
142
|
+
data = {
|
|
143
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
protected onUpdate() {
|
|
147
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
148
|
+
if (!entity) return;
|
|
149
|
+
|
|
150
|
+
const physics = this.world.getComponent(
|
|
151
|
+
entity.entityId,
|
|
152
|
+
PhysicsComponent,
|
|
153
|
+
) as PhysicsComponent | null;
|
|
154
|
+
if (!physics) return;
|
|
155
|
+
// Use the component on the picked entity.
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
::: tip Rigid body type
|
|
162
|
+
Set `values.rigidbody.type` to `"kinematicPosition"` in the inspector for the second example. Applying impulses requires a `"dynamic"` rigid body.
|
|
163
|
+
:::
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Script
|
|
2
|
+
|
|
3
|
+
Component holding the list of `scripts` attached to an entity. Loaded from the saved project; the runtime-side fields (`scriptInstance`, `scriptInstances`) are non-enumerable so they never leak into save data or undo history. Authored scripts subclass `Behaviour`.
|
|
4
|
+
|
|
5
|
+
> **Managed by:** [`ScriptBehaviourSystem`](../systems/script-behaviour-system)
|
|
6
|
+
|
|
7
|
+
## Editor inspector
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Properties
|
|
12
|
+
|
|
13
|
+
| Property | Type | Description |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `entries` | `ScriptEntry[]` | Authored script entries attached to the entity. Each entry references a class by name plus its inspector field overrides. Saved with the project. |
|
|
16
|
+
| `scriptInstance` | `unknown \| null` | First live behaviour instance after compile/load. Non-enumerable, so it does not appear in save data. `null` when no script is loaded. |
|
|
17
|
+
| `scriptInstances` | `Map<number, unknown>` | Map of `entityId` to its compiled behaviour instance (one entry per script bound to the entity). Non-enumerable, so it does not appear in save data. |
|
|
18
|
+
|
|
19
|
+
## API reference
|
|
20
|
+
|
|
21
|
+
- Class: [`ScriptComponent`](../../api/components/classes/ScriptComponent.md)
|
|
22
|
+
- Source: [`core/components/ScriptComponent.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/ScriptComponent.ts)
|
|
23
|
+
|
|
24
|
+
## Scripting examples
|
|
25
|
+
|
|
26
|
+
::: tip Component access patterns
|
|
27
|
+
Use `this.getComponent(X)` to access a component on the **entity this script is attached to**. Use `this.world.getEntityByName` to find another entity by name, then `this.world.getComponent` to read its component:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// Component on the entity this script is on
|
|
31
|
+
const scriptComp = this.getComponent(ScriptComponent);
|
|
32
|
+
|
|
33
|
+
// Component on another entity, found by its scene name
|
|
34
|
+
const other = this.world.getEntityByName("Manager");
|
|
35
|
+
if (other) {
|
|
36
|
+
const scriptComp = this.world.getComponent(other.entityId, ScriptComponent);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
:::
|
|
40
|
+
|
|
41
|
+
### Call a method on another script attached to the same entity
|
|
42
|
+
|
|
43
|
+
`ScriptComponent.scriptInstances` maps entity IDs to their compiled behaviour instances. You can cast an instance to a known shape and call public methods on it, enabling script-to-script communication.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { Behaviour, ScriptComponent } from "@relu-interactives/spatial-ecs";
|
|
47
|
+
|
|
48
|
+
// Assumes another script on this entity exposes a `reset()` method.
|
|
49
|
+
export default class ScriptBridge extends Behaviour {
|
|
50
|
+
protected init() {
|
|
51
|
+
const scriptComp = this.getComponent(ScriptComponent);
|
|
52
|
+
if (!scriptComp) return;
|
|
53
|
+
|
|
54
|
+
// scriptInstance is the first compiled behaviour on this entity
|
|
55
|
+
const other = scriptComp.scriptInstance as { reset?(): void } | null;
|
|
56
|
+
if (other?.reset) {
|
|
57
|
+
other.reset();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Inspect script entries
|
|
64
|
+
|
|
65
|
+
Read the authored `entries` array to find which scripts are attached and inspect their saved field overrides.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { Behaviour, ScriptComponent } from "@relu-interactives/spatial-ecs";
|
|
69
|
+
|
|
70
|
+
export default class ScriptInspector extends Behaviour {
|
|
71
|
+
protected init() {
|
|
72
|
+
const scriptComp = this.getComponent(ScriptComponent);
|
|
73
|
+
if (!scriptComp) return;
|
|
74
|
+
|
|
75
|
+
for (const entry of scriptComp.entries) {
|
|
76
|
+
console.log(`Script: ${entry.className}`, entry.data);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Via `ComponentInput` in the inspector
|
|
83
|
+
|
|
84
|
+
You can also pick this component from the inspector using a `ComponentInput` field. Assign any entity in the inspector and the field resolves to the live `ScriptComponent` instance at runtime.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import {
|
|
88
|
+
Behaviour,
|
|
89
|
+
ScriptComponent,
|
|
90
|
+
type ComponentInput,
|
|
91
|
+
} from "@relu-interactives/spatial-ecs";
|
|
92
|
+
|
|
93
|
+
export default class Example extends Behaviour {
|
|
94
|
+
data = {
|
|
95
|
+
targetScript: {
|
|
96
|
+
type: "component",
|
|
97
|
+
value: null,
|
|
98
|
+
} as unknown as ComponentInput,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
protected onUpdate() {
|
|
102
|
+
const scriptComp = this.data.targetScript.value as ScriptComponent | null;
|
|
103
|
+
if (!scriptComp) return;
|
|
104
|
+
// Use the live component instance.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Via `EntityInput` in the inspector
|
|
110
|
+
|
|
111
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import {
|
|
115
|
+
Behaviour,
|
|
116
|
+
ScriptComponent,
|
|
117
|
+
type EntityInput,
|
|
118
|
+
type WorldEntityView,
|
|
119
|
+
} from "@relu-interactives/spatial-ecs";
|
|
120
|
+
|
|
121
|
+
export default class Example extends Behaviour {
|
|
122
|
+
data = {
|
|
123
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
protected onUpdate() {
|
|
127
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
128
|
+
if (!entity) return;
|
|
129
|
+
|
|
130
|
+
const scriptComp = this.world.getComponent(
|
|
131
|
+
entity.entityId,
|
|
132
|
+
ScriptComponent,
|
|
133
|
+
) as ScriptComponent | null;
|
|
134
|
+
if (!scriptComp) return;
|
|
135
|
+
// Use the component on the picked entity.
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
::: tip Runtime vs. authored data
|
|
141
|
+
`entries` is the persisted array of script definitions (class name + inspector overrides). `scriptInstance` and `scriptInstances` are non-enumerable runtime references that are never saved to snapshots. Do not store references to `scriptInstance` across frames — re-read from `ScriptComponent` each time if needed.
|
|
142
|
+
:::
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Sprite
|
|
2
|
+
|
|
3
|
+
Camera-facing 2D sprite. Unlike `ImageComponent`, sprites use `THREE.Sprite` and always render as billboards.
|
|
4
|
+
|
|
5
|
+
## Editor inspector
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Properties
|
|
10
|
+
|
|
11
|
+
| Property | Type | Description |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `path` | `string` | Source URL or `localasset://` path of the sprite image. |
|
|
14
|
+
| `width` | `number` | Width of the sprite in world units. |
|
|
15
|
+
| `height` | `number` | Height of the sprite in world units. |
|
|
16
|
+
| `texture` | `THREE.Texture \| null` | Loaded texture, populated asynchronously. `null` until loaded. |
|
|
17
|
+
| `object` | `THREE.Sprite \| null` | Live `THREE.Sprite` placed in the scene. `null` until built. |
|
|
18
|
+
|
|
19
|
+
## API reference
|
|
20
|
+
|
|
21
|
+
- Class: [`SpriteComponent`](../../api/components/classes/SpriteComponent.md)
|
|
22
|
+
- Source: [`core/components/Sprite.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Sprite.ts)
|
|
23
|
+
|
|
24
|
+
## Scripting examples
|
|
25
|
+
|
|
26
|
+
::: tip Component access patterns
|
|
27
|
+
Use `this.getComponent(X)` to access a component on the **entity this script is attached to**. Use `this.world.getEntityByName` to find another entity by name, then `this.world.getComponent` to read its component:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// Component on the entity this script is on
|
|
31
|
+
const sprite = this.getComponent(SpriteComponent);
|
|
32
|
+
|
|
33
|
+
// Component on another entity, found by its scene name
|
|
34
|
+
const other = this.world.getEntityByName("Coin");
|
|
35
|
+
if (other) {
|
|
36
|
+
const sprite = this.world.getComponent(other.entityId, SpriteComponent);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
:::
|
|
40
|
+
|
|
41
|
+
### Pulse sprite size
|
|
42
|
+
|
|
43
|
+
Animate the sprite's width and height to create a breathing or highlight effect. The initial dimensions are captured on `init` so the pulse is relative to the authored size.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { Behaviour, SpriteComponent } from "@relu-interactives/spatial-ecs";
|
|
47
|
+
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
48
|
+
|
|
49
|
+
export default class SpritePulse extends Behaviour {
|
|
50
|
+
data = {
|
|
51
|
+
speed: 2 as FloatInput,
|
|
52
|
+
amplitude: 0.2 as FloatInput,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
private elapsed = 0;
|
|
56
|
+
private baseWidth = 1;
|
|
57
|
+
private baseHeight = 1;
|
|
58
|
+
|
|
59
|
+
protected init() {
|
|
60
|
+
const sprite = this.getComponent(SpriteComponent);
|
|
61
|
+
if (sprite) {
|
|
62
|
+
this.baseWidth = sprite.width;
|
|
63
|
+
this.baseHeight = sprite.height;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
protected onUpdate() {
|
|
68
|
+
this.elapsed += this.deltaTime;
|
|
69
|
+
const sprite = this.getComponent(SpriteComponent);
|
|
70
|
+
if (!sprite) return;
|
|
71
|
+
|
|
72
|
+
const factor = 1 + this.data.amplitude * Math.sin(this.elapsed * this.data.speed);
|
|
73
|
+
sprite.width = this.baseWidth * factor;
|
|
74
|
+
sprite.height = this.baseHeight * factor;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Toggle visibility on key press
|
|
80
|
+
|
|
81
|
+
Show or hide the sprite by toggling `Object3DRef.visibility`.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { Behaviour, Object3DRef, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
85
|
+
|
|
86
|
+
export default class SpriteToggle extends Behaviour {
|
|
87
|
+
private visible = true;
|
|
88
|
+
|
|
89
|
+
protected onUpdate() {
|
|
90
|
+
if (this.world.getKeyDown(KeyboardKeys.V)) {
|
|
91
|
+
this.visible = !this.visible;
|
|
92
|
+
const ref = this.getComponent(Object3DRef);
|
|
93
|
+
if (ref) ref.visibility = this.visible;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Via `ComponentInput` in the inspector
|
|
100
|
+
|
|
101
|
+
You can also pick this component from the inspector using a `ComponentInput` field. Assign any entity in the inspector and the field resolves to the live `SpriteComponent` instance at runtime.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import {
|
|
105
|
+
Behaviour,
|
|
106
|
+
SpriteComponent,
|
|
107
|
+
type ComponentInput,
|
|
108
|
+
} from "@relu-interactives/spatial-ecs";
|
|
109
|
+
|
|
110
|
+
export default class Example extends Behaviour {
|
|
111
|
+
data = {
|
|
112
|
+
targetSprite: {
|
|
113
|
+
type: "component",
|
|
114
|
+
value: null,
|
|
115
|
+
} as unknown as ComponentInput,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
protected onUpdate() {
|
|
119
|
+
const sprite = this.data.targetSprite.value as SpriteComponent | null;
|
|
120
|
+
if (!sprite) return;
|
|
121
|
+
// Use the live component instance.
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Via `EntityInput` in the inspector
|
|
127
|
+
|
|
128
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import {
|
|
132
|
+
Behaviour,
|
|
133
|
+
SpriteComponent,
|
|
134
|
+
type EntityInput,
|
|
135
|
+
type WorldEntityView,
|
|
136
|
+
} from "@relu-interactives/spatial-ecs";
|
|
137
|
+
|
|
138
|
+
export default class Example extends Behaviour {
|
|
139
|
+
data = {
|
|
140
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
protected onUpdate() {
|
|
144
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
145
|
+
if (!entity) return;
|
|
146
|
+
|
|
147
|
+
const sprite = this.world.getComponent(
|
|
148
|
+
entity.entityId,
|
|
149
|
+
SpriteComponent,
|
|
150
|
+
) as SpriteComponent | null;
|
|
151
|
+
if (!sprite) return;
|
|
152
|
+
// Use the component on the picked entity.
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|