Skip to main content

Entity Component System

Everything in a PlayCanvas scene is an entity: the camera that views it, the lights that light it, every model, sound and piece of UI, and the objects of your game. On its own, an entity is a named point in space, with a position, a rotation and a scale, and a place in a hierarchy of other entities. Components give it abilities. A camera component makes it a camera, a render component draws a mesh at its position, a rigidbody component hands it to the physics engine, and a script component runs your own code on it. For each type of component, the application has one system that runs every component of that type.

A tree of entities under app.root, camera, light and car with the car's body and wheel below it, with each entity's components in a row beside it. Each component sits in the column of its system in app.systems, so the render column holds the render components of the car, its body and its wheel

This pattern is called an Entity Component System, or ECS. You use it however you build: the Editor, React and Web Components all create the same entities and components as code written against the engine. Each page in this section explains a concept once and then shows how to apply it on each of those surfaces.

Entities​

An entity is an object of the Entity class. It has a name and tags, which you can use to find it, and an enabled state, which switches it on and off together with everything below it. Its position, rotation and scale are relative to its parent, so moving an entity moves its children with it.

The entities of a scene form a tree whose root is app.root. An entity joins the scene when you add it to that tree: until then, it is not drawn and its scripts do not run. See Hierarchy and Transforms.

Components​

A component adds one ability to its entity, and holds the settings of that ability as properties, such as entity.light.color or entity.camera.fov. An entity has at most one component of each type. To give an object two lights, give it two child entities with a light each.

The engine has around twenty types of component, covering cameras, lights, rendering, sound, physics, animation, particles and user interface. You do not write new types of component for your own behavior. Instead, you write scripts, and the script component runs any number of them on its entity.

Systems​

Each type of component has a system, a ComponentSystem that creates, updates and destroys every component of that type and holds the settings they share. You rarely need a system directly. One exception is shared settings: app.systems.rigidbody.gravity is the gravity that pulls on every rigid body, for example.

An application runs only the systems registered with it. pc.AppBase starts with none, so you list the ones you use and a bundler can leave the rest out of your build. pc.Application registers every built-in system, and so do the Editor, React and Web Components. See Component Systems.

note

If you come from Unity, entities are game objects and components are components: see Migrating from Unity. If you come from a data-oriented ECS, such as Unity's DOTS or Bevy, note that PlayCanvas entities are objects in a scene graph rather than plain identifiers, and that components keep both their data and their behavior.

One Scene, Four Ways​

Here is a scene with three entities: a camera, a light and an orange box. The camera is raised and tilted down to look at the box, which is turned to show three of its sides.

An orange box, turned to show its top and two of its sides, lit from the upper left against a dark background

With an application set up as in Using the Engine Standalone, and the render, camera and light component systems registered:

const camera = new pc.Entity('camera');
camera.addComponent('camera', {
clearColor: new pc.Color(0.11, 0.12, 0.17)
});
camera.setPosition(0, 1.1, 3.2);
camera.setEulerAngles(-20, 0, 0);
app.root.addChild(camera);

const light = new pc.Entity('light');
light.addComponent('light');
light.setEulerAngles(45, -30, 0);
app.root.addChild(light);

const material = new pc.StandardMaterial();
material.diffuse = new pc.Color(1, 0.55, 0.2);
material.update();

const box = new pc.Entity('box');
box.addComponent('render', { type: 'box', material: material });
box.setEulerAngles(0, 35, 0);
app.root.addChild(box);

Whichever way you build, the result is the same tree of entities under app.root, each with one component. The Editor, React and Web Components create these engine objects for you, and each gives you a way to reach them when you need to:

EngineEditorReactWeb Components
An entitynew pc.Entity('box')An item in the Hierarchy<Entity name="box"><pc-entity name="box">
Its place in the treeparent.addChild(box)Drag it onto its parent in the HierarchyNest it inside its parent's <Entity>Nest it inside its parent's <pc-entity>
A componentbox.addComponent('render', { type: 'box' })Add Component in the Inspector<Render type="box" /> inside the <Entity><pc-render type="box"> inside the <pc-entity>
A propertybox.render.castShadows = falseA field in the InspectorcastShadows={false}cast-shadows="false"
Your own behaviorbox.addComponent('script').create(Spin)A script in a Script component<Script script={Spin} /><pc-script-instance name="spin"> in a <pc-script>
The engine entity, from your codeboxthis.entity in a script on itThe ref of the <Entity>The entity property of the <pc-entity>

In This Section​

  • Entities - Creating, naming, enabling, destroying and copying entities.
  • Components - The built-in components, and adding, changing, disabling and removing them.
  • Hierarchy and Transforms - The coordinate system, local and world space, moving and rotating, and parenting.
  • Finding Entities - Looking entities up by name, path, tag, component or script.

See Also​