@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.
Files changed (308) hide show
  1. package/README.md +125 -0
  2. package/dist/System-rXAmagXA.d.cts +659 -0
  3. package/dist/System-rXAmagXA.d.ts +659 -0
  4. package/dist/Video-CDemv74U.d.cts +1261 -0
  5. package/dist/Video-ChKV1UI7.d.ts +1261 -0
  6. package/dist/assets/draco/draco_decoder.js +34 -0
  7. package/dist/assets/draco/draco_decoder.wasm +0 -0
  8. package/dist/assets/draco/draco_wasm_wrapper.js +117 -0
  9. package/dist/chunk-AYEF3X2P.js +223 -0
  10. package/dist/chunk-AYEF3X2P.js.map +1 -0
  11. package/dist/chunk-MAWBTMCG.js +1722 -0
  12. package/dist/chunk-MAWBTMCG.js.map +1 -0
  13. package/dist/chunk-NFDTIYR4.js +248 -0
  14. package/dist/chunk-NFDTIYR4.js.map +1 -0
  15. package/dist/chunk-OY7ZODZP.js +16 -0
  16. package/dist/chunk-OY7ZODZP.js.map +1 -0
  17. package/dist/chunk-P2YDX5DB.js +3304 -0
  18. package/dist/chunk-P2YDX5DB.js.map +1 -0
  19. package/dist/chunk-QHILSPT4.js +3 -0
  20. package/dist/chunk-QHILSPT4.js.map +1 -0
  21. package/dist/chunk-XWIEEJ7Z.js +1315 -0
  22. package/dist/chunk-XWIEEJ7Z.js.map +1 -0
  23. package/dist/components/index.cjs +1745 -0
  24. package/dist/components/index.cjs.map +1 -0
  25. package/dist/components/index.d.cts +4 -0
  26. package/dist/components/index.d.ts +4 -0
  27. package/dist/components/index.js +4 -0
  28. package/dist/components/index.js.map +1 -0
  29. package/dist/docs/api/Behaviour/classes/Behaviour.md +554 -0
  30. package/dist/docs/api/Behaviour/index.md +15 -0
  31. package/dist/docs/api/Component/classes/Component.md +57 -0
  32. package/dist/docs/api/Component/index.md +15 -0
  33. package/dist/docs/api/components/classes/AnimationComponent.md +318 -0
  34. package/dist/docs/api/components/classes/AudioComponent.md +114 -0
  35. package/dist/docs/api/components/classes/CameraComponent.md +59 -0
  36. package/dist/docs/api/components/classes/EntityType.md +48 -0
  37. package/dist/docs/api/components/classes/Environment.md +47 -0
  38. package/dist/docs/api/components/classes/ImageComponent.md +57 -0
  39. package/dist/docs/api/components/classes/ImageTarget.md +60 -0
  40. package/dist/docs/api/components/classes/ImageTargetAnchor.md +48 -0
  41. package/dist/docs/api/components/classes/LightComponent.md +70 -0
  42. package/dist/docs/api/components/classes/MaterialComponent.md +181 -0
  43. package/dist/docs/api/components/classes/MeshComponent.md +48 -0
  44. package/dist/docs/api/components/classes/MeshGeometryComponent.md +64 -0
  45. package/dist/docs/api/components/classes/ModelComponent.md +49 -0
  46. package/dist/docs/api/components/classes/Name.md +46 -0
  47. package/dist/docs/api/components/classes/Object3DRef.md +54 -0
  48. package/dist/docs/api/components/classes/ParentId.md +47 -0
  49. package/dist/docs/api/components/classes/PhysicsComponent.md +82 -0
  50. package/dist/docs/api/components/classes/Postprocessing.md +49 -0
  51. package/dist/docs/api/components/classes/ScriptComponent.md +54 -0
  52. package/dist/docs/api/components/classes/Selectable.md +46 -0
  53. package/dist/docs/api/components/classes/SelectionTransformState.md +54 -0
  54. package/dist/docs/api/components/classes/SpriteComponent.md +55 -0
  55. package/dist/docs/api/components/classes/TransformComponent.md +197 -0
  56. package/dist/docs/api/components/classes/VideoComponent.md +123 -0
  57. package/dist/docs/api/components/functions/normalizePhysicsState.md +23 -0
  58. package/dist/docs/api/components/index.md +94 -0
  59. package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +42 -0
  60. package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +45 -0
  61. package/dist/docs/api/components/type-aliases/CameraProjection.md +15 -0
  62. package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +15 -0
  63. package/dist/docs/api/components/type-aliases/ColliderShape.md +15 -0
  64. package/dist/docs/api/components/type-aliases/ColliderState.md +62 -0
  65. package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +27 -0
  66. package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +15 -0
  67. package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +37 -0
  68. package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +15 -0
  69. package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +15 -0
  70. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +34 -0
  71. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +15 -0
  72. package/dist/docs/api/components/type-aliases/EnvironmentState.md +29 -0
  73. package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +25 -0
  74. package/dist/docs/api/components/type-aliases/ImageTargetReference.md +33 -0
  75. package/dist/docs/api/components/type-aliases/LightValueState.md +41 -0
  76. package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +15 -0
  77. package/dist/docs/api/components/type-aliases/MaterialValueState.md +75 -0
  78. package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +13 -0
  79. package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +33 -0
  80. package/dist/docs/api/components/type-aliases/PhysicsState.md +25 -0
  81. package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +25 -0
  82. package/dist/docs/api/components/type-aliases/PostprocessingState.md +164 -0
  83. package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +25 -0
  84. package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +23 -0
  85. package/dist/docs/api/components/type-aliases/RigidbodyState.md +53 -0
  86. package/dist/docs/api/components/type-aliases/RigidbodyType.md +19 -0
  87. package/dist/docs/api/components/type-aliases/ScriptEntry.md +38 -0
  88. package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +15 -0
  89. package/dist/docs/api/components/type-aliases/TransformData.md +27 -0
  90. package/dist/docs/api/components/type-aliases/TransformModeValue.md +15 -0
  91. package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +15 -0
  92. package/dist/docs/api/components/type-aliases/Vec3.md +27 -0
  93. package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +13 -0
  94. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +13 -0
  95. package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +13 -0
  96. package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +13 -0
  97. package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +13 -0
  98. package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +13 -0
  99. package/dist/docs/api/index/classes/AnimationStateMachine.md +201 -0
  100. package/dist/docs/api/index/classes/AnimationStateManager.md +253 -0
  101. package/dist/docs/api/index/classes/AnimationSystem.md +68 -0
  102. package/dist/docs/api/index/classes/AudioSystem.md +98 -0
  103. package/dist/docs/api/index/classes/CameraSyncSystem.md +49 -0
  104. package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +75 -0
  105. package/dist/docs/api/index/classes/InputSystem.md +449 -0
  106. package/dist/docs/api/index/classes/LightSyncSystem.md +49 -0
  107. package/dist/docs/api/index/classes/MaterialSyncSystem.md +67 -0
  108. package/dist/docs/api/index/classes/MeshGeometrySystem.md +49 -0
  109. package/dist/docs/api/index/classes/ObjectManagementSystem.md +298 -0
  110. package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +49 -0
  111. package/dist/docs/api/index/classes/PhysicsSyncSystem.md +83 -0
  112. package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +80 -0
  113. package/dist/docs/api/index/classes/RenderSystem.md +64 -0
  114. package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +83 -0
  115. package/dist/docs/api/index/classes/TransformSyncSystem.md +49 -0
  116. package/dist/docs/api/index/classes/VideoSystem.md +97 -0
  117. package/dist/docs/api/index/classes/World.md +1405 -0
  118. package/dist/docs/api/index/functions/createAnimationComponent.md +28 -0
  119. package/dist/docs/api/index/functions/createAudioComponent.md +32 -0
  120. package/dist/docs/api/index/functions/createCameraComponent.md +28 -0
  121. package/dist/docs/api/index/functions/createEntityTypeComponent.md +28 -0
  122. package/dist/docs/api/index/functions/createEnvironmentComponent.md +28 -0
  123. package/dist/docs/api/index/functions/createImageComponent.md +28 -0
  124. package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +28 -0
  125. package/dist/docs/api/index/functions/createImageTargetComponent.md +28 -0
  126. package/dist/docs/api/index/functions/createLightComponent.md +28 -0
  127. package/dist/docs/api/index/functions/createMaterialComponent.md +28 -0
  128. package/dist/docs/api/index/functions/createMeshComponent.md +28 -0
  129. package/dist/docs/api/index/functions/createMeshGeometryComponent.md +28 -0
  130. package/dist/docs/api/index/functions/createModelComponent.md +28 -0
  131. package/dist/docs/api/index/functions/createNameComponent.md +28 -0
  132. package/dist/docs/api/index/functions/createObject3DRefComponent.md +28 -0
  133. package/dist/docs/api/index/functions/createParentIdComponent.md +28 -0
  134. package/dist/docs/api/index/functions/createPhysicsComponent.md +30 -0
  135. package/dist/docs/api/index/functions/createPostprocessingComponent.md +28 -0
  136. package/dist/docs/api/index/functions/createScriptComponent.md +28 -0
  137. package/dist/docs/api/index/functions/createSelectableComponent.md +28 -0
  138. package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +28 -0
  139. package/dist/docs/api/index/functions/createSpriteComponent.md +28 -0
  140. package/dist/docs/api/index/functions/createTransformComponent.md +28 -0
  141. package/dist/docs/api/index/functions/createVideoComponent.md +28 -0
  142. package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +28 -0
  143. package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +28 -0
  144. package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +23 -0
  145. package/dist/docs/api/index/functions/registerDefaultFactories.md +23 -0
  146. package/dist/docs/api/index/index.md +249 -0
  147. package/dist/docs/api/index/interfaces/EcsSystem.md +50 -0
  148. package/dist/docs/api/index/interfaces/StateMachine.md +26 -0
  149. package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +25 -0
  150. package/dist/docs/api/index/type-aliases/ComponentFactory.md +25 -0
  151. package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +37 -0
  152. package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +26 -0
  153. package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +25 -0
  154. package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +23 -0
  155. package/dist/docs/api/index/type-aliases/KeyboardKey.md +13 -0
  156. package/dist/docs/api/index/type-aliases/MouseButton.md +13 -0
  157. package/dist/docs/api/index/type-aliases/SelectionContext.md +31 -0
  158. package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +13 -0
  159. package/dist/docs/api/index/variables/KeyboardKeys.md +195 -0
  160. package/dist/docs/api/index.md +15 -0
  161. package/dist/docs/api/typedoc-sidebar.json +1 -0
  162. package/dist/docs/api/types/index.md +34 -0
  163. package/dist/docs/api/types/type-aliases/AssetInput.md +23 -0
  164. package/dist/docs/api/types/type-aliases/CheckboxInput.md +13 -0
  165. package/dist/docs/api/types/type-aliases/ColorInput.md +13 -0
  166. package/dist/docs/api/types/type-aliases/ComponentInput.md +52 -0
  167. package/dist/docs/api/types/type-aliases/ComponentKind.md +37 -0
  168. package/dist/docs/api/types/type-aliases/DropdownInput.md +23 -0
  169. package/dist/docs/api/types/type-aliases/DropdownOption.md +23 -0
  170. package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +15 -0
  171. package/dist/docs/api/types/type-aliases/EcsEntityKind.md +35 -0
  172. package/dist/docs/api/types/type-aliases/EntityId.md +16 -0
  173. package/dist/docs/api/types/type-aliases/EntityInput.md +23 -0
  174. package/dist/docs/api/types/type-aliases/FloatInput.md +13 -0
  175. package/dist/docs/api/types/type-aliases/IntersectionResult.md +29 -0
  176. package/dist/docs/api/types/type-aliases/ParentLookup.md +26 -0
  177. package/dist/docs/api/types/type-aliases/SelectionListener.md +25 -0
  178. package/dist/docs/api/types/type-aliases/SliderInput.md +27 -0
  179. package/dist/docs/api/types/type-aliases/TextInput.md +13 -0
  180. package/dist/docs/api/types/type-aliases/ToggleInput.md +13 -0
  181. package/dist/docs/api/types/type-aliases/Vec3.md +23 -0
  182. package/dist/docs/api/types/type-aliases/Vector2Input.md +23 -0
  183. package/dist/docs/api/types/type-aliases/Vector3Input.md +25 -0
  184. package/dist/docs/api/types/type-aliases/WorldEntityView.md +17 -0
  185. package/dist/docs/guide/accessing-components.md +399 -0
  186. package/dist/docs/guide/authoring-a-behaviour.md +166 -0
  187. package/dist/docs/guide/behaviour-lifecycle.md +43 -0
  188. package/dist/docs/guide/component-catalog.md +59 -0
  189. package/dist/docs/guide/components/_sidebar.json +78 -0
  190. package/dist/docs/guide/components/animation.md +171 -0
  191. package/dist/docs/guide/components/audio.md +181 -0
  192. package/dist/docs/guide/components/camera.md +179 -0
  193. package/dist/docs/guide/components/entity-type.md +141 -0
  194. package/dist/docs/guide/components/image-target-anchor.md +103 -0
  195. package/dist/docs/guide/components/image-target.md +122 -0
  196. package/dist/docs/guide/components/image.md +146 -0
  197. package/dist/docs/guide/components/light.md +157 -0
  198. package/dist/docs/guide/components/material.md +161 -0
  199. package/dist/docs/guide/components/mesh-geometry.md +153 -0
  200. package/dist/docs/guide/components/mesh.md +151 -0
  201. package/dist/docs/guide/components/model.md +96 -0
  202. package/dist/docs/guide/components/name.md +121 -0
  203. package/dist/docs/guide/components/object3d-ref.md +115 -0
  204. package/dist/docs/guide/components/parent-id.md +108 -0
  205. package/dist/docs/guide/components/physics.md +163 -0
  206. package/dist/docs/guide/components/script.md +142 -0
  207. package/dist/docs/guide/components/sprite.md +155 -0
  208. package/dist/docs/guide/components/transform.md +155 -0
  209. package/dist/docs/guide/components/video.md +153 -0
  210. package/dist/docs/guide/concepts.md +34 -0
  211. package/dist/docs/guide/getting-started/creating-objects.md +50 -0
  212. package/dist/docs/guide/getting-started/editing-objects.md +62 -0
  213. package/dist/docs/guide/getting-started/editor/assets-browser.md +55 -0
  214. package/dist/docs/guide/getting-started/editor/hierarchy.md +47 -0
  215. package/dist/docs/guide/getting-started/editor/index.md +16 -0
  216. package/dist/docs/guide/getting-started/editor/inspector.md +36 -0
  217. package/dist/docs/guide/getting-started/editor/modules.md +35 -0
  218. package/dist/docs/guide/getting-started/editor/scene-inspector.md +64 -0
  219. package/dist/docs/guide/getting-started/editor/toolbar.md +39 -0
  220. package/dist/docs/guide/getting-started/editor/viewport.md +43 -0
  221. package/dist/docs/guide/getting-started/first-launch.md +17 -0
  222. package/dist/docs/guide/getting-started/index.md +37 -0
  223. package/dist/docs/guide/getting-started/installation.md +59 -0
  224. package/dist/docs/guide/getting-started/preview-and-test.md +55 -0
  225. package/dist/docs/guide/getting-started/project-types/3d.md +30 -0
  226. package/dist/docs/guide/getting-started/project-types/ar.md +6 -0
  227. package/dist/docs/guide/getting-started/project-types/face-tracking.md +6 -0
  228. package/dist/docs/guide/getting-started/project-types/image-tracking.md +42 -0
  229. package/dist/docs/guide/getting-started/project-types/index.md +25 -0
  230. package/dist/docs/guide/getting-started/project-types/vr.md +6 -0
  231. package/dist/docs/guide/getting-started/projects.md +53 -0
  232. package/dist/docs/guide/getting-started/shortcuts.md +43 -0
  233. package/dist/docs/guide/inspector-data-binding.md +367 -0
  234. package/dist/docs/guide/reading-input.md +202 -0
  235. package/dist/docs/guide/scene/environment.md +101 -0
  236. package/dist/docs/guide/scene/index.md +36 -0
  237. package/dist/docs/guide/scene/postprocessing.md +108 -0
  238. package/dist/docs/guide/spawning/ambient-light.md +28 -0
  239. package/dist/docs/guide/spawning/area-light.md +32 -0
  240. package/dist/docs/guide/spawning/audio.md +42 -0
  241. package/dist/docs/guide/spawning/camera.md +50 -0
  242. package/dist/docs/guide/spawning/capsule.md +29 -0
  243. package/dist/docs/guide/spawning/cube.md +31 -0
  244. package/dist/docs/guide/spawning/cylinder.md +29 -0
  245. package/dist/docs/guide/spawning/directional-light.md +32 -0
  246. package/dist/docs/guide/spawning/empty.md +31 -0
  247. package/dist/docs/guide/spawning/image-target.md +48 -0
  248. package/dist/docs/guide/spawning/image.md +33 -0
  249. package/dist/docs/guide/spawning/index.md +79 -0
  250. package/dist/docs/guide/spawning/model.md +31 -0
  251. package/dist/docs/guide/spawning/plane.md +31 -0
  252. package/dist/docs/guide/spawning/point-light.md +32 -0
  253. package/dist/docs/guide/spawning/sphere.md +29 -0
  254. package/dist/docs/guide/spawning/spot-light.md +32 -0
  255. package/dist/docs/guide/spawning/sprite.md +31 -0
  256. package/dist/docs/guide/spawning/video.md +53 -0
  257. package/dist/docs/guide/system-overview.md +73 -0
  258. package/dist/docs/guide/systems/_sidebar.json +66 -0
  259. package/dist/docs/guide/systems/animation-system.md +32 -0
  260. package/dist/docs/guide/systems/audio-system.md +28 -0
  261. package/dist/docs/guide/systems/camera-sync-system.md +31 -0
  262. package/dist/docs/guide/systems/environment-sync-system.md +31 -0
  263. package/dist/docs/guide/systems/input-system.md +217 -0
  264. package/dist/docs/guide/systems/light-sync-system.md +29 -0
  265. package/dist/docs/guide/systems/material-sync-system.md +32 -0
  266. package/dist/docs/guide/systems/mesh-geometry-system.md +40 -0
  267. package/dist/docs/guide/systems/object-management-system.md +38 -0
  268. package/dist/docs/guide/systems/object-visibility-system.md +26 -0
  269. package/dist/docs/guide/systems/physics-sync-system.md +56 -0
  270. package/dist/docs/guide/systems/postprocessing-sync-system.md +43 -0
  271. package/dist/docs/guide/systems/render-system.md +22 -0
  272. package/dist/docs/guide/systems/script-behaviour-system.md +59 -0
  273. package/dist/docs/guide/systems/transform-sync-system.md +29 -0
  274. package/dist/docs/guide/systems/video-system.md +30 -0
  275. package/dist/docs/guide/world-api.md +405 -0
  276. package/dist/factories/index.cjs +3077 -0
  277. package/dist/factories/index.cjs.map +1 -0
  278. package/dist/factories/index.d.cts +69 -0
  279. package/dist/factories/index.d.ts +69 -0
  280. package/dist/factories/index.js +6 -0
  281. package/dist/factories/index.js.map +1 -0
  282. package/dist/index-B4-YyUNR.d.cts +73 -0
  283. package/dist/index-BZUOKeTO.d.ts +73 -0
  284. package/dist/index.cjs +8584 -0
  285. package/dist/index.cjs.map +1 -0
  286. package/dist/index.d.cts +283 -0
  287. package/dist/index.d.ts +283 -0
  288. package/dist/index.js +1729 -0
  289. package/dist/index.js.map +1 -0
  290. package/dist/systems/index.cjs +5119 -0
  291. package/dist/systems/index.cjs.map +1 -0
  292. package/dist/systems/index.d.cts +200 -0
  293. package/dist/systems/index.d.ts +200 -0
  294. package/dist/systems/index.js +6 -0
  295. package/dist/systems/index.js.map +1 -0
  296. package/dist/types.cjs +4 -0
  297. package/dist/types.cjs.map +1 -0
  298. package/dist/types.d.cts +3 -0
  299. package/dist/types.d.ts +3 -0
  300. package/dist/types.js +3 -0
  301. package/dist/types.js.map +1 -0
  302. package/dist/worldSnapshotUtils.cjs +259 -0
  303. package/dist/worldSnapshotUtils.cjs.map +1 -0
  304. package/dist/worldSnapshotUtils.d.cts +3 -0
  305. package/dist/worldSnapshotUtils.d.ts +3 -0
  306. package/dist/worldSnapshotUtils.js +4 -0
  307. package/dist/worldSnapshotUtils.js.map +1 -0
  308. package/package.json +80 -0
