@relu-interactives/spatial-ecs 0.2.11 → 0.2.13
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-KTHuWc-i.d.cts → System-CTTwEGn1.d.cts} +312 -3
- package/dist/{System-KTHuWc-i.d.ts → System-CTTwEGn1.d.ts} +312 -3
- package/dist/{Video-Ds_0Aj66.d.ts → Video-BMWPYc3q.d.cts} +2 -241
- package/dist/{Video-BnrYbbzu.d.cts → Video-CV1-u6hL.d.ts} +2 -241
- package/dist/{chunk-OIOUWDOS.js → chunk-27RBPOVO.js} +40 -4
- package/dist/chunk-27RBPOVO.js.map +1 -0
- package/dist/{chunk-YLRCC4EK.js → chunk-7QBONTBW.js} +4 -4
- package/dist/{chunk-YLRCC4EK.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-UU6VYCIO.js → chunk-KDZ6VBRO.js} +4 -4
- package/dist/{chunk-UU6VYCIO.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 +39 -19
- 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 +146 -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/component-catalog.md +2 -0
- package/dist/docs/guide/components/animation.md +40 -1
- package/dist/docs/guide/components/instanced-mesh.md +1 -4
- 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/spawning/audio.md +29 -7
- package/dist/docs/guide/systems/object-management-system.md +70 -0
- package/dist/docs/guide/world-api.md +3 -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-D-gUELQS.d.ts → index-ByX7502C.d.ts} +2 -2
- package/dist/{index-ComEYKYI.d.cts → index-D7q4SRCp.d.cts} +2 -2
- package/dist/index.cjs +84 -1
- 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 +55 -8
- package/dist/index.js.map +1 -1
- package/dist/systems/index.cjs +37 -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-OIOUWDOS.js.map +0 -1
- package/dist/chunk-XPCVEXMY.js.map +0 -1
- package/dist/docs/guide/inspector-data-binding.md +0 -367
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Behaviour Data Binding
|
|
2
|
+
|
|
3
|
+
The `ScriptComponent.data` field is the bridge between the editor inspector and your `Behaviour` subclass. Anything you place on `data` is:
|
|
4
|
+
|
|
5
|
+
1. Saved with the project.
|
|
6
|
+
2. Rendered as a live inspector control in the editor.
|
|
7
|
+
3. Available at runtime as `this.data` inside the script.
|
|
8
|
+
|
|
9
|
+
The **type annotation** on each field tells the editor which control to render. Import the input types from `@relu-interactives/spatial-ecs` and use them as `as` casts on the initial values in your data object.
|
|
10
|
+
|
|
11
|
+
## Input types
|
|
12
|
+
|
|
13
|
+
| Type | Inspector control | Runtime value |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| [`FloatInput`](./float-input) | Number input | `number` |
|
|
16
|
+
| [`TextInput`](./text-input) | Text input | `string` |
|
|
17
|
+
| [`ColorInput`](./color-input) | Color picker | `string` (hex, e.g. `"#ff0000"`) |
|
|
18
|
+
| [`Vector2Input`](./vector2-input) | XY number pair | `{ x: number; y: number }` |
|
|
19
|
+
| [`Vector3Input`](./vector3-input) | XYZ number triple | `{ x: number; y: number; z: number }` |
|
|
20
|
+
| [`SliderInput`](./slider-input) | Range slider | `{ min, max, step, value }` — read `field.value` at runtime |
|
|
21
|
+
| [`DropdownInput`](./dropdown-input) | Select dropdown | `{ options: DropdownOption[]; value: string }` — read `field.value` |
|
|
22
|
+
| [`CheckboxInput`](./checkbox-input) | Checkbox | `{ type: "checkbox"; value: boolean }` — read `.value` |
|
|
23
|
+
| [`ToggleInput`](./toggle-input) | Toggle switch | `boolean` |
|
|
24
|
+
| [`AssetInput`](./asset-input) | Asset file picker | `{ path: string; type: string }` — read `field.path` |
|
|
25
|
+
| [`EntityInput`](./entity-input) | Entity picker | `{ type: "entity"; value: WorldEntityView \| null }` — read `field.value` |
|
|
26
|
+
| [`ComponentInput`](./component-input) | Entity + component picker | `{ type: "component"; componentKind?: ComponentKind; value: Component \| null }` — read `field.value` |
|
|
27
|
+
|
|
28
|
+
## Declaring inspector fields
|
|
29
|
+
|
|
30
|
+
Import the input types you need alongside `Behaviour`, then declare them directly on the `data` class property using `as` casts:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import {
|
|
34
|
+
Behaviour,
|
|
35
|
+
type FloatInput,
|
|
36
|
+
type TextInput,
|
|
37
|
+
type ColorInput,
|
|
38
|
+
type Vector2Input,
|
|
39
|
+
type Vector3Input,
|
|
40
|
+
type SliderInput,
|
|
41
|
+
type DropdownInput,
|
|
42
|
+
type CheckboxInput,
|
|
43
|
+
type ToggleInput,
|
|
44
|
+
type AssetInput,
|
|
45
|
+
type EntityInput,
|
|
46
|
+
type ComponentInput,
|
|
47
|
+
} from "@relu-interactives/spatial-ecs";
|
|
48
|
+
|
|
49
|
+
export default class Demo extends Behaviour {
|
|
50
|
+
data = {
|
|
51
|
+
speed: 1 as FloatInput,
|
|
52
|
+
label: "Hello" as TextInput,
|
|
53
|
+
tint: "#ffffff" as ColorInput,
|
|
54
|
+
offset: { x: 0, y: 0 } as Vector2Input,
|
|
55
|
+
origin: { x: 0, y: 0, z: 0 } as Vector3Input,
|
|
56
|
+
range: { min: 0, max: 10, step: 0.1, value: 5 } as SliderInput,
|
|
57
|
+
axis: {
|
|
58
|
+
value: "y",
|
|
59
|
+
options: [
|
|
60
|
+
{ label: "X", value: "x" },
|
|
61
|
+
{ label: "Y", value: "y" },
|
|
62
|
+
{ label: "Z", value: "z" },
|
|
63
|
+
],
|
|
64
|
+
} as DropdownInput,
|
|
65
|
+
active: true as ToggleInput,
|
|
66
|
+
visible: { type: "checkbox", value: true } as CheckboxInput,
|
|
67
|
+
texture: { path: "", type: "image" } as AssetInput,
|
|
68
|
+
target: { type: "entity", value: null } as EntityInput,
|
|
69
|
+
camera: { type: "component", componentKind: "Camera", value: null } as ComponentInput,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Each field in `data` maps directly to a live inspector control. The script above produces the following inspector panel:
|
|
75
|
+
|
|
76
|
+

|
|
77
|
+
|
|
78
|
+
## Reading values at runtime
|
|
79
|
+
|
|
80
|
+
Most types map directly to their underlying primitive. The exceptions are `SliderInput`, `DropdownInput`, `AssetInput`, `EntityInput`, and `ComponentInput` — read the nested value:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
onUpdate() {
|
|
84
|
+
// Primitives — use directly
|
|
85
|
+
this.transform.rotation.y += this.data.speed * this.deltaTime;
|
|
86
|
+
|
|
87
|
+
// SliderInput → read .value
|
|
88
|
+
const volume = this.data.range.value;
|
|
89
|
+
|
|
90
|
+
// DropdownInput → read .value
|
|
91
|
+
const axis = this.data.axis.value as "x" | "y" | "z";
|
|
92
|
+
|
|
93
|
+
// AssetInput → read .path
|
|
94
|
+
const src = this.data.texture.path;
|
|
95
|
+
|
|
96
|
+
// EntityInput → cast to WorldEntityView | null
|
|
97
|
+
const entity = this.data.target.value as WorldEntityView | null;
|
|
98
|
+
|
|
99
|
+
// ComponentInput → cast to the concrete component type
|
|
100
|
+
const cam = this.data.camera.value as CameraComponent | null;
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Practical example — spinner with inspector controls
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import {
|
|
108
|
+
Behaviour,
|
|
109
|
+
type FloatInput,
|
|
110
|
+
type ColorInput,
|
|
111
|
+
type DropdownInput,
|
|
112
|
+
type ToggleInput,
|
|
113
|
+
} from "@relu-interactives/spatial-ecs";
|
|
114
|
+
|
|
115
|
+
export default class Spinner extends Behaviour {
|
|
116
|
+
data = {
|
|
117
|
+
speed: 1 as FloatInput,
|
|
118
|
+
color: "#00aaff" as ColorInput,
|
|
119
|
+
enabled: true as ToggleInput,
|
|
120
|
+
axis: {
|
|
121
|
+
value: "y",
|
|
122
|
+
options: [
|
|
123
|
+
{ label: "X", value: "x" },
|
|
124
|
+
{ label: "Y", value: "y" },
|
|
125
|
+
{ label: "Z", value: "z" },
|
|
126
|
+
],
|
|
127
|
+
} as DropdownInput,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
onUpdate() {
|
|
131
|
+
if (!this.data.enabled) return;
|
|
132
|
+
const axis = this.data.axis.value as "x" | "y" | "z";
|
|
133
|
+
this.transform.rotation[axis] += this.data.speed * this.deltaTime;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Defaulting fields
|
|
139
|
+
|
|
140
|
+
Defaults are set inline on the `data` property. When a saved project reloads, saved values take precedence — the inline defaults only apply when a field has never been saved. This means:
|
|
141
|
+
|
|
142
|
+
- Adding a new field with an inline default is safe — existing saves will pick it up on next load.
|
|
143
|
+
- The inspector always has a valid initial value when the script is first attached.
|
|
144
|
+
- For `SliderInput` and `DropdownInput`, the full object (including `options`) must be present in the inline default — the editor reads `options` to build the control.
|
|
145
|
+
|
|
146
|
+
## Persistence
|
|
147
|
+
|
|
148
|
+
`ScriptComponent.data` is serialized and saved with the project. On reload, your `data` payload is restored verbatim. If you rename or restructure a field, migrate it inside `init()`:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
init() {
|
|
152
|
+
// migrate renamed field
|
|
153
|
+
if ((this.data as any).oldSpeed !== undefined) {
|
|
154
|
+
this.data.speed = (this.data as any).oldSpeed;
|
|
155
|
+
delete (this.data as any).oldSpeed;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# SliderInput
|
|
2
|
+
|
|
3
|
+
A range slider. The inspector renders a horizontal slider with the current value displayed alongside it.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ min: number; max: number; step: number; value: number }` — read `field.value`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
Provide the full object including `min`, `max`, `step`, and the initial `value`. The editor reads `min`/`max`/`step` to configure the slider control.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { Behaviour, type SliderInput } from "@relu-interactives/spatial-ecs";
|
|
15
|
+
|
|
16
|
+
export default class Demo extends Behaviour {
|
|
17
|
+
data = {
|
|
18
|
+
volume: { min: 0, max: 1, step: 0.01, value: 0.8 } as SliderInput,
|
|
19
|
+
quality: { min: 1, max: 10, step: 1, value: 5 } as SliderInput,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Runtime usage
|
|
25
|
+
|
|
26
|
+
Read the `.value` property — the other fields (`min`, `max`, `step`) are for the editor control only:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
onUpdate() {
|
|
30
|
+
const volume = this.data.volume.value; // number between 0 and 1
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
|
|
36
|
+
- Always include `min`, `max`, and `step` in the inline default — the editor needs them to render the control.
|
|
37
|
+
- `step` can be fractional for smooth sliders (e.g. `0.01`).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# TextInput
|
|
2
|
+
|
|
3
|
+
A single-line text field. The inspector renders a plain text input.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `string`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Behaviour, type TextInput } from "@relu-interactives/spatial-ecs";
|
|
13
|
+
|
|
14
|
+
export default class Demo extends Behaviour {
|
|
15
|
+
data = {
|
|
16
|
+
label: "Hello world" as TextInput,
|
|
17
|
+
apiKey: "" as TextInput,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Runtime usage
|
|
23
|
+
|
|
24
|
+
Use the value directly as a `string`:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
init() {
|
|
28
|
+
console.log(this.data.label); // "Hello world"
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Notes
|
|
33
|
+
|
|
34
|
+
- The default value is what the user sees when the script is first attached.
|
|
35
|
+
- Useful for URLs, display strings, or any freeform text parameter.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# ToggleInput
|
|
2
|
+
|
|
3
|
+
An on/off toggle switch. The inspector renders a pill-shaped toggle.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `boolean`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Behaviour, type ToggleInput } from "@relu-interactives/spatial-ecs";
|
|
13
|
+
|
|
14
|
+
export default class Demo extends Behaviour {
|
|
15
|
+
data = {
|
|
16
|
+
enabled: true as ToggleInput,
|
|
17
|
+
loopAudio: false as ToggleInput,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Runtime usage
|
|
23
|
+
|
|
24
|
+
Use the value directly as a `boolean`:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
onUpdate() {
|
|
28
|
+
if (!this.data.enabled) return;
|
|
29
|
+
// ... rest of update logic
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Notes
|
|
34
|
+
|
|
35
|
+
- Prefer `ToggleInput` for feature flags (e.g. "Enabled", "Loop") and [`CheckboxInput`](./checkbox-input) for property-style options.
|
|
36
|
+
- Both types resolve to a plain `boolean` at runtime.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Vector2Input
|
|
2
|
+
|
|
3
|
+
An XY number pair. The inspector renders two side-by-side number inputs labelled **X** and **Y**.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ x: number; y: number }`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Behaviour, type Vector2Input } from "@relu-interactives/spatial-ecs";
|
|
13
|
+
|
|
14
|
+
export default class Demo extends Behaviour {
|
|
15
|
+
data = {
|
|
16
|
+
offset: { x: 0, y: 0 } as Vector2Input,
|
|
17
|
+
uvScale: { x: 1, y: 1 } as Vector2Input,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Runtime usage
|
|
23
|
+
|
|
24
|
+
Read `x` and `y` directly:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
onUpdate() {
|
|
28
|
+
this.transform.position.x += this.data.offset.x * this.deltaTime;
|
|
29
|
+
this.transform.position.y += this.data.offset.y * this.deltaTime;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Notes
|
|
34
|
+
|
|
35
|
+
- Suitable for screen-space positions, UV offsets, or any 2D vector parameter.
|
|
36
|
+
- Use [`Vector3Input`](./vector3-input) for 3D world-space values.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Vector3Input
|
|
2
|
+
|
|
3
|
+
An XYZ number triple. The inspector renders three side-by-side number inputs labelled **X**, **Y**, and **Z**.
|
|
4
|
+
|
|
5
|
+
**Runtime value:** `{ x: number; y: number; z: number }`
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Declaration
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Behaviour, type Vector3Input } from "@relu-interactives/spatial-ecs";
|
|
13
|
+
|
|
14
|
+
export default class Demo extends Behaviour {
|
|
15
|
+
data = {
|
|
16
|
+
spawnPoint: { x: 0, y: 1, z: 0 } as Vector3Input,
|
|
17
|
+
force: { x: 0, y: 0, z: 0 } as Vector3Input,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Runtime usage
|
|
23
|
+
|
|
24
|
+
Read `x`, `y`, and `z` directly:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import * as THREE from "three";
|
|
28
|
+
|
|
29
|
+
init() {
|
|
30
|
+
const point = new THREE.Vector3(
|
|
31
|
+
this.data.spawnPoint.x,
|
|
32
|
+
this.data.spawnPoint.y,
|
|
33
|
+
this.data.spawnPoint.z,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Notes
|
|
39
|
+
|
|
40
|
+
- Ideal for world-space positions, directions, or scale factors.
|
|
41
|
+
- Values are plain numbers — no automatic unit conversion is applied.
|
|
@@ -27,6 +27,8 @@ Every entity in `@relu-interactives/spatial-ecs` is a bag of components. This ca
|
|
|
27
27
|
- [Sprite](./components/sprite) — camera-facing billboard.
|
|
28
28
|
- [Video](./components/video) — video texture with optional green-screen keying.
|
|
29
29
|
- [Model](./components/model) — GLTF/GLB asset reference loaded asynchronously.
|
|
30
|
+
- [Instanced Mesh](./components/instanced-mesh) — groups instance-slot entities into a single GPU-instanced draw call for high-count identical objects.
|
|
31
|
+
- [Instance Slot](./components/instance-slot) — marks an entity as a single instance within an `InstancedMeshComponent` group.
|
|
30
32
|
|
|
31
33
|
## Lighting & atmosphere
|
|
32
34
|
|
|
@@ -109,9 +109,48 @@ export default class AnimationSpeedDriver extends Behaviour {
|
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
::: tip State machine
|
|
112
|
-
Always use anim.switchState(name)` to change the active clip — do not assign to `active` directly. This ensures the animation system observes the transition and applies the configured cross-fade.
|
|
112
|
+
Always use `anim.switchState(name)` to change the active clip — do not assign to `active` directly. This ensures the animation system observes the transition and applies the configured cross-fade.
|
|
113
113
|
:::
|
|
114
114
|
|
|
115
|
+
### ⚠️ `addState` — positional args only (critical)
|
|
116
|
+
|
|
117
|
+
`addState` takes **three positional arguments**: `(name, clipRef, loop)`. Passing an object will silently resolve nothing because `resolveClipRef` won't find a clip named `[object Object]`.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// ✅ Correct — positional args
|
|
121
|
+
anim.addState("Walk", "Walk", true);
|
|
122
|
+
anim.addState("Attack", "Attack", false);
|
|
123
|
+
|
|
124
|
+
// ❌ Wrong — object arg; the clip will never resolve
|
|
125
|
+
anim.addState({ name: "Walk", clip: "Walk", loop: true }); // ← broken
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Typical deferred setup (model may not be loaded yet)
|
|
129
|
+
|
|
130
|
+
Guard on `availableClips.length > 0` inside `onUpdate` until the model is ready, then register states once:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { Behaviour, AnimationComponent } from "@relu-interactives/spatial-ecs";
|
|
134
|
+
|
|
135
|
+
export default class AnimSetup extends Behaviour {
|
|
136
|
+
private ready = false;
|
|
137
|
+
|
|
138
|
+
protected onUpdate() {
|
|
139
|
+
if (this.ready) return;
|
|
140
|
+
const anim = this.getComponent(AnimationComponent);
|
|
141
|
+
if (!anim || anim.availableClips.length === 0) return;
|
|
142
|
+
|
|
143
|
+
const c = anim.availableClips;
|
|
144
|
+
if (c.includes("Walk")) anim.addState("Walk", "Walk", true);
|
|
145
|
+
if (c.includes("Run")) anim.addState("Run", "Run", true);
|
|
146
|
+
if (c.includes("Attack")) anim.addState("Attack", "Attack", false);
|
|
147
|
+
anim.crossFadeDuration = 0.25;
|
|
148
|
+
anim.switchState("Walk");
|
|
149
|
+
this.ready = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
115
154
|
### Via `ComponentInput` in the inspector
|
|
116
155
|
|
|
117
156
|
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 `AnimationComponent` instance at runtime.
|
|
@@ -8,10 +8,7 @@ Use instanced meshes when you need tens, hundreds, or thousands of identical obj
|
|
|
8
8
|
|
|
9
9
|
## Editor inspector
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
Add a screenshot of the **Instanced Mesh** component in the editor inspector here.
|
|
13
|
-
Suggested asset path: `/public/images/inspector/instanced-mesh.png`
|
|
14
|
-
:::
|
|
11
|
+

|
|
15
12
|
|
|
16
13
|
## Properties
|
|
17
14
|
|