组件系统与执行顺序
组件是神岛引擎中最基础的功能单元,理解组件的工作方式和执行顺序对于开发高质量的游戏至关重要。
组件基础
组件定义
typescript
@apclass("PlayerComponent")
class PlayerComponent extends Component<GameEntity> {
// 组件属性
public speed: number = 5;
private health: number = 100;
// 生命周期方法
onLoad(): void {
console.log("组件加载");
}
start(): void {
console.log("组件开始");
}
update(dt: number): void {
console.log("组件更新");
}
onDestroy(): void {
console.log("组件销毁");
}
}
组件权重
组件的执行顺序由权重(weight)决定,权重值越小,执行优先级越高。
typescript
@apclass("PhysicsComponent")
class PhysicsComponent extends Component<GameEntity> {
onLoad(): void {
// 设置较高优先级(较小的权重值)
this.weight = -2;
}
}
@apclass("AnimationComponent")
class AnimationComponent extends Component<GameEntity> {
onLoad(): void {
// 设置较低优先级(较大的权重值)
this.weight = 1;
}
}
执行顺序详解
1. 生命周期执行顺序
typescript
@apclass("LifecycleComponent")
class LifecycleComponent extends Component<GameEntity> {
onLoad(): void {
// 1. 首先执行,用于初始化组件
console.log("1. onLoad");
}
onEnable(): void {
// 2. 组件启用时执行
console.log("2. onEnable");
}
start(): void {
// 3. 所有组件 onLoad 完成后执行
console.log("3. start");
}
update(dt: number): void {
// 4. 每帧执行,按权重排序
console.log("4. update");
}
lateUpdate(dt: number): void {
// 5. 全部组件刷新后执行,按权重排序
console.log("5. lateUpdate");
}
onDisable(): void {
//6. 组件禁用时执行
console.log("6. onDisable");
}
onDestroy(): void {
// 7. 组件销毁时执行
console.log("7. onDestroy");
}
}
高级用法
1. 动态调整优先级
typescript
@apclass("DynamicComponent")
class DynamicComponent extends Component<GameEntity> {
private needsHighPriority: boolean = false;
update(dt: number): void {
if (this.needsHighPriority && this.weight !== -999) {
// 动态提升优先级
this.weight = -999;
}
}
}
2. 组件组合模式
typescript
@apclass("CompositeSystem")
class CompositeSystem extends Component<GameEntity> {
// 存储子系统组件
private systems: Component[] = [];
protected start(): void {
// 按特定顺序添加子系统
this.systems.push(
this.node.addComponent(PhysicsSystem, { weight: -2 }),
this.node.addComponent(InputSystem, { weight: -1 }),
this.node.addComponent(RenderSystem, { weight: 0 })
);
}
protected onDestroy(): void {
// 按相反顺序销毁子系统
this.systems.reverse().forEach((system) => {
this.node.removeComponent(system.constructor as any);
});
}
}
最佳实践
1. 权重分配建议
typescript
// 物理系统:最高优先级
@apclass("PhysicsSystem")
class PhysicsSystem extends Component<GameEntity> {
onLoad() {
this.weight = -100;
}
}
// 输入系统:次高优先级
@apclass("InputSystem")
class InputSystem extends Component<GameEntity> {
onLoad() {
this.weight = -50;
}
}
// 游戏逻辑:普通优先级
@apclass("GameLogic")
class GameLogic extends Component<GameEntity> {
onLoad() {
this.weight = 0;
}
}
// 渲染系统:较低优先级
@apclass("RenderSystem")
class RenderSystem extends Component<GameEntity> {
onLoad() {
this.weight = 50;
}
}
2. 依赖管理
typescript
@apclass("DependentComponent")
class DependentComponent extends Component<GameEntity> {
start(): void {
// 确保依赖组件已经初始化
const physics = this.node.getComponent(PhysicsSystem);
if (!physics) {
console.error("缺少物理系统组件!");
this.enabled = false;
return;
}
}
}
注意事项
权重设置时机
- 在 onLoad 中设置权重
- 避免频繁修改权重
- 合理规划权重范围
执行顺序依赖
- 不要过度依赖执行顺序
- 使用事件系统处理组件间通信
- 注意避免循环依赖
性能考虑
- 避免过多的高优先级组件
- 合理使用 update,lateUpdate 方法
- 考虑使用事件驱动替代轮询
常见问题
Q: 如何处理组件间的依赖关系?
A: 推荐以下方法:
- 使用权重系统确保正确的刷新顺序
- 在 start 方法中检查依赖
- 使用事件系统进行松耦合通信
Q: 权重值的范围是多少?
A: 权重值是数字类型,推荐范围:
- -100 ~ -50:系统级组件
- -49 ~ 0:核心游戏逻辑
- 1 ~ 50:普通组件
- 51 ~ 100:后处理组件
Q: 如何优化大量组件的性能?
A: 可以通过以下方式优化:
- 合理使用权重系统
- 使用组件池
- 适时禁用不需要的组件
- 避免在 update,lateUpdate 中进行重复计算