Skip to content

Components ​

Components add behavior to GameObjects. They work much like in Unity: you write a class with lifecycle methods and attach it to any object or prefab.

ts
import { Component, InspectorField } from 'bare-engine';

export class SpinComponent extends Component
{
    @InspectorField
    speed = 90;

    OnUpdate(deltaTime: number)
    {
        this.go.rotation += this.speed * deltaTime;
    }
}
  • The class name must end in Component.
  • Put it in src/components/ and export it. Exported components are registered with the engine automatically.
  • this.go is the GameObject it's attached to, and this.scene is its scene.
  • Use Component<ArcadeObject> to type this.go as a specific GameObject class.

Examples: the Platformer's PlayerComponent and CollectableComponent, and the Showcase's components demo.

Attaching components ​

In code:

ts
const spin = obj.AddComponent(SpinComponent);
spin.speed = 180;

In a prefab, using the name without Component, starting lowercase:

json
{
  "name": "fan",
  "texture": "fan",
  "components": {
    "spin": {
      "speed": 180
    }
  }
}

Lifecycle ​

All methods are optional.

An active component attached to an already started object can run OnAwake, OnAdded, and OnStart before AddComponent returns. See Lifecycle & Cleanup for initialization and teardown patterns.

MethodWhen it runs
OnAwake(go)When the component is created.
OnAdded(go)When it's attached to a GameObject in the scene.
OnStart()Once, before its first update.
OnUpdate(dt) / OnFixedUpdate(dt)Every frame / every fixed step.
OnPreRender() / OnRender() / OnPostRender()Around rendering.
OnEnable() / OnDisable()When enabled or disabled.
OnRemoved()When removed, or when its GameObject is removed.
OnCollisionStart(other) / OnCollisionUpdate(other) / OnCollisionEnd(other)With physics.
OnPostLoadLevel() / OnPreSaveLevel()Around level loading and saving.

Finding components ​

ts
obj.GetComponent(SpinComponent);
obj.HasComponent(SpinComponent);
obj.RemoveComponent(SpinComponent);

bare.component.GetAllByType(SpinComponent);   // every SpinComponent in the scene
bare.component.Disable(obj, SpinComponent);
bare.component.Enable(obj, SpinComponent);

Example: the Platformer counts its coins with bare.component.GetAllByType(CollectableComponent).

Calling a method on all components ​

CallMethodOnComponentsOfObject calls a method on every component of an object that has it. This lets components react to things without knowing about each other, for example getting hit:

ts
bare.component.CallMethodOnComponentsOfObject('OnHit', enemy, damage);

Describe the method once so TypeScript knows about it:

ts
declare module 'bare-engine'
{
    interface Component
    {
        OnHit?(damage: number): void;
    }
}

Example: the RPG declares OnHit and OnDie. Its AliveComponent loses health on a hit and calls OnDie on all components, while its HitComponent flashes and knocks the object back.

Inspector fields ​

Fields marked @InspectorField show up in the Chrome extension, where you can edit them live, and can be set from prefabs. More decorators control how they're shown:

ts
import { Component, Inspector, InspectorField } from 'bare-engine';

export class PlayerComponent extends Component
{
    @InspectorField
    @Inspector.Limit(0, Infinity)
    moveSpeed = 500;

    @InspectorField
    @Inspector.Label('Jump force')
    jump = -1600;
}

Inspector decorators are removed in production builds, so they don't add to your game's size. See Inspector Decorators for the full list.

Example: the Platformer's player fields use Limit, Label and Locked.

Built-in components ​

ComponentDescription
AnimationComponentPlays frame animations. See Animations.
ParticleComponentAttaches a particle emitter to the object. See Particles.
TextComponentRenders text. See Text & UI.
CollisionEventComponentSends an event when the object collides with a named object. See below.

CollisionEventComponent ​

Turns a collision into an event, set up entirely in data. Give a trigger prefab the component:

json
{
  "name": "exitDoor",
  "baseClass": "ArcadeObject",
  "sensor": true,
  "components": {
    "collisionEvent": {
      "object": "player",
      "event": "levelExit",
      "once": true
    }
  }
}
FieldDescription
objectName of the object that triggers it. Leave empty to trigger on any collision.
eventEvent sent with bare.SendEvent, with { collidingObject, trigger }.
onceFire only once, then remove the component.
removeObjectWith once, remove the whole object instead.

Then listen for it anywhere:

ts
bare.events.on('levelExit', () => bare.level.Load('level2'));

It needs physics. The Fire button in the Chrome extension sends the event by hand.

Bare Engine is open source under the MIT license.