生命周期
实体的生命周期包括创建、运行和销毁三个阶段。本节介绍如何正确管理实体的生命周期。
// 销毁实体player.destroy();
// 检查实体是否已销毁if (player.isDestroyed) { console.log("实体已被销毁");}销毁实体时会:
- 移除所有组件(触发
onRemovedFromEntity回调) - 从查询系统中移除
- 从场景实体列表中移除
- 清理所有引用追踪
// 常见模式:生命值耗尽时销毁const health = enemy.getComponent(Health);if (health && health.current <= 0) { enemy.destroy();}销毁操作是幂等的,多次调用不会出错:
player.destroy();player.destroy(); // 安全,不会报错默认情况下,实体在场景切换时会被销毁。使用持久化可以让实体跨场景存活。
// 方式一:链式调用const player = scene.createEntity('Player') .setPersistent() .createComponent(PlayerComponent);
// 方式二:单独设置player.setPersistent();
// 检查是否持久化if (player.isPersistent) { console.log("这是持久化实体");}// 恢复为场景本地实体player.setSceneLocal();生命周期策略
Section titled “生命周期策略”实体有两种生命周期策略:
| 策略 | 说明 |
|---|---|
SceneLocal | 默认,随场景销毁 |
Persistent | 跨场景保留 |
import { EEntityLifecyclePolicy } from '@esengine/ecs-framework';
// 获取当前策略const policy = entity.lifecyclePolicy;
if (policy === EEntityLifecyclePolicy.Persistent) { // 持久化实体}持久化实体适用于:
- 玩家角色
- 全局管理器
- UI 实体
- 需要跨场景保留的游戏状态
// 玩家角色const player = scene.createEntity('Player') .setPersistent();
// 游戏管理器const gameManager = scene.createEntity('GameManager') .setPersistent() .createComponent(GameStateComponent);
// 分数管理const scoreManager = scene.createEntity('ScoreManager') .setPersistent() .createComponent(ScoreComponent);场景切换时的行为
Section titled “场景切换时的行为”// 场景管理器切换场景sceneManager.loadScene('Level2');
// 切换时:// 1. SceneLocal 实体被销毁// 2. Persistent 实体被迁移到新场景// 3. 新场景的实体被创建实体引用清理
Section titled “实体引用清理”框架提供了引用追踪系统,在实体销毁时自动清理引用:
// 引用追踪会在实体销毁时清理指向该实体的所有引用scene.referenceTracker?.clearReferencesTo(entity.id);配合 @entityRef 装饰器使用可以自动处理:
class FollowComponent extends Component { @entityRef() targetId: number | null = null;}
// 当 target 被销毁时,targetId 会自动设为 null详见 组件引用。
1. 及时销毁不需要的实体
Section titled “1. 及时销毁不需要的实体”// 子弹飞出屏幕后销毁if (position.x < 0 || position.x > screenWidth) { bullet.destroy();}2. 使用对象池代替频繁创建销毁
Section titled “2. 使用对象池代替频繁创建销毁”class BulletPool { private pool: Entity[] = [];
acquire(scene: Scene): Entity { if (this.pool.length > 0) { const bullet = this.pool.pop()!; bullet.enabled = true; return bullet; } return scene.createEntity('Bullet'); }
release(bullet: Entity) { bullet.enabled = false; this.pool.push(bullet); }}3. 谨慎使用持久化
Section titled “3. 谨慎使用持久化”只对真正需要跨场景的实体使用持久化,过多的持久化实体会增加内存占用。
4. 销毁前清理引用
Section titled “4. 销毁前清理引用”// 销毁前通知相关系统const aiSystem = scene.getSystem(AISystem);aiSystem?.clearTarget(enemy.id);
enemy.destroy();生命周期事件
Section titled “生命周期事件”可以监听实体销毁事件:
// 方式一:通过事件系统scene.eventSystem.on('entity:destroyed', (data) => { console.log(`实体 ${data.entityName} 已销毁`);});
// 方式二:在组件中监听class MyComponent extends Component { onRemovedFromEntity() { console.log('组件被移除,实体可能正在销毁'); // 清理资源 }}// 获取实体状态const debugInfo = entity.getDebugInfo();console.log({ destroyed: debugInfo.destroyed, enabled: debugInfo.enabled, active: debugInfo.active});