@@ -0,0 +1,161 @@
1
+ # Material
2
+
3
+ Material catalog for an entity. Tracks the live three.js materials (`materials`, `material`) plus serialized authoring state (`values[]`) mirrored from the inspector. Supports `standard`, `basic`, `phong`, and `physical` PBR types with optional texture map slots. Use `setMaterials`, `updateValue`, `setMaterialType`, `setTextureFiltering`, and `setUseMipmaps` to mutate state — these keep `values[]` and the live three.js materials in sync. Texture URLs use the `localasset://` protocol inside the editor.
4
+
5
+ > **Managed by:** [`MaterialSyncSystem`](../systems/material-sync-system)
6
+
7
+ ## Editor inspector
8
+
9
+ ![Material inspector](/images/components/Material.png)
10
+
11
+ ## Properties
12
+
13
+ | Property | Type | Description |
14
+ | --- | --- | --- |
15
+ | `materials` | `THREE.Material[]` | Live three.js materials currently bound to the entity's mesh (one per submesh). |
16
+ | `material` | `THREE.Material \| null` | Convenience reference to `materials[0]`. `null` when no material is assigned. |
17
+ | `values` | `MaterialValueState[]` | Serialized authoring state (one entry per material in `materials`). Saved with the project. |
18
+
19
+ ## API reference
20
+
21
+ - Class: [`MaterialComponent`](../../api/components/classes/MaterialComponent.md)
22
+ - Source: [`core/components/Material.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Material.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 mat = this.getComponent(MaterialComponent);
32
+
33
+ // Component on another entity, found by its scene name
34
+ const other = this.world.getEntityByName("Wall");
35
+ if (other) {
36
+ const mat = this.world.getComponent(other.entityId, MaterialComponent);
37
+ }
38
+ ```
39
+ :::
40
+
41
+ ### Fade opacity with a sine wave
42
+
43
+ Animate material transparency to create a pulsing ghost or reveal effect. Use `updateValue` so the state persists in the ECS snapshot — `MaterialSyncSystem` applies it to the live material each frame.
44
+
45
+ ```typescript
46
+ import { Behaviour, MaterialComponent } from "@relu-interactives/spatial-ecs";
47
+ import type { FloatInput } from "@relu-interactives/spatial-ecs";
48
+
49
+ export default class MaterialFade extends Behaviour {
50
+ data = {
51
+ speed: 1 as FloatInput,
52
+ };
53
+
54
+ private elapsed = 0;
55
+
56
+ protected onUpdate() {
57
+ this.elapsed += this.deltaTime;
58
+ const mat = this.getComponent(MaterialComponent);
59
+ if (!mat) return;
60
+
61
+ const opacity = (Math.sin(this.elapsed * this.data.speed) + 1) * 0.5;
62
+ mat.updateValue(0, 'transparent', true);
63
+ mat.updateValue(0, 'opacity', opacity);
64
+ }
65
+ }
66
+ ```
67
+
68
+ ::: warning Transient vs persistent opacity
69
+ `mat.updateValue(0, 'opacity', value)` keeps `values[]` in sync with the live material — changes survive a project reload.
70
+
71
+ Mutating `mat.material?.opacity` directly can work for transient visual-only effects, but `MaterialSyncSystem` may overwrite it when other material properties change. Prefer `updateValue` for any state you want to persist.
72
+ :::
73
+
74
+ ### Change material color at runtime
75
+
76
+ Let the inspector drive the diffuse color live without restarting the scene.
77
+
78
+ ```typescript
79
+ import { Behaviour, MaterialComponent } from "@relu-interactives/spatial-ecs";
80
+ import type { ColorInput } from "@relu-interactives/spatial-ecs";
81
+
82
+ export default class MaterialColorDriver extends Behaviour {
83
+ data = {
84
+ color: "#ff0000" as ColorInput,
85
+ };
86
+
87
+ private _prev: string | null = null;
88
+
89
+ protected onUpdate() {
90
+ // Guard — only call updateValue when the color actually changes
91
+ if (this.data.color === this._prev) return;
92
+ this._prev = this.data.color;
93
+
94
+ const mat = this.getComponent(MaterialComponent);
95
+ if (!mat) return;
96
+ mat.updateValue(0, 'color', this.data.color);
97
+ }
98
+ }
99
+ ```
100
+
101
+ ::: tip Material sync
102
+ `updateValue(index, key, value)` writes to `values[]` (persisted with the project) and lets `MaterialSyncSystem` apply the change to the live THREE.js material. Mutating `material.color` or other THREE.js properties directly is not saved with the project.
103
+ :::
104
+
105
+ ### Via `ComponentInput` in the inspector
106
+
107
+ 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 `MaterialComponent` instance at runtime.
108
+
109
+ ```typescript
110
+ import {
111
+ Behaviour,
112
+ MaterialComponent,
113
+ type ComponentInput,
114
+ } from "@relu-interactives/spatial-ecs";
115
+
116
+ export default class Example extends Behaviour {
117
+ data = {
118
+ targetMaterial: {
119
+ type: "component",
120
+ value: null,
121
+ } as unknown as ComponentInput,
122
+ };
123
+
124
+ protected onUpdate() {
125
+ const mat = this.data.targetMaterial.value as MaterialComponent | null;
126
+ if (!mat) return;
127
+ // Use the live component instance.
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Via `EntityInput` in the inspector
133
+
134
+ Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
135
+
136
+ ```typescript
137
+ import {
138
+ Behaviour,
139
+ MaterialComponent,
140
+ type EntityInput,
141
+ type WorldEntityView,
142
+ } from "@relu-interactives/spatial-ecs";
143
+
144
+ export default class Example extends Behaviour {
145
+ data = {
146
+ targetEntity: { type: "entity", value: null } as unknown as EntityInput,
147
+ };
148
+
149
+ protected onUpdate() {
150
+ const entity = this.data.targetEntity.value as WorldEntityView | null;
151
+ if (!entity) return;
152
+
153
+ const mat = this.world.getComponent(
154
+ entity.entityId,
155
+ MaterialComponent,
156
+ ) as MaterialComponent | null;
157
+ if (!mat) return;
158
+ // Use the component on the picked entity.
159
+ }
160
+ }
161
+ ```
@@ -0,0 +1,153 @@
1
+ # Mesh Geometry
2
+
3
+ Editable geometry parameters for primitive meshes (cube, sphere, plane, capsule, cylinder) and the placeholder for `model` entities. Holds the authoring values plus shadow casting/receiving flags. The mesh-geometry system rebuilds the underlying `BufferGeometry` when parameters change.
4
+
5
+ > **Managed by:** [`MeshGeometrySystem`](../systems/mesh-geometry-system)
6
+
7
+ ## Properties
8
+
9
+ | Property | Type | Description |
10
+ | --- | --- | --- |
11
+ | `kind` | `EditableMeshObjectKind` | Primitive kind (`cube`, `sphere`, `plane`, `capsule`, `cylinder`) or `model` for loaded assets. |
12
+ | `geometryType` | `string` | Three.js geometry class name (e.g. `"BoxGeometry"`, `"SphereGeometry"`). Derived from `kind`. |
13
+ | `parameters` | `MeshGeometryParameters` | Editable parameters whose shape depends on `kind`. The mesh-geometry system rebuilds geometry when these change. |
14
+ | `object` | `THREE.Object3D \| null` | Live three.js object whose geometry is being managed. `null` until the object is built. |
15
+ | `modelName` | `string` | Human-readable model name shown in the inspector for `model` entities; empty for primitives. |
16
+ | `castShadow` | `boolean` | Whether the mesh casts shadows in the renderer. |
17
+ | `receiveShadow` | `boolean` | Whether the mesh receives shadows in the renderer. |
18
+
19
+ ## API reference
20
+
21
+ - Class: [`MeshGeometryComponent`](../../api/components/classes/MeshGeometryComponent.md)
22
+ - Source: [`core/components/MeshGeometry.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/MeshGeometry.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 geo = this.getComponent(MeshGeometryComponent);
32
+
33
+ // Component on another entity, found by its scene name
34
+ const other = this.world.getEntityByName("Floor");
35
+ if (other) {
36
+ const geo = this.world.getComponent(other.entityId, MeshGeometryComponent);
37
+ }
38
+ ```
39
+ :::
40
+
41
+ ### Toggle shadow casting at runtime
42
+
43
+ Let the inspector or game logic control whether the mesh casts and receives shadows.
44
+
45
+ ```typescript
46
+ import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
47
+ import type { BooleanInput } from "@relu-interactives/spatial-ecs";
48
+
49
+ export default class ShadowDriver extends Behaviour {
50
+ data = {
51
+ castShadow: true as BooleanInput,
52
+ receiveShadow: true as BooleanInput,
53
+ };
54
+
55
+ protected onUpdate() {
56
+ const geo = this.getComponent(MeshGeometryComponent);
57
+ if (!geo) return;
58
+ geo.castShadow = this.data.castShadow;
59
+ geo.receiveShadow = this.data.receiveShadow;
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Animate sphere radius
65
+
66
+ Pulse the radius of a sphere primitive by writing to its geometry `parameters` each frame. The mesh-geometry system rebuilds the `BufferGeometry` when parameters change.
67
+
68
+ ```typescript
69
+ import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
70
+ import type { FloatInput } from "@relu-interactives/spatial-ecs";
71
+
72
+ export default class SphereGrow extends Behaviour {
73
+ data = {
74
+ speed: 1 as FloatInput,
75
+ minRadius: 0.3 as FloatInput,
76
+ maxRadius: 1 as FloatInput,
77
+ };
78
+
79
+ private elapsed = 0;
80
+
81
+ protected onUpdate() {
82
+ this.elapsed += this.deltaTime;
83
+ const geo = this.getComponent(MeshGeometryComponent);
84
+ if (!geo || geo.kind !== "sphere") return;
85
+
86
+ const t = (Math.sin(this.elapsed * this.data.speed) + 1) * 0.5;
87
+ const radius = this.data.minRadius + t * (this.data.maxRadius - this.data.minRadius);
88
+ (geo.parameters as { radius: number }).radius = radius;
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### Via `ComponentInput` in the inspector
94
+
95
+ 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 `MeshGeometryComponent` instance at runtime.
96
+
97
+ ```typescript
98
+ import {
99
+ Behaviour,
100
+ MeshGeometryComponent,
101
+ type ComponentInput,
102
+ } from "@relu-interactives/spatial-ecs";
103
+
104
+ export default class Example extends Behaviour {
105
+ data = {
106
+ targetGeometry: {
107
+ type: "component",
108
+ value: null,
109
+ } as unknown as ComponentInput,
110
+ };
111
+
112
+ protected onUpdate() {
113
+ const geo = this.data.targetGeometry.value as MeshGeometryComponent | null;
114
+ if (!geo) return;
115
+ // Use the live component instance.
116
+ }
117
+ }
118
+ ```
119
+
120
+ ### Via `EntityInput` in the inspector
121
+
122
+ Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
123
+
124
+ ```typescript
125
+ import {
126
+ Behaviour,
127
+ MeshGeometryComponent,
128
+ type EntityInput,
129
+ type WorldEntityView,
130
+ } from "@relu-interactives/spatial-ecs";
131
+
132
+ export default class Example extends Behaviour {
133
+ data = {
134
+ targetEntity: { type: "entity", value: null } as unknown as EntityInput,
135
+ };
136
+
137
+ protected onUpdate() {
138
+ const entity = this.data.targetEntity.value as WorldEntityView | null;
139
+ if (!entity) return;
140
+
141
+ const geo = this.world.getComponent(
142
+ entity.entityId,
143
+ MeshGeometryComponent,
144
+ ) as MeshGeometryComponent | null;
145
+ if (!geo) return;
146
+ // Use the component on the picked entity.
147
+ }
148
+ }
149
+ ```
150
+
151
+ ::: tip Geometry rebuild cost
152
+ The mesh-geometry system only rebuilds geometry when parameters actually change. Avoid writing the same value every frame unless the value is genuinely different, to prevent unnecessary geometry allocations.
153
+ :::
@@ -0,0 +1,151 @@
1
+ # Mesh
2
+
3
+ Holds the live three.js `Object3D` for an entity that renders as a primitive mesh (cube, sphere, plane, capsule, cylinder). For loaded GLTF/GLB models see `ModelComponent`; for the editable geometry parameters see `MeshGeometryComponent`.
4
+
5
+ ## Editor inspector
6
+
7
+ ![Mesh inspector](/images/components/Mesh.png)
8
+
9
+ ## Properties
10
+
11
+ | Property | Type | Description |
12
+ | --- | --- | --- |
13
+ | `mesh` | `THREE.Object3D` | Underlying three.js mesh placed in the scene graph. |
14
+
15
+ ## API reference
16
+
17
+ - Class: [`MeshComponent`](../../api/components/classes/MeshComponent.md)
18
+ - Source: [`core/components/Mesh.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Mesh.ts)
19
+
20
+ ## Scripting examples
21
+
22
+ ::: tip Component access patterns
23
+ 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:
24
+
25
+ ```typescript
26
+ // Component on the entity this script is on
27
+ const mesh = this.getComponent(MeshComponent);
28
+
29
+ // Component on another entity, found by its scene name
30
+ const other = this.world.getEntityByName("Terrain");
31
+ if (other) {
32
+ const mesh = this.world.getComponent(other.entityId, MeshComponent);
33
+ }
34
+ ```
35
+ :::
36
+
37
+ ### Toggle shadow casting on all sub-meshes
38
+
39
+ Walk the mesh hierarchy and enable or disable shadow casting based on a boolean inspector field.
40
+
41
+ ```typescript
42
+ import { Behaviour, MeshComponent } from "@relu-interactives/spatial-ecs";
43
+ import type { BooleanInput } from "@relu-interactives/spatial-ecs";
44
+
45
+ export default class ShadowToggle extends Behaviour {
46
+ data = {
47
+ castShadow: true as BooleanInput,
48
+ receiveShadow: true as BooleanInput,
49
+ };
50
+
51
+ protected onUpdate() {
52
+ const mesh = this.getComponent(MeshComponent);
53
+ if (!mesh?.mesh) return;
54
+
55
+ mesh.mesh.traverse((child: any) => {
56
+ if (child.isMesh) {
57
+ child.castShadow = this.data.castShadow;
58
+ child.receiveShadow = this.data.receiveShadow;
59
+ }
60
+ });
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### Change vertex color or material on the raw mesh
66
+
67
+ Access the underlying `THREE.Object3D` directly for low-level material mutations that are not exposed through `MaterialComponent`.
68
+
69
+ ```typescript
70
+ import { Behaviour, MeshComponent } from "@relu-interactives/spatial-ecs";
71
+ import type { ColorInput } from "@relu-interactives/spatial-ecs";
72
+
73
+ export default class MeshColorDriver extends Behaviour {
74
+ data = {
75
+ color: "#ffffff" as ColorInput,
76
+ };
77
+
78
+ protected onUpdate() {
79
+ const mesh = this.getComponent(MeshComponent);
80
+ if (!mesh?.mesh) return;
81
+
82
+ mesh.mesh.traverse((child: any) => {
83
+ if (child.isMesh && child.material?.color) {
84
+ child.material.color.set(this.data.color);
85
+ }
86
+ });
87
+ }
88
+ }
89
+ ```
90
+
91
+ ::: tip Prefer MaterialComponent for authored changes
92
+ For changes that should persist across save/reload, prefer `MaterialComponent.updateValue()` which keeps the serialised `values[]` in sync. Use `MeshComponent.mesh` for frame-by-frame visual effects only.
93
+ :::
94
+
95
+ ### Via `ComponentInput` in the inspector
96
+
97
+ 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 `MeshComponent` instance at runtime.
98
+
99
+ ```typescript
100
+ import {
101
+ Behaviour,
102
+ MeshComponent,
103
+ type ComponentInput,
104
+ } from "@relu-interactives/spatial-ecs";
105
+
106
+ export default class Example extends Behaviour {
107
+ data = {
108
+ targetMesh: {
109
+ type: "component",
110
+ value: null,
111
+ } as unknown as ComponentInput,
112
+ };
113
+
114
+ protected onUpdate() {
115
+ const mesh = this.data.targetMesh.value as MeshComponent | null;
116
+ if (!mesh) return;
117
+ // Use the live component instance.
118
+ }
119
+ }
120
+ ```
121
+
122
+ ### Via `EntityInput` in the inspector
123
+
124
+ Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
125
+
126
+ ```typescript
127
+ import {
128
+ Behaviour,
129
+ MeshComponent,
130
+ type EntityInput,
131
+ type WorldEntityView,
132
+ } from "@relu-interactives/spatial-ecs";
133
+
134
+ export default class Example extends Behaviour {
135
+ data = {
136
+ targetEntity: { type: "entity", value: null } as unknown as EntityInput,
137
+ };
138
+
139
+ protected onUpdate() {
140
+ const entity = this.data.targetEntity.value as WorldEntityView | null;
141
+ if (!entity) return;
142
+
143
+ const mesh = this.world.getComponent(
144
+ entity.entityId,
145
+ MeshComponent,
146
+ ) as MeshComponent | null;
147
+ if (!mesh) return;
148
+ // Use the component on the picked entity.
149
+ }
150
+ }
151
+ ```
@@ -0,0 +1,96 @@
1
+ # Model
2
+
3
+ References a GLTF/GLB asset loaded from `path`. The model loading system resolves the asset asynchronously and populates `ModelComponent.object` once available; loading is deferred-tolerant so the entity exists before the model finishes loading.
4
+
5
+ ## Properties
6
+
7
+ | Property | Type | Description |
8
+ | --- | --- | --- |
9
+ | `path` | `string` | Source URL or `localasset://` path of the GLTF/GLB asset. |
10
+ | `object` | `THREE.Object3D \| null` | Loaded model object, populated asynchronously by the model loader. `null` until loaded. |
11
+
12
+ ## API reference
13
+
14
+ - Class: [`ModelComponent`](../../api/components/classes/ModelComponent.md)
15
+ - Source: [`core/components/Model.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Model.ts)
16
+
17
+ ## Scripting examples
18
+
19
+ ::: tip Component access patterns
20
+ 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:
21
+
22
+ ```typescript
23
+ // Component on the entity this script is on
24
+ const model = this.getComponent(ModelComponent);
25
+
26
+ // Component on another entity, found by its scene name
27
+ const other = this.world.getEntityByName("Robot");
28
+ if (other) {
29
+ const model = this.world.getComponent(other.entityId, ModelComponent);
30
+ }
31
+ ```
32
+ :::
33
+
34
+ ### Fade the model in after it loads
35
+
36
+ Wait for the async model load to complete, then animate opacity to 1 over one second.
37
+
38
+ ```typescript
39
+ import { Behaviour, ModelComponent } from "@relu-interactives/spatial-ecs";
40
+
41
+ export default class ModelFadeIn extends Behaviour {
42
+ private fadeProgress = 0;
43
+ private started = false;
44
+
45
+ protected onUpdate() {
46
+ const model = this.getComponent(ModelComponent);
47
+ if (!model?.object) return; // wait for async load to complete
48
+
49
+ if (!this.started) {
50
+ this.started = true;
51
+ // Initialise all sub-mesh materials to transparent before fading in
52
+ model.object.traverse((child: any) => {
53
+ if (child.isMesh && child.material) {
54
+ child.material.transparent = true;
55
+ child.material.opacity = 0;
56
+ }
57
+ });
58
+ }
59
+
60
+ this.fadeProgress = Math.min(1, this.fadeProgress + this.deltaTime);
61
+ model.object.traverse((child: any) => {
62
+ if (child.isMesh && child.material) {
63
+ child.material.opacity = this.fadeProgress;
64
+ }
65
+ });
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### Toggle model visibility
71
+
72
+ Show or hide the loaded model at runtime using the `Object3DRef` visibility flag.
73
+
74
+ ```typescript
75
+ import { Behaviour, ModelComponent, Object3DRef } from "@relu-interactives/spatial-ecs";
76
+ import type { BooleanInput } from "@relu-interactives/spatial-ecs";
77
+
78
+ export default class ModelVisibility extends Behaviour {
79
+ data = {
80
+ visible: true as BooleanInput,
81
+ };
82
+
83
+ protected onUpdate() {
84
+ const model = this.getComponent(ModelComponent);
85
+ if (!model?.object) return; // still loading
86
+
87
+ const ref = this.getComponent(Object3DRef);
88
+ if (ref) ref.visibility = this.data.visible;
89
+ }
90
+ }
91
+ ```
92
+
93
+ ::: tip Async loading
94
+ Always guard with `model?.object` before traversing or mutating sub-meshes. The `object` property is `null` until the GLTF/GLB asset finishes loading.
95
+ :::
96
+
@@ -0,0 +1,121 @@
1
+ # Name
2
+
3
+ Human-readable name for an entity. Shown in the editor hierarchy panel and preserved across save/reload.
4
+
5
+ ## Editor inspector
6
+
7
+ ![Name inspector](/images/components/Name.png)
8
+
9
+ ## Properties
10
+
11
+ | Property | Type | Description |
12
+ | --- | --- | --- |
13
+ | `value` | `string` | Display name for the entity. Shown in the editor hierarchy. |
14
+
15
+ ## API reference
16
+
17
+ - Class: [`Name`](../../api/components/classes/Name.md)
18
+ - Source: [`core/components/Name.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Name.ts)
19
+
20
+ ## Scripting examples
21
+
22
+ ::: tip Component access patterns
23
+ 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:
24
+
25
+ ```typescript
26
+ // Component on the entity this script is on
27
+ const name = this.getComponent(Name);
28
+
29
+ // Component on another entity, found by its scene name
30
+ const other = this.world.getEntityByName("Player");
31
+ if (other) {
32
+ const name = this.world.getComponent(other.entityId, Name);
33
+ }
34
+ ```
35
+ :::
36
+
37
+ ### Drive the display name from the inspector
38
+
39
+ Rename the entity at runtime from an inspector string field. Useful for dynamic labels or debug output.
40
+
41
+ ```typescript
42
+ import { Behaviour, Name } from "@relu-interactives/spatial-ecs";
43
+ import type { StringInput } from "@relu-interactives/spatial-ecs";
44
+
45
+ export default class EntityRenamer extends Behaviour {
46
+ data = {
47
+ displayName: "My Entity" as StringInput,
48
+ };
49
+
50
+ protected onUpdate() {
51
+ const name = this.getComponent(Name);
52
+ if (name && name.value !== this.data.displayName) {
53
+ name.value = this.data.displayName;
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### Find another entity by name
60
+
61
+ Query all `Name` components to locate a sibling entity and read its position.
62
+
63
+ ```typescript
64
+ import { Behaviour, Name, TransformComponent } from "@relu-interactives/spatial-ecs";
65
+ import type { StringInput } from "@relu-interactives/spatial-ecs";
66
+
67
+ export default class LookAtTarget extends Behaviour {
68
+ data = {
69
+ targetName: "Target" as StringInput,
70
+ };
71
+
72
+ protected onUpdate() {
73
+ let targetTransform: TransformComponent | null = null;
74
+
75
+ for (const [id, nameComp] of this.world.query([Name])) {
76
+ if (nameComp.value === this.data.targetName) {
77
+ targetTransform = this.world.getComponent(id, TransformComponent);
78
+ break;
79
+ }
80
+ }
81
+
82
+ if (!targetTransform) return;
83
+
84
+ // Rotate to face the target on the Y axis
85
+ const dx = targetTransform.position.x - this.transform.position.x;
86
+ const dz = targetTransform.position.z - this.transform.position.z;
87
+ this.transform.rotation.y = Math.atan2(dx, dz);
88
+ }
89
+ }
90
+ ```
91
+
92
+ ### Via `EntityInput` in the inspector
93
+
94
+ Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
95
+
96
+ ```typescript
97
+ import {
98
+ Behaviour,
99
+ Name,
100
+ type EntityInput,
101
+ type WorldEntityView,
102
+ } from "@relu-interactives/spatial-ecs";
103
+
104
+ export default class Example extends Behaviour {
105
+ data = {
106
+ targetEntity: { type: "entity", value: null } as unknown as EntityInput,
107
+ };
108
+
109
+ protected onUpdate() {
110
+ const entity = this.data.targetEntity.value as WorldEntityView | null;
111
+ if (!entity) return;
112
+
113
+ const nameComp = this.world.getComponent(
114
+ entity.entityId,
115
+ Name,
116
+ ) as Name | null;
117
+ if (!nameComp) return;
118
+ // Use the component on the picked entity.
119
+ }
120
+ }
121
+ ```