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.
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.gois the GameObject it's attached to, andthis.sceneis its scene.- Use
Component<ArcadeObject>to typethis.goas a specific GameObject class.
Examples: the Platformer's PlayerComponent and CollectableComponent, and the Showcase's components demo.
Attaching components
In code:
const spin = obj.AddComponent(SpinComponent);
spin.speed = 180;In a prefab, using the name without Component, starting lowercase:
{
"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.
| Method | When 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
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:
bare.component.CallMethodOnComponentsOfObject('OnHit', enemy, damage);Describe the method once so TypeScript knows about it:
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:
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
| Component | Description |
|---|---|
AnimationComponent | Plays frame animations. See Animations. |
ParticleComponent | Attaches a particle emitter to the object. See Particles. |
TextComponent | Renders text. See Text & UI. |
CollisionEventComponent | Sends 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:
{
"name": "exitDoor",
"baseClass": "ArcadeObject",
"sensor": true,
"components": {
"collisionEvent": {
"object": "player",
"event": "levelExit",
"once": true
}
}
}| Field | Description |
|---|---|
object | Name of the object that triggers it. Leave empty to trigger on any collision. |
event | Event sent with bare.SendEvent, with { collidingObject, trigger }. |
once | Fire only once, then remove the component. |
removeObject | With once, remove the whole object instead. |
Then listen for it anywhere:
bare.events.on('levelExit', () => bare.level.Load('level2'));It needs physics. The Fire button in the Chrome extension sends the event by hand.