Feature/ecs behavior tree (#188)
* feat(behavior-tree): 完全 ECS 化的行为树系统 * feat(editor-app): 添加行为树可视化编辑器 * chore: 移除 Cocos Creator 扩展目录 * feat(editor-app): 行为树编辑器功能增强 * fix(editor-app): 修复 TypeScript 类型错误 * feat(editor-app): 使用 FlexLayout 重构面板系统并优化资产浏览器 * feat(editor-app): 改进编辑器UI样式并修复行为树执行顺序 * feat(behavior-tree,editor-app): 添加装饰器系统并优化编辑器性能 * feat(behavior-tree,editor-app): 添加属性绑定系统 * feat(editor-app,behavior-tree): 优化编辑器UI并改进行为树功能 * feat(editor-app,behavior-tree): 添加全局黑板系统并增强资产浏览器功能 * feat(behavior-tree,editor-app): 添加运行时资产导出系统 * feat(behavior-tree,editor-app): 添加SubTree系统和资产选择器 * feat(behavior-tree,editor-app): 优化系统架构并改进编辑器文件管理 * fix(behavior-tree,editor-app): 修复SubTree节点错误显示空节点警告 * fix(editor-app): 修复局部黑板类型定义文件扩展名错误
This commit is contained in:
179
packages/behavior-tree/src/BehaviorTreeStarter.ts
Normal file
179
packages/behavior-tree/src/BehaviorTreeStarter.ts
Normal file
@@ -0,0 +1,179 @@
|
||||
import { Entity } from '@esengine/ecs-framework';
|
||||
import { BehaviorTreeNode } from './Components/BehaviorTreeNode';
|
||||
import { ActiveNode } from './Components/ActiveNode';
|
||||
import { TaskStatus } from './Types/TaskStatus';
|
||||
|
||||
/**
|
||||
* 行为树启动/停止辅助类
|
||||
*
|
||||
* 提供便捷方法来启动、停止和暂停行为树
|
||||
*/
|
||||
export class BehaviorTreeStarter {
|
||||
/**
|
||||
* 启动行为树
|
||||
*
|
||||
* 给根节点添加 ActiveNode 组件,使行为树开始执行
|
||||
*
|
||||
* @param rootEntity 行为树根节点实体
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const aiRoot = scene.createEntity('aiRoot');
|
||||
* // ... 构建行为树结构
|
||||
* BehaviorTreeStarter.start(aiRoot);
|
||||
* ```
|
||||
*/
|
||||
static start(rootEntity: Entity): void {
|
||||
if (!rootEntity.hasComponent(BehaviorTreeNode)) {
|
||||
throw new Error('Entity must have BehaviorTreeNode component');
|
||||
}
|
||||
|
||||
if (!rootEntity.hasComponent(ActiveNode)) {
|
||||
rootEntity.addComponent(new ActiveNode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止行为树
|
||||
*
|
||||
* 移除所有节点的 ActiveNode 组件,停止执行
|
||||
*
|
||||
* @param rootEntity 行为树根节点实体
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* BehaviorTreeStarter.stop(aiRoot);
|
||||
* ```
|
||||
*/
|
||||
static stop(rootEntity: Entity): void {
|
||||
this.stopRecursive(rootEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归停止所有子节点
|
||||
*/
|
||||
private static stopRecursive(entity: Entity): void {
|
||||
// 移除活跃标记
|
||||
if (entity.hasComponent(ActiveNode)) {
|
||||
entity.removeComponentByType(ActiveNode);
|
||||
}
|
||||
|
||||
// 重置节点状态
|
||||
const node = entity.getComponent(BehaviorTreeNode);
|
||||
if (node) {
|
||||
node.reset();
|
||||
}
|
||||
|
||||
// 递归处理子节点
|
||||
for (const child of entity.children) {
|
||||
this.stopRecursive(child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停行为树
|
||||
*
|
||||
* 移除 ActiveNode 但保留节点状态,可以恢复执行
|
||||
*
|
||||
* @param rootEntity 行为树根节点实体
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 暂停
|
||||
* BehaviorTreeStarter.pause(aiRoot);
|
||||
*
|
||||
* // 恢复
|
||||
* BehaviorTreeStarter.resume(aiRoot);
|
||||
* ```
|
||||
*/
|
||||
static pause(rootEntity: Entity): void {
|
||||
this.pauseRecursive(rootEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归暂停所有子节点
|
||||
*/
|
||||
private static pauseRecursive(entity: Entity): void {
|
||||
// 只移除活跃标记,不重置状态
|
||||
if (entity.hasComponent(ActiveNode)) {
|
||||
entity.removeComponentByType(ActiveNode);
|
||||
}
|
||||
|
||||
// 递归处理子节点
|
||||
for (const child of entity.children) {
|
||||
this.pauseRecursive(child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复行为树执行
|
||||
*
|
||||
* 从暂停状态恢复,重新添加 ActiveNode 到之前正在执行的节点
|
||||
*
|
||||
* @param rootEntity 行为树根节点实体
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* BehaviorTreeStarter.resume(aiRoot);
|
||||
* ```
|
||||
*/
|
||||
static resume(rootEntity: Entity): void {
|
||||
this.resumeRecursive(rootEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归恢复所有正在执行的节点
|
||||
*/
|
||||
private static resumeRecursive(entity: Entity): void {
|
||||
const node = entity.getComponent(BehaviorTreeNode);
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果节点状态是 Running,恢复活跃标记
|
||||
if (node.status === TaskStatus.Running) {
|
||||
if (!entity.hasComponent(ActiveNode)) {
|
||||
entity.addComponent(new ActiveNode());
|
||||
}
|
||||
}
|
||||
|
||||
// 递归处理子节点
|
||||
for (const child of entity.children) {
|
||||
this.resumeRecursive(child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启行为树
|
||||
*
|
||||
* 停止并重置所有节点,然后重新启动
|
||||
*
|
||||
* @param rootEntity 行为树根节点实体
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* BehaviorTreeStarter.restart(aiRoot);
|
||||
* ```
|
||||
*/
|
||||
static restart(rootEntity: Entity): void {
|
||||
this.stop(rootEntity);
|
||||
this.start(rootEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查行为树是否正在运行
|
||||
*
|
||||
* @param rootEntity 行为树根节点实体
|
||||
* @returns 是否正在运行
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* if (BehaviorTreeStarter.isRunning(aiRoot)) {
|
||||
* console.log('AI is active');
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
static isRunning(rootEntity: Entity): boolean {
|
||||
return rootEntity.hasComponent(ActiveNode);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user