通过程序创建实体
通常,你会通过 PlayCanvas 编辑器创建实体,并组合组件与脚本来制作游戏的各个部分。不过,某些情况下在脚本中创建实体更方便,本教程将介绍具体方法。
创建实体
var entity = new pc.Entity(); // Create an Entity
// Add it to the Entity hierarchy
this.app.root.addChild(entity);
首先创建实体。这很简单,但务必将实体添加到主实体层级中,因为只有位于层级中的实体才会更新其变换、组件和脚本。在脚本中,可以通过传入的 Application 对象访问实体层级的根节点。按照惯例,该对象通常命名为 app,根节点可通过 this.app.root 访问。
添加组件
// Create a new Entity
var entity = new pc.Entity();
// Add a new Camera Component with default values
entity.addComponent("camera");
// Add a new Model Component and add it to the Entity.
entity.addComponent("render", {
type: 'box',
});
// Add it to the Entity hierarchy
this.app.root.addChild(entity);
单独的实体几乎没有功能,因此需要添加组件来赋予其行为。使用实体的 addComponent 方法,可以创建并添加新组件。
不同组件类型支持在 data 对象中传入不同属性。可用属性详见组件文档。可以省略 data 参数,此时使用默认值。
移除组件
var entity = new pc.Entity();
// Attach Camera Component with default values
entity.addComponent("camera");
// Delete the Camera Component
entity.removeComponent("camera");
调用实体的 removeComponent 方法,可以单独删除某个组件。
删除实体
// Create a new Entity
var entity = new pc.Entity();
// Create a new Camera Component with default values
entity.addComponent("camera");
// Create a new Model Component and add it to the Entity.
entity.addComponent("render", {
type: 'box',
});
// Add it to the Entity hierarchy
this.app.root.addChild(entity);
// Delete the Entity and remove it from the hierarchy
entity.destroy();
不再需要实体时,调用其 destroy 方法。这会删除所有组件,并将实体从层级中移除,同时以相同方式删除全部子实体。
实际示例
- ESM
- 传统脚本
import { Script, Entity, math } from 'playcanvas';
export class EntityCreator extends Script {
static scriptName = "entityCreator";
/**
* @attribute
* @title Material
* @type {Asset}
* @resource material
*/
material = null;
/**
* @attribute
* @title Box Dimensions
* @type {number}
*/
boxDimensions = 10;
/**
* @attribute
* @title Lifetime
* @type {number}
*/
lifetime = 5;
/**
* @attribute
* @title Max Cubes
* @type {number}
*/
maxCubes = 10;
// initialize code called once per entity
initialize() {
this.entities = [];
}
// update code called every frame
update(dt) {
// Spawn new cubes if there are less than maxCubes
while (this.entities.length < this.maxCubes) {
this.spawnCube();
}
// Loop through Entities and delete them when their time is up
for (let i = 0; i < this.entities.length; i++) {
this.entities[i].timer -= dt;
if (this.entities[i].timer < 0) {
// entity.destroy() deletes all components and removes Entity from the hierarchy
this.entities[i].entity.destroy();
// Remove from the local list
this.entities.splice(i, 1);
}
}
}
spawnCube() {
const entity = new Entity();
// Add a new Model Component and add it to the Entity.
entity.addComponent("render", {
type: 'box'
});
// set material
entity.render.material = this.material.resource;
// Move to a random position
entity.setLocalPosition(
math.random(-this.boxDimensions, this.boxDimensions),
math.random(-this.boxDimensions, this.boxDimensions),
math.random(-this.boxDimensions, this.boxDimensions)
);
// Add to the Hierarchy
this.app.root.addChild(entity);
// Store in a list for some random duration before deleting
this.entities.push({
entity: entity,
timer: math.random(0, this.lifetime)
});
}
}
var EntityCreator = pc.createScript('entityCreator');
EntityCreator.attributes.add('material', {
type: 'asset',
assetType: 'material'
});
EntityCreator.attributes.add('boxDimensions', {
type: 'number',
default: 10
});
EntityCreator.attributes.add('lifetime', {
type: 'number',
default: 5
});
EntityCreator.attributes.add('maxCubes', {
type: 'number',
default: 10
});
// initialize code called once per entity
EntityCreator.prototype.initialize = function() {
this.entities = [];
};
// update code called every frame
EntityCreator.prototype.update = function(dt) {
// Spawn new cubes if there are less than maxCubes
while (this.entities.length < this.maxCubes) {
this.spawnCube();
}
// Loop through Entities and delete them when their time is up
for (i = 0; i < this.entities.length; i++) {
this.entities[i].timer -= dt;
if (this.entities[i].timer < 0) {
// entity.destroy() deletes all components and removes Entity from the hierarchy
this.entities[i].entity.destroy();
// Remove from the local list
this.entities.splice(i, 1);
}
}
};
EntityCreator.prototype.spawnCube = function () {
var entity = new pc.Entity();
// Add a new Model Component and add it to the Entity.
entity.addComponent("render", {
type: 'box'
});
// set material
entity.render.material = this.material.resource;
// Move to a random position
entity.setLocalPosition(
pc.math.random(-this.boxDimensions, this.boxDimensions),
pc.math.random(-this.boxDimensions, this.boxDimensions),
pc.math.random(-this.boxDimensions, this.boxDimensions)
);
// Add to the Hierarchy
this.app.root.addChild(entity);
// Store in a list for some random duration before deleting
this.entities.push({
entity: entity,
timer: pc.math.random(0, this.lifetime)
});
};
下面是页面顶部演示使用的完整实体脚本。它不断创建并销毁带有 Model 组件的新实体。