跳到主要内容

组件

组件为实体赋予一种能力。带相机组件的实体渲染场景,带灯光组件的实体提供光照,带刚体和碰撞组件的实体则会下落、反弹和碰撞。组件通过属性保存功能设置,每个实体同类型组件最多只能有一个。

内置组件​

各名称链接到相应开发方式的组件参考。引擎名称既是传给 addComponent() 的名称,也是实体上保存组件的属性,例如 entity.camera、entity.rigidbody。

EngineEditorReactWeb Components功能
animAnim<Anim><pc-anim>播放动画,通过动画状态图混合
animationAnimation--旧版动画片段播放,请改用 Anim
audiolistenerAudio Listener-<pc-audio-listener>声音的监听位置
buttonButton-<pc-button>让 UI 元素响应悬停和点击
cameraCamera<Camera><pc-camera>从实体视点渲染场景
collisionCollision<Collision><pc-collision>为刚体或触发体积提供形状
elementElement<Element><pc-element>用户界面中的矩形元素:图像、文本或分组
gsplatGSplat<GSplat><pc-gsplat>渲染 3D 高斯泼溅
jointJoint-<pc-joint>Alpha 阶段:通过关节连接刚体
layoutchildLayout Child-<pc-layout-child>覆盖布局组对子元素尺寸的计算方式
layoutgroupLayout Group-<pc-layout-group>按行、列或网格排列子 UI 元素
lightLight<Light><pc-light>方向、点或聚光光源
modelModel--旧版模型资源渲染,请改用 Render
particlesystemParticle System-<pc-particle-system>发射和绘制粒子
renderRender<Render><pc-render>绘制基本几何体或渲染资源中的网格
rigidbodyRigid Body<RigidBody><pc-rigid-body>将实体交给物理模拟
screenScreen<Screen><pc-screen>用户界面的根节点
scriptScript<Script><pc-script>在实体上运行自定义脚本
scrollbarScrollbar-<pc-scrollbar>滚动视图的滚动条
scrollviewScroll View-<pc-scroll-view>用户界面中的可滚动区域
soundSound-<pc-sound>播放声音,可选择在 3D 空间中定位
spriteSprite<Sprite><pc-sprite>绘制 2D 精灵或精灵动画

React 和 Web Components 封装了大多数应用常用的组件。短横线表示没有封装,但仍可通过代码向引擎实体添加该组件,见下文。

添加组件​

为实体添加组件时,可以指定初始设置;未指定的设置使用默认值。

const lamp = new pc.Entity('lamp');
lamp.addComponent('light', {
type: 'omni',
color: new pc.Color(1, 0.8, 0.6),
range: 10
});
app.root.addChild(lamp);

addComponent() 返回新组件,也可以通过 lamp.light 访问它。如果实体已经有灯光,方法返回 null,调试版引擎会记录警告。如果应用尚未注册灯光组件系统,也会返回 null,参见组件系统。

没有封装的组件​

在 React 和 Web Components 中,可通过代码向引擎实体添加没有封装的组件。

编写一个组件,在挂载时为所在实体添加引擎组件,在卸载时移除。useParent() 返回外层 <Entity> 对应的引擎实体:

import { useEffect } from 'react';
import { Entity } from '@playcanvas/react';
import { useParent } from '@playcanvas/react/hooks';

function AudioListener() {
const entity = useParent();

useEffect(() => {
entity.addComponent('audiolistener');
return () => {
// unmounting the whole entity has already destroyed its components
if (entity.audiolistener) entity.removeComponent('audiolistener');
};
}, [entity]);

return null;
}

<Entity name="camera">
<AudioListener />
</Entity>

读取和修改属性​

组件设置是可以随时读取和修改的属性,修改会立即生效。修改向量或颜色属性时,应为属性赋一个新值。

lamp.light.intensity = 2;
lamp.light.color = new pc.Color(1, 0, 0);

console.log(lamp.light.range); // 10

禁用与移除组件​

每个组件都有 enabled 属性。禁用后组件停止工作,例如渲染组件不再绘制,脚本组件停止运行脚本,但会保留设置,供重新启用。移除组件则会删除组件及其设置。禁用整个实体会同时禁用所有组件,参见启用与禁用。

box.render.enabled = false; // stop drawing the box
box.render.enabled = true; // draw it again

box.removeComponent('render');

添加自定义行为​

内置组件提供引擎支持的能力。其他功能,从打开门到游戏规则,都应通过脚本实现,再使用脚本组件附加到实体。一个脚本组件可运行任意数量的脚本,各脚本通过 this.entity 访问实体。下面的脚本让实体绕竖直轴旋转:

import { Script } from 'playcanvas';

export class Spin extends Script {
static scriptName = 'spin';

/**
* How fast to spin, in degrees per second.
*
* @attribute
*/
speed = 90;

update(dt) {
this.entity.rotate(0, this.speed * dt, 0);
}
}
box.addComponent('script');
box.script.create(Spin, { properties: { speed: 45 } });

组件系统​

每种组件类型在应用中都有一个组件系统,负责创建该类型的所有组件、逐帧更新及销毁。系统位于 app.systems,名称与组件相同;部分系统还保存所有该类型组件共享的设置:

// the gravity that pulls on every rigid body
app.systems.rigidbody.gravity = new pc.Vec3(0, -1.62, 0);

应用只能添加已注册系统所对应的组件。pc.Application 注册全部内置系统,Editor、React 和 Web Components 也是如此。pc.AppBase 仅注册明确列出的系统,让打包工具可以排除其余部分:

const options = new pc.AppOptions();
options.graphicsDevice = device;
options.componentSystems = [
pc.RenderComponentSystem,
pc.CameraComponentSystem,
pc.LightComponentSystem,
pc.ScriptComponentSystem
];

const app = new pc.AppBase(canvas);
app.init(options);

其余配置见独立使用引擎。

另请参阅​