@relu-interactives/spatial-ecs 0.3.19 → 0.3.21
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/{chunk-JYKFLQB5.js → chunk-CDSE7476.js} +38 -3
- package/dist/chunk-CDSE7476.js.map +1 -0
- package/dist/docs/guide/accessing-components.md +7 -6
- package/dist/docs/guide/behaviour-data-binding/component-input.md +10 -6
- package/dist/docs/guide/behaviour-data-binding/entity-input.md +13 -5
- package/dist/docs/guide/camera-rigs.md +2 -2
- package/dist/docs/guide/components/animation.md +12 -5
- package/dist/docs/guide/components/audio.md +13 -6
- package/dist/docs/guide/components/camera.md +10 -4
- package/dist/docs/guide/components/entity-type.md +13 -6
- package/dist/docs/guide/components/image-target-anchor.md +6 -2
- package/dist/docs/guide/components/image-target.md +10 -5
- package/dist/docs/guide/components/image.md +10 -4
- package/dist/docs/guide/components/instance-slot.md +7 -3
- package/dist/docs/guide/components/instanced-mesh.md +15 -7
- package/dist/docs/guide/components/light.md +10 -4
- package/dist/docs/guide/components/material.md +14 -8
- package/dist/docs/guide/components/mesh-geometry.md +10 -4
- package/dist/docs/guide/components/mesh.md +10 -4
- package/dist/docs/guide/components/model.md +4 -2
- package/dist/docs/guide/components/name.md +11 -6
- package/dist/docs/guide/components/object3d-ref.md +7 -3
- package/dist/docs/guide/components/parent-id.md +10 -4
- package/dist/docs/guide/components/physics.md +12 -6
- package/dist/docs/guide/components/script.md +10 -4
- package/dist/docs/guide/components/sprite.md +10 -4
- package/dist/docs/guide/components/transform.md +6 -2
- package/dist/docs/guide/components/video.md +10 -4
- package/dist/docs/guide/prefabs.md +2 -0
- package/dist/docs/guide/runtime-entity-management.md +1 -1
- package/dist/docs/guide/spawning/instanced-mesh.md +11 -6
- package/dist/docs/guide/systems/input-system.md +4 -1
- package/dist/docs/guide/systems/script-object-system.md +9 -1
- package/dist/docs/guide/vr-and-hand-poses.md +105 -1
- package/dist/docs/guide/world-api.md +23 -15
- package/dist/{index-C_589fc4.d.ts → index-6l4hn2Sh.d.ts} +14 -0
- package/dist/{index-3pNbH0iP.d.cts → index-C2I5PxCI.d.cts} +14 -0
- package/dist/index.cjs +36 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/systems/index.cjs +36 -1
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +1 -1
- package/dist/systems/index.d.ts +1 -1
- package/dist/systems/index.js +1 -1
- package/package.json +4 -2
- package/dist/chunk-JYKFLQB5.js.map +0 -1
|
@@ -89,11 +89,12 @@ export default class Jumper extends Behaviour {
|
|
|
89
89
|
true, // wake the body if sleeping
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
-
// Change mass at runtime
|
|
93
|
-
|
|
92
|
+
// Change mass at runtime. Rapier exposes `mass()` as a READ-ONLY getter —
|
|
93
|
+
// extra mass is added rather than assigned.
|
|
94
|
+
this.physics.rigidBody.setAdditionalMass(2, true);
|
|
94
95
|
|
|
95
|
-
// Lock rotation so the body can't tip over
|
|
96
|
-
this.physics.
|
|
96
|
+
// Lock rotation so the body can't tip over (locked, wakeUp)
|
|
97
|
+
this.physics.rigidBody.lockRotations(true, true);
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
```
|
|
@@ -296,7 +297,7 @@ export default class MaterialSwap extends Behaviour {
|
|
|
296
297
|
if (!this.mat) return;
|
|
297
298
|
|
|
298
299
|
// applyValues patches one or more fields on a slot (default slot index 0)
|
|
299
|
-
this.mat.
|
|
300
|
+
this.mat.updateValue(0, {
|
|
300
301
|
color: this.data.color,
|
|
301
302
|
roughness: this.data.roughness,
|
|
302
303
|
metalness: this.data.metalness,
|
|
@@ -410,7 +411,7 @@ export default class Tagger extends Behaviour {
|
|
|
410
411
|
if (!entity) return;
|
|
411
412
|
|
|
412
413
|
// Give the entity a display name
|
|
413
|
-
this.world.addComponent(entity.entityId, new Name(
|
|
414
|
+
this.world.addComponent(entity.entityId, new Name("Tagged"));
|
|
414
415
|
}
|
|
415
416
|
}
|
|
416
417
|
```
|
|
@@ -15,8 +15,8 @@ import { Behaviour, type ComponentInput } from "@relu-interactives/spatial-ecs";
|
|
|
15
15
|
|
|
16
16
|
export default class Demo extends Behaviour {
|
|
17
17
|
data = {
|
|
18
|
-
cam: { type: "component", componentKind: "
|
|
19
|
-
audio: { type: "component", componentKind: "
|
|
18
|
+
cam: { type: "component", componentKind: "Camera", value: null } as ComponentInput,
|
|
19
|
+
audio: { type: "component", componentKind: "Audio", value: null } as ComponentInput,
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
```
|
|
@@ -28,13 +28,15 @@ At runtime, `.value` is resolved to the **live component instance**. Cast to the
|
|
|
28
28
|
```ts
|
|
29
29
|
import {
|
|
30
30
|
Behaviour,
|
|
31
|
-
CameraComponent,
|
|
32
31
|
type ComponentInput,
|
|
33
32
|
} from "@relu-interactives/spatial-ecs";
|
|
33
|
+
import {
|
|
34
|
+
CameraComponent,
|
|
35
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
34
36
|
|
|
35
37
|
export default class FovReader extends Behaviour {
|
|
36
38
|
data = {
|
|
37
|
-
camera: { type: "component", componentKind: "
|
|
39
|
+
camera: { type: "component", componentKind: "Camera", value: null } as ComponentInput,
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
onUpdate() {
|
|
@@ -53,14 +55,16 @@ Mutate the instance directly — the system that owns the component picks up cha
|
|
|
53
55
|
```ts
|
|
54
56
|
import {
|
|
55
57
|
Behaviour,
|
|
56
|
-
CameraComponent,
|
|
57
58
|
type ComponentInput,
|
|
58
59
|
type FloatInput,
|
|
59
60
|
} from "@relu-interactives/spatial-ecs";
|
|
61
|
+
import {
|
|
62
|
+
CameraComponent,
|
|
63
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
60
64
|
|
|
61
65
|
export default class FovAnimator extends Behaviour {
|
|
62
66
|
data = {
|
|
63
|
-
camera: { type: "component", componentKind: "
|
|
67
|
+
camera: { type: "component", componentKind: "Camera", value: null } as ComponentInput,
|
|
64
68
|
targetFov: 90 as FloatInput,
|
|
65
69
|
speed: 30 as FloatInput,
|
|
66
70
|
};
|
|
@@ -23,11 +23,17 @@ export default class Demo extends Behaviour {
|
|
|
23
23
|
At runtime, `.value` is resolved to a **`WorldEntityView`** — not a raw ID. Always guard for `null` (no entity selected):
|
|
24
24
|
|
|
25
25
|
```ts
|
|
26
|
-
import { type WorldEntityView } from "@relu-interactives/spatial-ecs";
|
|
26
|
+
import { Behaviour, type EntityInput, type WorldEntityView } from "@relu-interactives/spatial-ecs";
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
export default class FollowTarget extends Behaviour {
|
|
29
|
+
data = {
|
|
30
|
+
target: { type: "entity", value: null } as unknown as EntityInput,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
onUpdate() {
|
|
34
|
+
const target = this.data.target.value as WorldEntityView | null;
|
|
35
|
+
if (!target) return; // no entity assigned in the inspector
|
|
36
|
+
}
|
|
31
37
|
}
|
|
32
38
|
```
|
|
33
39
|
|
|
@@ -69,11 +75,13 @@ Use the entity's `components` array to find and mutate a specific component:
|
|
|
69
75
|
```ts
|
|
70
76
|
import {
|
|
71
77
|
Behaviour,
|
|
72
|
-
TransformComponent,
|
|
73
78
|
type EntityInput,
|
|
74
79
|
type WorldEntityView,
|
|
75
80
|
type FloatInput,
|
|
76
81
|
} from "@relu-interactives/spatial-ecs";
|
|
82
|
+
import {
|
|
83
|
+
TransformComponent,
|
|
84
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
77
85
|
|
|
78
86
|
export default class Mover extends Behaviour {
|
|
79
87
|
data = {
|
|
@@ -166,7 +166,7 @@ Two cooperating scripts: the **camera** orbits behind the character under pointe
|
|
|
166
166
|
|
|
167
167
|
```ts
|
|
168
168
|
// ThirdPersonCamera.ts — attach to the CAMERA entity
|
|
169
|
-
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
169
|
+
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
170
170
|
import type { FloatInput, TextInput } from "@relu-interactives/spatial-ecs";
|
|
171
171
|
import {
|
|
172
172
|
PhysicsComponent,
|
|
@@ -220,7 +220,7 @@ export default class ThirdPersonCamera extends Behaviour {
|
|
|
220
220
|
|
|
221
221
|
// Pointer lock on click; Escape releases it.
|
|
222
222
|
if (this.world.getMouseDown("left")) this.world.lockMousePointer();
|
|
223
|
-
if (this.world.getKeyDown(
|
|
223
|
+
if (this.world.getKeyDown(KeyboardKeys.Escape)) this.world.unlockMousePointer();
|
|
224
224
|
|
|
225
225
|
// Orbit with the mouse while locked.
|
|
226
226
|
if (this.world.isMousePointerLocked()) {
|
|
@@ -52,7 +52,8 @@ if (other) {
|
|
|
52
52
|
Transition between an idle and a walk state based on arrow-key input. The cross-fade duration is set from the inspector.
|
|
53
53
|
|
|
54
54
|
```typescript
|
|
55
|
-
import { Behaviour,
|
|
55
|
+
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
56
|
+
import { AnimationComponent } from "@relu-interactives/spatial-ecs/components";
|
|
56
57
|
import type { TextInput, FloatInput } from "@relu-interactives/spatial-ecs";
|
|
57
58
|
|
|
58
59
|
export default class AnimationController extends Behaviour {
|
|
@@ -90,7 +91,8 @@ export default class AnimationController extends Behaviour {
|
|
|
90
91
|
Drive `timeScale` and `paused` live from inspector fields, useful for slow-motion or freeze effects.
|
|
91
92
|
|
|
92
93
|
```typescript
|
|
93
|
-
import { Behaviour
|
|
94
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
95
|
+
import { AnimationComponent } from "@relu-interactives/spatial-ecs/components";
|
|
94
96
|
import type { FloatInput, ToggleInput } from "@relu-interactives/spatial-ecs";
|
|
95
97
|
|
|
96
98
|
export default class AnimationSpeedDriver extends Behaviour {
|
|
@@ -130,7 +132,8 @@ anim.addState({ name: "Walk", clip: "Walk", loop: true }); // ← broken
|
|
|
130
132
|
Guard on `availableClips.length > 0` inside `onUpdate` until the model is ready, then register states once:
|
|
131
133
|
|
|
132
134
|
```typescript
|
|
133
|
-
import { Behaviour
|
|
135
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
136
|
+
import { AnimationComponent } from "@relu-interactives/spatial-ecs/components";
|
|
134
137
|
|
|
135
138
|
export default class AnimSetup extends Behaviour {
|
|
136
139
|
private ready = false;
|
|
@@ -158,9 +161,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
158
161
|
```typescript
|
|
159
162
|
import {
|
|
160
163
|
Behaviour,
|
|
161
|
-
AnimationComponent,
|
|
162
164
|
type ComponentInput,
|
|
163
165
|
} from "@relu-interactives/spatial-ecs";
|
|
166
|
+
import {
|
|
167
|
+
AnimationComponent,
|
|
168
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
164
169
|
|
|
165
170
|
export default class Example extends Behaviour {
|
|
166
171
|
data = {
|
|
@@ -185,10 +190,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
185
190
|
```typescript
|
|
186
191
|
import {
|
|
187
192
|
Behaviour,
|
|
188
|
-
AnimationComponent,
|
|
189
193
|
type EntityInput,
|
|
190
194
|
type WorldEntityView,
|
|
191
195
|
} from "@relu-interactives/spatial-ecs";
|
|
196
|
+
import {
|
|
197
|
+
AnimationComponent,
|
|
198
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
192
199
|
|
|
193
200
|
export default class Example extends Behaviour {
|
|
194
201
|
data = {
|
|
@@ -46,7 +46,8 @@ if (other) {
|
|
|
46
46
|
Toggle audio playback when the player presses Space. Volume is exposed as an inspector field.
|
|
47
47
|
|
|
48
48
|
```typescript
|
|
49
|
-
import { Behaviour,
|
|
49
|
+
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
50
|
+
import { AudioComponent } from "@relu-interactives/spatial-ecs/components";
|
|
50
51
|
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
51
52
|
|
|
52
53
|
export default class AudioController extends Behaviour {
|
|
@@ -82,7 +83,8 @@ export default class AudioController extends Behaviour {
|
|
|
82
83
|
Start playing when the camera comes within a configurable range, and stop when it moves away.
|
|
83
84
|
|
|
84
85
|
```typescript
|
|
85
|
-
import { Behaviour
|
|
86
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
87
|
+
import { AudioComponent, TransformComponent, CameraComponent } from "@relu-interactives/spatial-ecs/components";
|
|
86
88
|
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
87
89
|
|
|
88
90
|
export default class ProximityAudio extends Behaviour {
|
|
@@ -96,8 +98,9 @@ export default class ProximityAudio extends Behaviour {
|
|
|
96
98
|
|
|
97
99
|
// Find the default camera entity
|
|
98
100
|
let cameraPos = { x: 0, y: 0, z: 0 };
|
|
99
|
-
for (const
|
|
100
|
-
|
|
101
|
+
for (const id of this.world.query(CameraComponent)) {
|
|
102
|
+
const cam = this.world.getComponent(id, CameraComponent);
|
|
103
|
+
if (cam?.isDefault) {
|
|
101
104
|
const ct = this.world.getComponent(id, TransformComponent);
|
|
102
105
|
if (ct) cameraPos = ct.position;
|
|
103
106
|
break;
|
|
@@ -129,9 +132,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
129
132
|
```typescript
|
|
130
133
|
import {
|
|
131
134
|
Behaviour,
|
|
132
|
-
AudioComponent,
|
|
133
135
|
type ComponentInput,
|
|
134
136
|
} from "@relu-interactives/spatial-ecs";
|
|
137
|
+
import {
|
|
138
|
+
AudioComponent,
|
|
139
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
135
140
|
|
|
136
141
|
export default class Example extends Behaviour {
|
|
137
142
|
data = {
|
|
@@ -156,10 +161,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
156
161
|
```typescript
|
|
157
162
|
import {
|
|
158
163
|
Behaviour,
|
|
159
|
-
AudioComponent,
|
|
160
164
|
type EntityInput,
|
|
161
165
|
type WorldEntityView,
|
|
162
166
|
} from "@relu-interactives/spatial-ecs";
|
|
167
|
+
import {
|
|
168
|
+
AudioComponent,
|
|
169
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
163
170
|
|
|
164
171
|
export default class Example extends Behaviour {
|
|
165
172
|
data = {
|
|
@@ -52,7 +52,8 @@ if (other) {
|
|
|
52
52
|
Smoothly lerp the field-of-view toward a zoomed-in value while Shift is held, then lerp back out.
|
|
53
53
|
|
|
54
54
|
```typescript
|
|
55
|
-
import { Behaviour,
|
|
55
|
+
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
|
|
56
|
+
import { CameraComponent } from "@relu-interactives/spatial-ecs/components";
|
|
56
57
|
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
57
58
|
|
|
58
59
|
export default class CameraZoom extends Behaviour {
|
|
@@ -91,7 +92,8 @@ export default class CameraZoom extends Behaviour {
|
|
|
91
92
|
Rotate the camera entity's position around the scene origin at a configurable radius and height.
|
|
92
93
|
|
|
93
94
|
```typescript
|
|
94
|
-
import { Behaviour
|
|
95
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
96
|
+
import { CameraComponent } from "@relu-interactives/spatial-ecs/components";
|
|
95
97
|
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
96
98
|
|
|
97
99
|
export default class OrbitCamera extends Behaviour {
|
|
@@ -127,9 +129,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
127
129
|
```typescript
|
|
128
130
|
import {
|
|
129
131
|
Behaviour,
|
|
130
|
-
CameraComponent,
|
|
131
132
|
type ComponentInput,
|
|
132
133
|
} from "@relu-interactives/spatial-ecs";
|
|
134
|
+
import {
|
|
135
|
+
CameraComponent,
|
|
136
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
133
137
|
|
|
134
138
|
export default class Example extends Behaviour {
|
|
135
139
|
data = {
|
|
@@ -154,10 +158,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
154
158
|
```typescript
|
|
155
159
|
import {
|
|
156
160
|
Behaviour,
|
|
157
|
-
CameraComponent,
|
|
158
161
|
type EntityInput,
|
|
159
162
|
type WorldEntityView,
|
|
160
163
|
} from "@relu-interactives/spatial-ecs";
|
|
164
|
+
import {
|
|
165
|
+
CameraComponent,
|
|
166
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
161
167
|
|
|
162
168
|
export default class Example extends Behaviour {
|
|
163
169
|
data = {
|
|
@@ -35,7 +35,8 @@ if (other) {
|
|
|
35
35
|
Branch behaviour based on what kind of entity this script is attached to.
|
|
36
36
|
|
|
37
37
|
```typescript
|
|
38
|
-
import { Behaviour
|
|
38
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
39
|
+
import { EntityType } from "@relu-interactives/spatial-ecs/components";
|
|
39
40
|
|
|
40
41
|
export default class TypeAwareSetup extends Behaviour {
|
|
41
42
|
protected init() {
|
|
@@ -58,7 +59,8 @@ export default class TypeAwareSetup extends Behaviour {
|
|
|
58
59
|
Iterate all entities in the scene and apply logic only to those of a specific type.
|
|
59
60
|
|
|
60
61
|
```typescript
|
|
61
|
-
import { Behaviour
|
|
62
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
63
|
+
import { EntityType, TransformComponent } from "@relu-interactives/spatial-ecs/components";
|
|
62
64
|
import type { TextInput, FloatInput } from "@relu-interactives/spatial-ecs";
|
|
63
65
|
|
|
64
66
|
export default class TypeFilter extends Behaviour {
|
|
@@ -68,8 +70,9 @@ export default class TypeFilter extends Behaviour {
|
|
|
68
70
|
};
|
|
69
71
|
|
|
70
72
|
protected onUpdate() {
|
|
71
|
-
for (const
|
|
72
|
-
|
|
73
|
+
for (const id of this.world.query(EntityType)) {
|
|
74
|
+
const entityType = this.world.getComponent(id, EntityType);
|
|
75
|
+
if (entityType?.value !== this.data.targetKind) continue;
|
|
73
76
|
|
|
74
77
|
const t = this.world.getComponent(id, TransformComponent);
|
|
75
78
|
if (t) t.rotation.y += this.data.spinSpeed * this.deltaTime;
|
|
@@ -89,9 +92,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
89
92
|
```typescript
|
|
90
93
|
import {
|
|
91
94
|
Behaviour,
|
|
92
|
-
EntityType,
|
|
93
95
|
type ComponentInput,
|
|
94
96
|
} from "@relu-interactives/spatial-ecs";
|
|
97
|
+
import {
|
|
98
|
+
EntityType,
|
|
99
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
95
100
|
|
|
96
101
|
export default class Example extends Behaviour {
|
|
97
102
|
data = {
|
|
@@ -116,10 +121,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
116
121
|
```typescript
|
|
117
122
|
import {
|
|
118
123
|
Behaviour,
|
|
119
|
-
EntityType,
|
|
120
124
|
type EntityInput,
|
|
121
125
|
type WorldEntityView,
|
|
122
126
|
} from "@relu-interactives/spatial-ecs";
|
|
127
|
+
import {
|
|
128
|
+
EntityType,
|
|
129
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
123
130
|
|
|
124
131
|
export default class Example extends Behaviour {
|
|
125
132
|
data = {
|
|
@@ -51,9 +51,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
51
51
|
```typescript
|
|
52
52
|
import {
|
|
53
53
|
Behaviour,
|
|
54
|
-
ImageTargetAnchor,
|
|
55
54
|
type ComponentInput,
|
|
56
55
|
} from "@relu-interactives/spatial-ecs";
|
|
56
|
+
import {
|
|
57
|
+
ImageTargetAnchor,
|
|
58
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
57
59
|
|
|
58
60
|
export default class Example extends Behaviour {
|
|
59
61
|
data = {
|
|
@@ -78,10 +80,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
78
80
|
```typescript
|
|
79
81
|
import {
|
|
80
82
|
Behaviour,
|
|
81
|
-
ImageTargetAnchor,
|
|
82
83
|
type EntityInput,
|
|
83
84
|
type WorldEntityView,
|
|
84
85
|
} from "@relu-interactives/spatial-ecs";
|
|
86
|
+
import {
|
|
87
|
+
ImageTargetAnchor,
|
|
88
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
85
89
|
|
|
86
90
|
export default class Example extends Behaviour {
|
|
87
91
|
data = {
|
|
@@ -43,16 +43,17 @@ if (other) {
|
|
|
43
43
|
The image-tracking system reveals the entity when its target is detected and hides it when lost. Attach this script to a child entity that has `ImageTargetAnchor` to run logic on those transitions.
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import { Behaviour
|
|
46
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
47
|
+
import { Object3DRef, AudioComponent } from "@relu-interactives/spatial-ecs/components";
|
|
47
48
|
|
|
48
49
|
export default class TargetFoundReactor extends Behaviour {
|
|
49
|
-
|
|
50
|
+
onTargetFound() {
|
|
50
51
|
// Play audio, trigger animation, spawn objects, etc.
|
|
51
52
|
const audio = this.getComponent(AudioComponent);
|
|
52
53
|
audio?.play();
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
onTargetLost() {
|
|
56
57
|
const audio = this.getComponent(AudioComponent);
|
|
57
58
|
audio?.stop();
|
|
58
59
|
}
|
|
@@ -70,9 +71,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
70
71
|
```typescript
|
|
71
72
|
import {
|
|
72
73
|
Behaviour,
|
|
73
|
-
ImageTarget,
|
|
74
74
|
type ComponentInput,
|
|
75
75
|
} from "@relu-interactives/spatial-ecs";
|
|
76
|
+
import {
|
|
77
|
+
ImageTarget,
|
|
78
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
76
79
|
|
|
77
80
|
export default class Example extends Behaviour {
|
|
78
81
|
data = {
|
|
@@ -97,10 +100,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
97
100
|
```typescript
|
|
98
101
|
import {
|
|
99
102
|
Behaviour,
|
|
100
|
-
ImageTarget,
|
|
101
103
|
type EntityInput,
|
|
102
104
|
type WorldEntityView,
|
|
103
105
|
} from "@relu-interactives/spatial-ecs";
|
|
106
|
+
import {
|
|
107
|
+
ImageTarget,
|
|
108
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
104
109
|
|
|
105
110
|
export default class Example extends Behaviour {
|
|
106
111
|
data = {
|
|
@@ -43,7 +43,8 @@ if (other) {
|
|
|
43
43
|
Lerp the image quad's dimensions toward inspector-defined target values, useful for animated UI reveals or zoom effects.
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import { Behaviour
|
|
46
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
47
|
+
import { ImageComponent } from "@relu-interactives/spatial-ecs/components";
|
|
47
48
|
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
48
49
|
|
|
49
50
|
export default class ImageResizer extends Behaviour {
|
|
@@ -69,7 +70,8 @@ export default class ImageResizer extends Behaviour {
|
|
|
69
70
|
Drive the quad's visibility from the inspector or from game logic via `Object3DRef`.
|
|
70
71
|
|
|
71
72
|
```typescript
|
|
72
|
-
import { Behaviour
|
|
73
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
74
|
+
import { ImageComponent, Object3DRef } from "@relu-interactives/spatial-ecs/components";
|
|
73
75
|
import type { ToggleInput } from "@relu-interactives/spatial-ecs";
|
|
74
76
|
|
|
75
77
|
export default class ImageVisibility extends Behaviour {
|
|
@@ -94,9 +96,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
94
96
|
```typescript
|
|
95
97
|
import {
|
|
96
98
|
Behaviour,
|
|
97
|
-
ImageComponent,
|
|
98
99
|
type ComponentInput,
|
|
99
100
|
} from "@relu-interactives/spatial-ecs";
|
|
101
|
+
import {
|
|
102
|
+
ImageComponent,
|
|
103
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
100
104
|
|
|
101
105
|
export default class Example extends Behaviour {
|
|
102
106
|
data = {
|
|
@@ -121,10 +125,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
121
125
|
```typescript
|
|
122
126
|
import {
|
|
123
127
|
Behaviour,
|
|
124
|
-
ImageComponent,
|
|
125
128
|
type EntityInput,
|
|
126
129
|
type WorldEntityView,
|
|
127
130
|
} from "@relu-interactives/spatial-ecs";
|
|
131
|
+
import {
|
|
132
|
+
ImageComponent,
|
|
133
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
128
134
|
|
|
129
135
|
export default class Example extends Behaviour {
|
|
130
136
|
data = {
|
|
@@ -40,9 +40,11 @@ if (other) {
|
|
|
40
40
|
```typescript
|
|
41
41
|
import {
|
|
42
42
|
Behaviour,
|
|
43
|
+
} from "@relu-interactives/spatial-ecs";
|
|
44
|
+
import {
|
|
43
45
|
InstanceSlotComponent,
|
|
44
46
|
InstancedMeshComponent,
|
|
45
|
-
} from "@relu-interactives/spatial-ecs";
|
|
47
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
46
48
|
|
|
47
49
|
export default class SlotInfo extends Behaviour {
|
|
48
50
|
protected init() {
|
|
@@ -67,9 +69,11 @@ Use a `ComponentInput` field so the inspector can wire any instance slot entity
|
|
|
67
69
|
```typescript
|
|
68
70
|
import {
|
|
69
71
|
Behaviour,
|
|
72
|
+
} from "@relu-interactives/spatial-ecs";
|
|
73
|
+
import {
|
|
70
74
|
InstanceSlotComponent,
|
|
71
75
|
TransformComponent,
|
|
72
|
-
} from "@relu-interactives/spatial-ecs";
|
|
76
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
73
77
|
import type { ComponentInput, FloatInput } from "@relu-interactives/spatial-ecs";
|
|
74
78
|
|
|
75
79
|
export default class MoveSlot extends Behaviour {
|
|
@@ -86,7 +90,7 @@ export default class MoveSlot extends Behaviour {
|
|
|
86
90
|
const slot = this.data.targetSlot.value as InstanceSlotComponent | null;
|
|
87
91
|
if (!slot) return;
|
|
88
92
|
|
|
89
|
-
const transform = this.world.
|
|
93
|
+
const transform = this.world.getComponent(slot.groupEntityId, TransformComponent);
|
|
90
94
|
// Operate on the slot entity's own transform instead:
|
|
91
95
|
const slotEntity = this.world.getEntityById(
|
|
92
96
|
// find the slot entity ID from the group
|
|
@@ -47,7 +47,8 @@ if (other) {
|
|
|
47
47
|
### Read instance count
|
|
48
48
|
|
|
49
49
|
```typescript
|
|
50
|
-
import { Behaviour
|
|
50
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
51
|
+
import { InstancedMeshComponent } from "@relu-interactives/spatial-ecs/components";
|
|
51
52
|
|
|
52
53
|
export default class InstanceCounter extends Behaviour {
|
|
53
54
|
protected init() {
|
|
@@ -62,7 +63,8 @@ export default class InstanceCounter extends Behaviour {
|
|
|
62
63
|
### Toggle shadows on all instances at runtime
|
|
63
64
|
|
|
64
65
|
```typescript
|
|
65
|
-
import { Behaviour
|
|
66
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
67
|
+
import { InstancedMeshComponent } from "@relu-interactives/spatial-ecs/components";
|
|
66
68
|
import type { ToggleInput } from "@relu-interactives/spatial-ecs";
|
|
67
69
|
|
|
68
70
|
export default class ToggleShadows extends Behaviour {
|
|
@@ -87,9 +89,11 @@ Move each slot entity up and down using a sine wave. `InstancedMeshSystem` reads
|
|
|
87
89
|
```typescript
|
|
88
90
|
import {
|
|
89
91
|
Behaviour,
|
|
92
|
+
} from "@relu-interactives/spatial-ecs";
|
|
93
|
+
import {
|
|
90
94
|
InstancedMeshComponent,
|
|
91
95
|
TransformComponent,
|
|
92
|
-
} from "@relu-interactives/spatial-ecs";
|
|
96
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
93
97
|
|
|
94
98
|
export default class WaveInstances extends Behaviour {
|
|
95
99
|
private elapsed = 0;
|
|
@@ -102,7 +106,7 @@ export default class WaveInstances extends Behaviour {
|
|
|
102
106
|
|
|
103
107
|
for (let i = 0; i < instanced.instanceEntityIds.length; i++) {
|
|
104
108
|
const slotId = instanced.instanceEntityIds[i];
|
|
105
|
-
const transform = this.world.
|
|
109
|
+
const transform = this.world.getComponent(slotId, TransformComponent);
|
|
106
110
|
if (transform) {
|
|
107
111
|
transform.position.y = Math.sin(this.elapsed + i * 0.5) * 2;
|
|
108
112
|
}
|
|
@@ -118,9 +122,11 @@ Use a `ComponentInput` field so the inspector can wire any `InstancedMeshCompone
|
|
|
118
122
|
```typescript
|
|
119
123
|
import {
|
|
120
124
|
Behaviour,
|
|
125
|
+
} from "@relu-interactives/spatial-ecs";
|
|
126
|
+
import {
|
|
121
127
|
InstancedMeshComponent,
|
|
122
128
|
TransformComponent,
|
|
123
|
-
} from "@relu-interactives/spatial-ecs";
|
|
129
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
124
130
|
import type { ComponentInput } from "@relu-interactives/spatial-ecs";
|
|
125
131
|
|
|
126
132
|
export default class ScatterInstances extends Behaviour {
|
|
@@ -138,7 +144,7 @@ export default class ScatterInstances extends Behaviour {
|
|
|
138
144
|
|
|
139
145
|
// Scatter each instance randomly within a 10-unit area
|
|
140
146
|
for (const slotId of instanced.instanceEntityIds) {
|
|
141
|
-
const transform = this.world.
|
|
147
|
+
const transform = this.world.getComponent(slotId, TransformComponent);
|
|
142
148
|
if (transform) {
|
|
143
149
|
transform.position.x = (Math.random() - 0.5) * 10;
|
|
144
150
|
transform.position.z = (Math.random() - 0.5) * 10;
|
|
@@ -155,8 +161,10 @@ Add a new slot entity to an existing group from a script. The new slot's transfo
|
|
|
155
161
|
```typescript
|
|
156
162
|
import {
|
|
157
163
|
Behaviour,
|
|
158
|
-
InstancedMeshComponent,
|
|
159
164
|
} from "@relu-interactives/spatial-ecs";
|
|
165
|
+
import {
|
|
166
|
+
InstancedMeshComponent,
|
|
167
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
160
168
|
|
|
161
169
|
export default class DynamicSpawner extends Behaviour {
|
|
162
170
|
protected init() {
|
|
@@ -43,7 +43,8 @@ if (other) {
|
|
|
43
43
|
Animate the light's intensity between a min and max value using a sine wave — useful for flickering flames or heartbeat effects.
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import { Behaviour
|
|
46
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
47
|
+
import { LightComponent } from "@relu-interactives/spatial-ecs/components";
|
|
47
48
|
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
48
49
|
|
|
49
50
|
export default class LightPulse extends Behaviour {
|
|
@@ -72,7 +73,8 @@ export default class LightPulse extends Behaviour {
|
|
|
72
73
|
Cycle the light's color through the RGB spectrum over a configurable period.
|
|
73
74
|
|
|
74
75
|
```typescript
|
|
75
|
-
import { Behaviour
|
|
76
|
+
import { Behaviour } from "@relu-interactives/spatial-ecs";
|
|
77
|
+
import { LightComponent } from "@relu-interactives/spatial-ecs/components";
|
|
76
78
|
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
77
79
|
|
|
78
80
|
export default class LightColorCycle extends Behaviour {
|
|
@@ -105,9 +107,11 @@ You can also pick this component from the inspector using a `ComponentInput` fie
|
|
|
105
107
|
```typescript
|
|
106
108
|
import {
|
|
107
109
|
Behaviour,
|
|
108
|
-
LightComponent,
|
|
109
110
|
type ComponentInput,
|
|
110
111
|
} from "@relu-interactives/spatial-ecs";
|
|
112
|
+
import {
|
|
113
|
+
LightComponent,
|
|
114
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
111
115
|
|
|
112
116
|
export default class Example extends Behaviour {
|
|
113
117
|
data = {
|
|
@@ -132,10 +136,12 @@ Alternatively, pick an entity from the inspector using an `EntityInput` field an
|
|
|
132
136
|
```typescript
|
|
133
137
|
import {
|
|
134
138
|
Behaviour,
|
|
135
|
-
LightComponent,
|
|
136
139
|
type EntityInput,
|
|
137
140
|
type WorldEntityView,
|
|
138
141
|
} from "@relu-interactives/spatial-ecs";
|
|
142
|
+
import {
|
|
143
|
+
LightComponent,
|
|
144
|
+
} from "@relu-interactives/spatial-ecs/components";
|
|
139
145
|
|
|
140
146
|
export default class Example extends Behaviour {
|
|
141
147
|
data = {
|