Skip to content

Parent

Records the parent entity id for hierarchical scene graphs. null means the entity is at the world root. The ObjectManagementSystem reconciles scene-graph parenting from this component each frame.

Properties

PropertyTypeDescription
valueEntityId | nullParent entity id, or null for root-level entities.

API reference

Scripting examples

Component access patterns

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:

typescript
// Component on the entity this script is on
const parentId = this.getComponent(ParentId);

// Component on another entity, found by its scene name
const other = this.world.getEntityByName("Prop");
if (other) {
  const parentId = this.world.getComponent(other.entityId, ParentId);
}

Detach an entity to the world root on key press

Set ParentId.value to null to reparent the entity to the scene root. The ObjectManagementSystem reconciles the actual scene-graph hierarchy every frame.

typescript
import { Behaviour, ParentId, KeyboardKeys } from "@relu-interactives/spatial-ecs";

export default class DetachOnKey extends Behaviour {
  protected onUpdate() {
    if (this.world.getKeyDown(KeyboardKeys.D)) {
      const parent = this.getComponent(ParentId);
      if (parent) parent.value = null;
    }
  }
}

Reparent to a specific entity

Assign a new parent entity ID to move the entity (and its children) under a different part of the hierarchy at runtime.

typescript
import { Behaviour, ParentId, Name, KeyboardKeys } from "@relu-interactives/spatial-ecs";
import type { StringInput } from "@relu-interactives/spatial-ecs";

export default class Reparenter extends Behaviour {
  data = {
    newParentName: "Holder" as StringInput,
  };

  protected onUpdate() {
    if (!this.world.getKeyDown(KeyboardKeys.R)) return;

 // Find the target parent entity by name
    const parentEntity = this.world.getEntityByName(this.data.newParentName);
    const parent = this.getComponent(ParentId);
    if (parent) parent.value = id;
  }
}

Via EntityInput in the inspector

Alternatively, pick an entity from the inspector using an EntityInput field and then read the component off that entity via world.getComponent:

typescript
import {
  Behaviour,
  ParentId,
  type EntityInput,
  type WorldEntityView,
} from "@relu-interactives/spatial-ecs";

export default class Example extends Behaviour {
  data = {
    targetEntity: { type: "entity", value: null } as unknown as EntityInput,
  };

  protected onUpdate() {
    const entity = this.data.targetEntity.value as WorldEntityView | null;
    if (!entity) return;

    const parentId = this.world.getComponent(
      entity.entityId,
      ParentId,
    ) as ParentId | null;
    if (!parentId) return;
    // Use the component on the picked entity.
  }
}

ObjectManagementSystem

Do not call THREE.Object3D.add / remove directly to reparent. Write to ParentId.value instead — the ObjectManagementSystem reads this every frame and reconciles the scene graph. This keeps the ECS hierarchy state consistent with the three.js scene graph.