Skip to main content

Prefab

If you keep writing scenes on the bootstrapper, the bootstrapper will become too big.

You can use prefab to separate scene builds. It's like separating components in React development.

Make a prefab

We going to make a camera prefab that tracks a specific object.

./src/asset/prefab/CameraPrefab.ts
import { 
Camera,
GameObject,
GameObjectBuilder,
Prefab,
PrefabRef,
TrackCameraController
} from "the-world-engine";

export class CameraPrefab extends Prefab {
private _trackObject = new PrefabRef<GameObject>();
private _camera = new PrefabRef<Camera>();

//If you add a value inside the prefab from the outside, you can create the with method
public withTrackObject(trackObject: PrefabRef<GameObject>): this {
this._trackObject = trackObject;
return this;
}

//When receiving the value inside the prefab from the outside, it is possible by creating the get method
public getCamera(componentRef: PrefabRef<Camera>): this {
this._camera = componentRef;
return this;
}

public override make(): GameObjectBuilder {
return this.gameObjectBuilder
.withComponent(Camera)
.withComponent(TrackCameraController, c => {
c.smoothTrack = true;
if (this._trackObject.ref) c.setTrackTarget(this._trackObject.ref);
})
.getComponent(Camera, this._camera)
;
}
}
tip

It is recommended that the method of exporting something from a prefab starts with the name "with" And it is recommended that the method of getting something from the prefab starts with the name "get".

tip

You can see that the implementation of the "get" method and the "with" method is the same, because it works as a call by reference.

Eventually, the behavior is determined by whether the reference is read or written inside the prefab.

For this code, this._camera will be exposed as "get" method because the value was writed at .getComponent(Camera, this._camera)

And this._trackObject will be exposed as "with" method because the value was readed at if (this._trackObject.ref) c.setTrackTarget(this._trackObject.ref);

Add a prefab to the builder

Now we can create camera from CameraPrefab.

./src/asset/Bootstrapper.ts
import { /*...*/ } from "the-world-engine";
import { CameraPrefab } from "./prefab/CameraPrefab";

export class Bootstrapper extends BaseBootstrapper {
public run(): SceneBuilder {
const instantiater = this.instantiater;

const trackObject = new PrefabRef<GameObject>();
const camera = new PrefabRef<Camera>();

return this.sceneBuilder
.withChild(instantiater.buildPrefab("camera", CameraPrefab) // build prefab!
.withTrackObject(trackObject)
.getCamera(camera)
.make())

.withChild(instantiater.buildGameObject("player")
.withComponent(CssSpriteRenderer)
.withComponent(PlayerGridMovementController)
.getGameObject(trackObject))
;
}
}