If I want to add my own code I create a script and attach it to a script component. Is it possible to create a component like the built-in components and use it in the editor or even outside the editor (i.e. in a local dev environment) or is the script component the preferred way for adding custom code?
Hi @Trigger ,
You are able to add your own custom component to the engine, but it will not show up currently in editor.
There is a feature request about it here:
opened 09:10PM - 06 Sep 21 UTC
area: editor interface
feature request
It would be nice to use the same Playcanvas Components mechanism to build game-s… pecific logic.
For example, one script to register the system, i.e. to spawn players:
```
var ComponentRegistrator = pc.createScript('componentRegistrator');
ComponentRegistrator.prototype.initialize = function() {
var app = this.app;
app.systems.add(new SpawnComponentSystem(app));
console.log('registrator');
};
ComponentRegistrator.prototype.update = function(dt) {
};
```
And the system itself:
```
class SpawnComponent extends pc.Component {
constructor(system, entity) {
super(system, entity);
this._spawnPoint = undefined;
}
}
function defineSpawnProperty(name) {
var _name = '_' + name;
Object.defineProperty(SpawnComponent.prototype, name, {
get: function () {
return this[_name];
},
set: function (value) {
if (this[_name] !== value) {
this[_name] = value;
this.fire('spawn');
}
}
});
}
defineSpawnProperty('spawnPoint');
class SpawnComponentData {
constructor() {
this.enabled = true;
}
}
const _spawnSchema = ['enabled'];
class SpawnComponentSystem extends pc.ComponentSystem {
constructor(app) {
super(app);
this.id = 'spawn';
this.ComponentType = SpawnComponent;
this.DataType = SpawnComponentData;
this.schema = _spawnSchema;
}
initializeComponentData(component, data, properties) {
if (data.enabled !== undefined) component.enabled = data.enabled;
if (data.spawnPoint !== undefined) component.spawnPoint = data.spawnPoint;
super.initializeComponentData(component, data, properties);
}
cloneComponent(entity, clone) {
var layoutChild = entity.layoutchild;
return this.addComponent(clone, {
enabled: layoutChild.enabled,
spawnPoint: layoutChild.spawnPoint,
});
}
set(x, y, z) {
this._spawnPoint = new pc.Vec3(x, y, z);
}
spawn() {
var components = this.store;
for (var id in components) {
if (components[id].entity.spawn) {
components[id].entity.rigidbody.teleport(this._spawnPoint);
}
}
}
}
pc.Component._buildAccessors(SpawnComponent.prototype, _spawnSchema);
```
And the usage, something like this:
```
player.addComponent("spawn", {
spawnPoint: new pc.Vec3(0, 0, 0)
});
// ... on a state machine transition
console.log('onStartGame');
app.systems.spawn.set(0, 0, 0);
app.systems.spawn.spawn();
```
Everything works all right, but the component layout is obviously missing from the Editor.
Is it possible:
1) To add custom components to the editor, ideally with some basic layout, like enable/disable, numeric and others PODs.
It seems that Editor works with the same CustomEngine syntax as Launcher (use_local_engine=http://localhost:51000/playcanvas.js&debug=true), but it won't show a test component from the custom build.
2) Support auto registration of the custom components, to remove the hack with the ComponentRegistrator.
Thanks for that. Any documentation on how to create a custom component or maybe a pointer to the source code where the built-in components are registered?
I haven’t done it before myself, but I think the entry point is the add() method of the ComponentSystemRegistry class:
Also the feature request I posted above contains example code on how to create a custom component. It may be a bit old/outdated but it may still help.
1 Like