@relu-interactives/spatial-ecs 0.2.22 → 0.2.23
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-GZ2NKSMV.js → chunk-7BEZBIVB.js} +12 -5
- package/dist/chunk-7BEZBIVB.js.map +1 -0
- package/dist/docs/guide/authoring-a-script-object.md +24 -11
- package/dist/index.cjs +10 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/systems/index.cjs +10 -3
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-GZ2NKSMV.js.map +0 -1
|
@@ -14,18 +14,20 @@ import { ScriptObject, type ColorInput } from "@relu-interactives/spatial-ecs";
|
|
|
14
14
|
import * as THREE from "three";
|
|
15
15
|
|
|
16
16
|
export default class WavePlane extends ScriptObject {
|
|
17
|
-
//
|
|
18
|
-
declare data
|
|
17
|
+
// Inspector fields: an INLINE `data = { … }` literal (same envelopes as
|
|
18
|
+
// Behaviours). NEVER `declare data` — that is a type-only annotation with no
|
|
19
|
+
// runtime object, so the editor can't discover your fields and the inspector
|
|
20
|
+
// shows nothing to edit.
|
|
21
|
+
data = { color: "#3aa0ff" as ColorInput };
|
|
19
22
|
|
|
20
23
|
private mat!: THREE.ShaderMaterial;
|
|
21
24
|
|
|
22
25
|
// REQUIRED — build and return the visual root.
|
|
23
26
|
build(): THREE.Object3D {
|
|
24
|
-
this.data.color ??= { type: "color", value: "#3aa0ff" };
|
|
25
27
|
this.mat = new THREE.ShaderMaterial({
|
|
26
28
|
uniforms: {
|
|
27
29
|
uTime: { value: 0 },
|
|
28
|
-
uColor: { value: new THREE.Color(this.data.color
|
|
30
|
+
uColor: { value: new THREE.Color(this.data.color) },
|
|
29
31
|
},
|
|
30
32
|
vertexShader: /* glsl */ `
|
|
31
33
|
uniform float uTime;
|
|
@@ -66,22 +68,33 @@ export default class WavePlane extends ScriptObject {
|
|
|
66
68
|
| --- | --- | --- |
|
|
67
69
|
| `this.world` | `World` | The owning ECS world. |
|
|
68
70
|
| `this.entityId` | `number` | The entity this script is bound to. |
|
|
69
|
-
| `this.data` | `Record<string, unknown>` | Inspector-bound payload. Declare
|
|
71
|
+
| `this.data` | `Record<string, unknown>` | Inspector-bound payload. Declare it with an INLINE literal (`data = { … }`) — never `declare data` (a type-only annotation with no runtime object → no inspector fields). |
|
|
70
72
|
| `this.root` | `THREE.Object3D \| null` | The object `build()` returned (set after build). |
|
|
71
73
|
|
|
72
74
|
## Data fields (inspector)
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
Declare `data` as an **inline literal** (`data = { … }`) with the same input envelopes as Behaviours. **Never use `declare data`** — it is a type-only annotation that produces no runtime object, so the editor can't discover the fields and the inspector shows nothing to edit. (Likewise, don't set defaults with `this.data.x ??= …` inside `build()` — put the default in the literal.)
|
|
77
|
+
|
|
78
|
+
Simple scalars take a value plus an `as <Input>` cast and are read directly:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
data = {
|
|
82
|
+
color: "#3aa0ff" as ColorInput, // color swatch → this.data.color
|
|
83
|
+
speed: 1.0 as FloatInput, // number field → this.data.speed
|
|
84
|
+
enabled: true as ToggleInput, // toggle → this.data.enabled
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Rich inputs that carry metadata are authored as inline objects and read via `.value` (or the resolved view for entity/component pickers):
|
|
75
89
|
|
|
76
90
|
```ts
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
target: EntityInput; // entity picker
|
|
91
|
+
data = {
|
|
92
|
+
amplitude: { type: "slider", min: 0, max: 1, value: 0.5 }, // → this.data.amplitude.value
|
|
93
|
+
target: { type: "entity", value: null }, // → this.data.target.value
|
|
81
94
|
};
|
|
82
95
|
```
|
|
83
96
|
|
|
84
|
-
|
|
97
|
+
See [Data binding](./behaviour-data-binding/) for the full envelope catalog. Edits made in the inspector are pushed to the live instance's `this.data` between frames.
|
|
85
98
|
|
|
86
99
|
## Rules
|
|
87
100
|
|
package/dist/index.cjs
CHANGED
|
@@ -9419,9 +9419,9 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
9419
9419
|
} catch {
|
|
9420
9420
|
instance = new ctor(world, entityId, currentData);
|
|
9421
9421
|
}
|
|
9422
|
-
const
|
|
9423
|
-
const
|
|
9424
|
-
instance.data = resolveInputData(world,
|
|
9422
|
+
const literalDefaults = normalizeScriptData(instance.data);
|
|
9423
|
+
const seed = Object.keys(literalDefaults).length > 0 ? mergeDataByCurrentDefaults(literalDefaults, currentData) : { ...currentData };
|
|
9424
|
+
instance.data = resolveInputData(world, seed);
|
|
9425
9425
|
const parent = world.getComponent(entityId, Object3DRef)?.object;
|
|
9426
9426
|
if (!parent) {
|
|
9427
9427
|
throw new Error("Script object entity has no Object3D to attach to.");
|
|
@@ -9451,6 +9451,13 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
9451
9451
|
built.userData[SCRIPT_OBJECT_ROOT_FLAG] = true;
|
|
9452
9452
|
parent.add(built);
|
|
9453
9453
|
instance.root = built;
|
|
9454
|
+
const postBuildData = normalizeScriptData(instance.data);
|
|
9455
|
+
const schemaDefaults = { ...literalDefaults };
|
|
9456
|
+
for (const [key2, value] of Object.entries(postBuildData)) {
|
|
9457
|
+
if (!(key2 in schemaDefaults)) schemaDefaults[key2] = value;
|
|
9458
|
+
}
|
|
9459
|
+
const merged = mergeDataByCurrentDefaults(schemaDefaults, currentData);
|
|
9460
|
+
instance.data = resolveInputData(world, merged);
|
|
9454
9461
|
const stored = serializeDataForStorage(merged, merged);
|
|
9455
9462
|
component.data = stored;
|
|
9456
9463
|
component.runtimeState = "ready";
|