行为树详细介绍的文档

This commit is contained in:
gongxh
2025-09-23 18:18:20 +08:00
parent 11e6b06b24
commit 260a8badae
45 changed files with 4801 additions and 903 deletions

1466
INTRODUCE.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,20 @@
行为树本质上是一个**有向无环图**,用树状结构来组织和执行行为逻辑。每个节点代表一个行为或决策,通过父子关系形成层次化的控制流。
* 如果你从来没接触过行为树,可以看下这篇文章
[行为树逻辑详解](./docs/BehaviorTree.md)
## 可视化编辑器
[下载地址:https://store.cocos.com/app/detail/8201](https://store.cocos.com/app/detail/8201)
查看详情: [编辑器文档](./docs/USED.md)
![image](./image/bt-gui.png)
## 特性
- 🔧 **类型安全**: 完整 TypeScript 支持
@@ -30,13 +44,6 @@ npm install kunpocc-behaviortree
项目根目录下的 `bt-demo`文件夹
## GUI编辑器
查看详情: [GUI编辑器](./docs/USED.md)
![image](./image/image_tree.png)
## 核心概念
#### 状态类型
@@ -55,22 +62,6 @@ enum Status {
- **条件节点**: 特殊的叶子节点 (Condition)
## 装饰器
> **自行实现的节点,通过装饰器把数据暴露给行为树编辑器**
##### ClassAction - 行为节点装饰器
##### ClassCondition - 条件节点装饰器
##### ClassComposite - 组合节点装饰器
##### ClassDecorator - 装饰节点装饰器
##### prop - 属性装饰器
## 内置节点
### 组合节点 (Composite)

View File

@@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "de9afb2e-952c-4e0b-96df-cc676989bed9",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "d5a536b5-db1b-42ac-8654-5f6a81341c3a",
"files": [],
"subMetas": {},
"userData": {}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "6b9b2da1-08c2-4c40-ab35-e7cb5bb30872",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,147 +0,0 @@
[
{
"__type__": "cc.Prefab",
"_name": "spineboy",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "spineboy",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [],
"_active": true,
"_components": [
{
"__id__": 2
},
{
"__id__": 4
}
],
"_prefab": {
"__id__": 6
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": -1000
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 0.3,
"y": 0.3,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 3
},
"_contentSize": {
"__type__": "cc.Size",
"width": 419.8399963378906,
"height": 686.0800170898438
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.45412539378136013,
"y": 0.011660447470739235
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "dfVeZdqm9E15k7OBD615QP"
},
{
"__type__": "sp.Skeleton",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 5
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_skeletonData": {
"__uuid__": "39a7d8cd-533a-479a-b909-9575bf720338",
"__expectedType__": "sp.SkeletonData"
},
"defaultSkin": "default",
"defaultAnimation": "jump",
"_premultipliedAlpha": true,
"_timeScale": 1,
"_preCacheMode": 0,
"_cacheMode": 0,
"_sockets": [],
"_useTint": false,
"_debugMesh": false,
"_debugBones": false,
"_debugSlots": false,
"_enableBatch": false,
"loop": true,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "deHPJ9jpdJZq/2PP1E2haI"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "fcg4LyhU9MpITaQy7lW8Ru",
"instance": null,
"targetOverrides": null
}
]

View File

@@ -1,13 +0,0 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "610db270-416d-42a9-a228-67b0fe1beee4",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "spineboy"
}
}

View File

Before

Width:  |  Height:  |  Size: 824 KiB

After

Width:  |  Height:  |  Size: 824 KiB

View File

@@ -23,7 +23,7 @@
"_active": true,
"_components": [],
"_prefab": {
"__id__": 22
"__id__": 14
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -54,7 +54,7 @@
},
"autoReleaseAssets": false,
"_globals": {
"__id__": 25
"__id__": 17
},
"_id": "bef93422-3e63-4c0f-a5cf-d926e7360673"
},
@@ -71,22 +71,22 @@
"__id__": 3
},
{
"__id__": 6
"__id__": 9
},
{
"__id__": 8
"__id__": 7
}
],
"_active": true,
"_components": [
{
"__id__": 19
"__id__": 11
},
{
"__id__": 20
"__id__": 12
},
{
"__id__": 21
"__id__": 13
}
],
"_prefab": null,
@@ -199,13 +199,121 @@
},
"_enabled": true,
"__prefab": null,
"skeleton": null,
"btConfig": {
"__uuid__": "c8aeef5d-6d0e-4093-848e-7d8f1ca30261",
"__expectedType__": "cc.JsonAsset"
"skeleton": {
"__id__": 6
},
"btConfig": null,
"_id": "69LhmWaZRIUpmYvdiN82Ha"
},
{
"__type__": "sp.Skeleton",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 7
},
"_enabled": true,
"__prefab": null,
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_skeletonData": {
"__uuid__": "39a7d8cd-533a-479a-b909-9575bf720338",
"__expectedType__": "sp.SkeletonData"
},
"defaultSkin": "default",
"defaultAnimation": "idle",
"_premultipliedAlpha": true,
"_timeScale": 1,
"_preCacheMode": 0,
"_cacheMode": 0,
"_sockets": [],
"_useTint": false,
"_debugMesh": false,
"_debugBones": false,
"_debugSlots": false,
"_enableBatch": false,
"loop": false,
"_id": "e0SlYqh/pPzaLrAWsV78xj"
},
{
"__type__": "cc.Node",
"_name": "spineboy",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 2
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 8
},
{
"__id__": 6
}
],
"_prefab": null,
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": -151.948,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 0.5,
"y": 0.5,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": "a62KjBSsBMSpCYMjsx0oxG"
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 7
},
"_enabled": true,
"__prefab": null,
"_contentSize": {
"__type__": "cc.Size",
"width": 419.8399963378906,
"height": 686.0800170898438
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.45412539378136013,
"y": 0.011660447470739235
},
"_id": "c9XaAZS6pNILxWx4jmSYKE"
},
{
"__type__": "cc.Node",
"_name": "Camera",
@@ -218,7 +326,7 @@
"_active": true,
"_components": [
{
"__id__": 7
"__id__": 10
}
],
"_prefab": null,
@@ -257,7 +365,7 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 6
"__id__": 9
},
"_enabled": true,
"__prefab": null,
@@ -297,149 +405,6 @@
"_trackingType": 0,
"_id": "63WIch3o5BEYRlXzTT0oWc"
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_prefab": {
"__id__": 9
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 8
},
"asset": {
"__uuid__": "610db270-416d-42a9-a228-67b0fe1beee4",
"__expectedType__": "cc.Prefab"
},
"fileId": "fcg4LyhU9MpITaQy7lW8Ru",
"instance": {
"__id__": 10
},
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "2eYzhZYv5Mi5OETcYel3W3",
"prefabRootNode": null,
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 11
},
{
"__id__": 13
},
{
"__id__": 14
},
{
"__id__": 15
},
{
"__id__": 16
},
{
"__id__": 18
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 12
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "cc.TargetInfo",
"localID": [
"fcg4LyhU9MpITaQy7lW8Ru"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 12
},
"propertyPath": [
"_name"
],
"value": "spineboy"
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 12
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 12
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 17
},
"propertyPath": [
"defaultAnimation"
],
"value": "idle"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"deHPJ9jpdJZq/2PP1E2haI"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 17
},
"propertyPath": [
"_premultipliedAlpha"
],
"value": true
},
{
"__type__": "cc.UITransform",
"_name": "",
@@ -473,7 +438,7 @@
"_enabled": true,
"__prefab": null,
"_cameraComponent": {
"__id__": 7
"__id__": 10
},
"_alignCanvasWithScreen": true,
"_id": "12O/ljcVlEqLmVm3U2gEOQ"
@@ -516,12 +481,7 @@
"instance": null,
"targetOverrides": [
{
"__id__": 23
}
],
"nestedPrefabInstanceRoots": [
{
"__id__": 8
"__id__": 15
}
]
},
@@ -534,11 +494,9 @@
"propertyPath": [
"skeleton"
],
"target": {
"__id__": 8
},
"target": null,
"targetInfo": {
"__id__": 24
"__id__": 16
}
},
{
@@ -550,28 +508,28 @@
{
"__type__": "cc.SceneGlobals",
"ambient": {
"__id__": 26
"__id__": 18
},
"shadows": {
"__id__": 27
"__id__": 19
},
"_skybox": {
"__id__": 28
"__id__": 20
},
"fog": {
"__id__": 29
"__id__": 21
},
"octree": {
"__id__": 30
"__id__": 22
},
"skin": {
"__id__": 31
"__id__": 23
},
"lightProbeInfo": {
"__id__": 32
"__id__": 24
},
"postSettings": {
"__id__": 33
"__id__": 25
},
"bakedWithStationaryMainLight": false,
"bakedWithHighpLightmap": false

View File

@@ -47,7 +47,7 @@ export class BTAnimation extends BT.LeafNode {
}
/** 条件节点 */
@BT.ClassCondition("BTConditionRandom", { name: "随机条件节点", group: "基础条件节点", desc: "随机0-1的值于设置值返回成功,否则返回失败" })
@BT.ClassCondition("BTConditionRandom", { name: "随机条件节点", group: "基础条件节点", desc: "随机0-1的值于设置值返回成功,否则返回失败" })
export class BTConditionRandom extends BT.Condition {
@BT.prop({ type: BT.ParamType.float, description: "值", defaultValue: 0.5 })

View File

@@ -1,73 +0,0 @@
interface Math {
/**
* 限制值
* @param value 当前值
* @param min 最小值
* @param max 最大值
*/
clampf(value: number, min: number, max: number): number;
/**
* 随机从 min 到 max 的整数(包含min和max)
* @param min
* @param max
*/
rand(min: number, max: number): number;
/**
* 随机从 min 到 max的数
* @param min
* @param max
*/
randRange(min: number, max: number): number;
/**
* 角度转弧度
* @param angle 角度
*/
rad(angle: number): number;
/**
* 弧度转角度
* @param radian 弧度
*/
deg(radian: number): number;
/**
* 数值平滑渐变
* @param num1
* @param num2
* @param elapsedTime
* @param responseTime
*/
smooth(num1: number, num2: number, elapsedTime: number, responseTime: number): number;
}
Math.clampf = function (value: number, min: number, max: number): number {
return Math.min(Math.max(value, min), max);
};
Math.rand = function (min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1) + min);
};
Math.randRange = function (min: number, max: number): number {
return Math.random() * (max - min) + min;
};
Math.rad = function (angle: number): number {
return (angle * Math.PI) / 180;
};
Math.deg = function (radian: number): number {
return (radian * 180) / Math.PI;
};
Math.smooth = function (num1: number, num2: number, elapsedTime: number, responseTime: number): number {
let out: number = num1;
if (elapsedTime > 0) {
out = out + (num2 - num1) * (elapsedTime / (elapsedTime + responseTime));
}
return out;
};

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "a336ce23-5d73-4280-b2e9-084389a3877e",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,6 +1,6 @@
{
"name": "bt-tree1",
"description": "这是一个描述",
"description": "行为树描述\n",
"nodes": [
{
"id": "1759488688188_qejfcso50",
@@ -8,47 +8,24 @@
"name": "选择节点",
"position": {
"x": -60,
"y": -200
"y": -220
},
"parameters": {},
"children": [
"1759488707759_2bmdm1fqt",
"1759488725107_v8u160t95",
"1759488737637_axpz9aqaz",
"1759482034741_cf3mqaqdj",
"1758190139303_t5o7vv3ak"
"1759488707759_2bmdm1fqt",
"1759482034741_cf3mqaqdj"
],
"alias": "根选择节点"
},
{
"id": "1758190139303_t5o7vv3ak",
"className": "BTTestNode",
"name": "嵌套数据测试节点",
"position": {
"x": 440,
"y": -80
},
"parameters": {
"position": {
"x": 10,
"y": 20
},
"configs": [
{
"name": "hahaa",
"value": 1
}
]
},
"children": []
"alias": "根节点"
},
{
"id": "1759479318405_bptb8ltcp",
"className": "LimitTime",
"name": "时间限制器",
"position": {
"x": -120,
"y": 40
"x": -60,
"y": -40
},
"parameters": {
"_max": 2
@@ -62,8 +39,8 @@
"className": "LimitTime",
"name": "时间限制器",
"position": {
"x": -400,
"y": 40
"x": -340,
"y": -40
},
"parameters": {
"_max": 2
@@ -77,8 +54,8 @@
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": -400,
"y": 160
"x": -340,
"y": 40
},
"parameters": {
"_name": "walk",
@@ -91,22 +68,23 @@
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": -120,
"y": 160
"x": -60,
"y": 40
},
"parameters": {
"_name": "run",
"_loop": true
},
"children": []
"children": [],
"alias": "奔跑动画"
},
{
"id": "1758089757615_dp9tw9ka1",
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": 160,
"y": 40
"x": 220,
"y": -60
},
"parameters": {
"_name": "jump",
@@ -119,8 +97,8 @@
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": 300,
"y": 40
"x": 360,
"y": -60
},
"parameters": {
"_name": "idle",
@@ -133,8 +111,8 @@
"className": "BTConditionRandom",
"name": "随机条件节点",
"position": {
"x": -540,
"y": 40
"x": -480,
"y": -60
},
"parameters": {
"_value": 0.3
@@ -146,8 +124,8 @@
"className": "BTConditionRandom",
"name": "随机条件节点",
"position": {
"x": -260,
"y": 40
"x": -200,
"y": -60
},
"parameters": {
"_value": 0.4
@@ -159,8 +137,8 @@
"className": "BTConditionRandom",
"name": "随机条件节点",
"position": {
"x": 20,
"y": 40
"x": 80,
"y": -60
},
"parameters": {
"_value": 0.3
@@ -172,8 +150,8 @@
"className": "LimitTime",
"name": "时间限制器",
"position": {
"x": 300,
"y": -80
"x": 360,
"y": -140
},
"parameters": {
"_max": 2
@@ -188,45 +166,45 @@
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -480,
"y": -80
"x": -400,
"y": -120
},
"parameters": {},
"children": [
"1759481172259_xou25wj2n",
"1759479295671_jflit2ek8"
],
"alias": "行走动画分支"
"alias": "行走顺序节点"
},
{
"id": "1759488725107_v8u160t95",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -200,
"y": -80
"x": -120,
"y": -120
},
"parameters": {},
"children": [
"1759481282875_5orqavi5y",
"1759479318405_bptb8ltcp"
],
"alias": "奔跑动画"
"alias": "奔跑顺序节点"
},
{
"id": "1759488737637_axpz9aqaz",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 80,
"y": -80
"x": 160,
"y": -120
},
"parameters": {},
"children": [
"1759481307863_ja6q4q9bz",
"1758089757615_dp9tw9ka1"
],
"alias": "跳跃动画分支"
"alias": "跳跃顺序节点"
}
],
"connections": [
@@ -320,18 +298,11 @@
"targetNodeId": "1758089757615_dp9tw9ka1",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758204108181_90iaioyvg",
"sourceNodeId": "1759488688188_qejfcso50",
"targetNodeId": "1758190139303_t5o7vv3ak",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1.0006385665653545,
"canvasScale": 1.25,
"canvasOffset": {
"x": 584.9936143343465,
"y": 498.99074078480237
"x": 723,
"y": 600.875
}
}

View File

@@ -3,66 +3,193 @@
"description": "",
"nodes": [
{
"id": "1758206972710_bhxebhy7o",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 80,
"y": -320
},
"parameters": {},
"children": [
"1758090634327_mf36nwkdt"
]
},
{
"id": "1758090634327_mf36nwkdt",
"id": "1758972524240_4ockrv5jo",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -80,
"x": -60,
"y": -220
},
"parameters": {},
"children": [
"1758206988178_55b7kk5va"
],
"alias": "是的发放是的发放"
"1758972608716_o2uai5dp8",
"1758972550481_0iq7imml9",
"1758972698829_wxfe7ut33"
]
},
{
"id": "1758206988178_55b7kk5va",
"id": "1758889921667_sjwxkfjs7",
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": -20,
"y": -40
"x": 80,
"y": -60
},
"parameters": {
"_name": "",
"_name": "jump",
"_loop": false
},
"children": []
},
{
"id": "1758889925476_dcyjc7a4o",
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": 220,
"y": -60
},
"parameters": {
"_name": "idle",
"_loop": true
},
"children": []
},
{
"id": "1758972550481_0iq7imml9",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 20,
"y": -120
},
"parameters": {},
"children": [
"1758972573109_fxt7magur",
"1758889921667_sjwxkfjs7"
]
},
{
"id": "1758972573109_fxt7magur",
"className": "BTConditionRandom",
"name": "随机条件节点",
"position": {
"x": -60,
"y": -60
},
"parameters": {
"_value": 0.5
},
"children": []
},
{
"id": "1758972608716_o2uai5dp8",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -260,
"y": -120
},
"parameters": {},
"children": [
"1758972608716_ivq9o10bi",
"1758972608716_zmw9ep5n3"
]
},
{
"id": "1758972608716_ivq9o10bi",
"className": "BTConditionRandom",
"name": "随机条件节点",
"position": {
"x": -340,
"y": -60
},
"parameters": {
"_value": 0.5
},
"children": []
},
{
"id": "1758972608716_zmw9ep5n3",
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": -200,
"y": -60
},
"parameters": {
"_name": "jump",
"_loop": false
},
"children": []
},
{
"id": "1758972698829_wxfe7ut33",
"className": "LimitTime",
"name": "时间限制节点",
"position": {
"x": 220,
"y": -140
},
"parameters": {
"_max": 2
},
"children": [
"1758889925476_dcyjc7a4o"
]
}
],
"connections": [
{
"id": "conn_1758206976733_208tneycs",
"sourceNodeId": "1758206972710_bhxebhy7o",
"targetNodeId": "1758090634327_mf36nwkdt",
"id": "conn_1758972580886_zykcbl2vk",
"sourceNodeId": "1758972550481_0iq7imml9",
"targetNodeId": "1758972573109_fxt7magur",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758206989897_46hw88z7h",
"sourceNodeId": "1758090634327_mf36nwkdt",
"targetNodeId": "1758206988178_55b7kk5va",
"id": "conn_1758972582770_9e4pexjcz",
"sourceNodeId": "1758972550481_0iq7imml9",
"targetNodeId": "1758889921667_sjwxkfjs7",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758972608716_6gnj5711e",
"sourceNodeId": "1758972608716_o2uai5dp8",
"targetNodeId": "1758972608716_ivq9o10bi",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758972608716_9y9ytjxa8",
"sourceNodeId": "1758972608716_o2uai5dp8",
"targetNodeId": "1758972608716_zmw9ep5n3",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758972613504_me3rp31l8",
"sourceNodeId": "1758972524240_4ockrv5jo",
"targetNodeId": "1758972608716_o2uai5dp8",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758972674275_rkn2let28",
"sourceNodeId": "1758972524240_4ockrv5jo",
"targetNodeId": "1758972550481_0iq7imml9",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758972717495_fo5zdeslg",
"sourceNodeId": "1758972524240_4ockrv5jo",
"targetNodeId": "1758972698829_wxfe7ut33",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758972724719_hjsvpuvvy",
"sourceNodeId": "1758972698829_wxfe7ut33",
"targetNodeId": "1758889925476_dcyjc7a4o",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1.139190980775211,
"canvasScale": 1.953125,
"canvasOffset": {
"x": 549.4323607689915,
"y": 698.6185343759718
"x": 700,
"y": 665.25
}
}

View File

@@ -0,0 +1,193 @@
{
"name": "bt-tree3",
"description": "",
"nodes": [
{
"id": "1758979704536_g6jkamjdm",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -60,
"y": -220
},
"parameters": {},
"children": [
"1758979708831_vibpbusev",
"1758979710657_ksqwgrqym",
"1758979712702_5miziffc9"
]
},
{
"id": "1758979708831_vibpbusev",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -260,
"y": -120
},
"parameters": {},
"children": [
"1758979721847_ikkmffinc",
"1758979717102_hs4zv2ysl"
]
},
{
"id": "1758979710657_ksqwgrqym",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 20,
"y": -120
},
"parameters": {},
"children": [
"1758979723586_oa4umrekl",
"1758979718532_16c9kb7cx"
]
},
{
"id": "1758979712702_5miziffc9",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 220,
"y": -120
},
"parameters": {},
"children": [
"1758979720285_9ojvbt7sw"
]
},
{
"id": "1758979717102_hs4zv2ysl",
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": -200,
"y": -60
},
"parameters": {
"_name": "run",
"_loop": false
},
"children": []
},
{
"id": "1758979718532_16c9kb7cx",
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": 80,
"y": -60
},
"parameters": {
"_name": "",
"_loop": false
},
"children": []
},
{
"id": "1758979720285_9ojvbt7sw",
"className": "BTAnimation",
"name": "播放动画",
"position": {
"x": 220,
"y": -60
},
"parameters": {
"_name": "",
"_loop": false
},
"children": []
},
{
"id": "1758979721847_ikkmffinc",
"className": "BTConditionRandom",
"name": "随机条件节点",
"position": {
"x": -340,
"y": -60
},
"parameters": {
"_value": 0.5
},
"children": []
},
{
"id": "1758979723586_oa4umrekl",
"className": "BTConditionRandom",
"name": "随机条件节点",
"position": {
"x": -60,
"y": -60
},
"parameters": {
"_value": 0.5
},
"children": []
}
],
"connections": [
{
"id": "conn_1758979728478_r812fr61c",
"sourceNodeId": "1758979704536_g6jkamjdm",
"targetNodeId": "1758979708831_vibpbusev",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758979730147_24owqabyj",
"sourceNodeId": "1758979704536_g6jkamjdm",
"targetNodeId": "1758979710657_ksqwgrqym",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758979732272_8ywszwdxr",
"sourceNodeId": "1758979704536_g6jkamjdm",
"targetNodeId": "1758979712702_5miziffc9",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758979734464_rm0ysdtpo",
"sourceNodeId": "1758979708831_vibpbusev",
"targetNodeId": "1758979721847_ikkmffinc",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758979739229_8pnb80e23",
"sourceNodeId": "1758979708831_vibpbusev",
"targetNodeId": "1758979717102_hs4zv2ysl",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758979741003_zg52rxs79",
"sourceNodeId": "1758979710657_ksqwgrqym",
"targetNodeId": "1758979723586_oa4umrekl",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758979744846_1oagoplj0",
"sourceNodeId": "1758979710657_ksqwgrqym",
"targetNodeId": "1758979718532_16c9kb7cx",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758979750437_3oafpzhyz",
"sourceNodeId": "1758979712702_5miziffc9",
"targetNodeId": "1758979720285_9ojvbt7sw",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1,
"canvasOffset": {
"x": 595,
"y": 618.5
}
}

View File

@@ -0,0 +1,494 @@
{
"name": "example-boss",
"description": "",
"nodes": [
{
"id": "1758636606871_d00eo32m0",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -360,
"y": -240
},
"parameters": {},
"children": [
"1758636606871_nlci5zgin",
"1758636827735_ghi1jyp6e",
"1758636606871_73vz04ef6"
],
"alias": "Boss选择节点"
},
{
"id": "1758636606871_nlci5zgin",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -740,
"y": -180
},
"parameters": {},
"children": [
"1758636606871_bfer3pf0k",
"1758636606871_fz7ji79yr"
],
"alias": "第三阶段"
},
{
"id": "1758636606871_bfer3pf0k",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -920,
"y": -80
},
"parameters": {},
"children": [],
"alias": "血量<25%"
},
{
"id": "1758636606871_fz7ji79yr",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -780,
"y": -80
},
"parameters": {},
"children": [
"1758636606871_9xic9f2n1",
"1758636606871_v7xq9t9ca",
"1758636606871_3hexy07r4"
],
"alias": "狂暴行为选择"
},
{
"id": "1758636606871_9xic9f2n1",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -960,
"y": 60
},
"parameters": {},
"children": [],
"alias": "火焰吐息"
},
{
"id": "1758636606871_v7xq9t9ca",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -820,
"y": 60
},
"parameters": {},
"children": [],
"alias": "地面重击"
},
{
"id": "1758636606871_3hexy07r4",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -680,
"y": 60
},
"parameters": {},
"children": [],
"alias": "愤怒冲撞"
},
{
"id": "1758636606871_ramtsopmx",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -540,
"y": 60
},
"parameters": {},
"children": [
"1758636606871_wkmdmgfdw",
"1758636926699_fkhgmqdd1",
"1758636950500_y5gbq9gt9"
],
"alias": "飞行轰炸"
},
{
"id": "1758636606871_wkmdmgfdw",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -680,
"y": 140
},
"parameters": {},
"children": [],
"alias": "起飞"
},
{
"id": "1758636606871_73vz04ef6",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -180,
"y": -100
},
"parameters": {},
"children": [
"1758637141288_y6xr4qiqo",
"1758637139642_lhe3fdfhi",
"1758636606871_4cwadcn7f"
],
"alias": "第一阶段"
},
{
"id": "1758636606871_o1bko71f4",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -220,
"y": 240
},
"parameters": {},
"children": [],
"alias": "在攻击范围内?"
},
{
"id": "1758636606871_kman1jm6o",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -80,
"y": 240
},
"parameters": {},
"children": [],
"alias": "爪击攻击"
},
{
"id": "1758636606871_4cwadcn7f",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 120,
"y": 60
},
"parameters": {},
"children": [],
"alias": "位置调整"
},
{
"id": "1758636783944_9xxk4gqyo",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -560,
"y": -60
},
"parameters": {},
"children": [],
"alias": "血量<60%"
},
{
"id": "1758636827735_ghi1jyp6e",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -480,
"y": -120
},
"parameters": {},
"children": [
"1758636783944_9xxk4gqyo",
"1758636868515_9gnnfpbvg"
],
"alias": "第二阶段"
},
{
"id": "1758636868515_9gnnfpbvg",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -400,
"y": -40
},
"parameters": {},
"children": [
"1758636606871_ramtsopmx",
"1758636975617_40xzee108",
"1758636981864_rtfejtz1m"
],
"alias": "空中行为"
},
{
"id": "1758636926699_fkhgmqdd1",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -540,
"y": 140
},
"parameters": {},
"children": [],
"alias": "空中盘旋"
},
{
"id": "1758636950500_y5gbq9gt9",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -400,
"y": 140
},
"parameters": {},
"children": [],
"alias": "火球轰炸"
},
{
"id": "1758636975617_40xzee108",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -400,
"y": 60
},
"parameters": {},
"children": [],
"alias": "俯冲攻击"
},
{
"id": "1758636981864_rtfejtz1m",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -260,
"y": 60
},
"parameters": {},
"children": [],
"alias": "着陆休息"
},
{
"id": "1758637139642_lhe3fdfhi",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -40,
"y": 40
},
"parameters": {},
"children": [
"1758637233781_l0o4zg8uh",
"1758637233781_vrbhvrzj7"
],
"alias": "远程攻击"
},
{
"id": "1758637141288_y6xr4qiqo",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -160,
"y": 120
},
"parameters": {},
"children": [
"1758636606871_o1bko71f4",
"1758636606871_kman1jm6o"
],
"alias": "近战攻击"
},
{
"id": "1758637233781_l0o4zg8uh",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 0,
"y": 160
},
"parameters": {},
"children": [],
"alias": "远程攻击范围内?"
},
{
"id": "1758637233781_vrbhvrzj7",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 140,
"y": 180
},
"parameters": {},
"children": [],
"alias": "火焰吐息"
}
],
"connections": [
{
"id": "conn_1758636606871_hohhzwyui",
"sourceNodeId": "1758636606871_d00eo32m0",
"targetNodeId": "1758636606871_nlci5zgin",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636606871_g4io9w6xa",
"sourceNodeId": "1758636606871_nlci5zgin",
"targetNodeId": "1758636606871_bfer3pf0k",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636606871_uxssfr3ed",
"sourceNodeId": "1758636606871_nlci5zgin",
"targetNodeId": "1758636606871_fz7ji79yr",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636606871_f5z1f2yqo",
"sourceNodeId": "1758636606871_fz7ji79yr",
"targetNodeId": "1758636606871_9xic9f2n1",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636606871_8y8rjemlv",
"sourceNodeId": "1758636606871_fz7ji79yr",
"targetNodeId": "1758636606871_v7xq9t9ca",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636606871_rt5kqakrv",
"sourceNodeId": "1758636606871_fz7ji79yr",
"targetNodeId": "1758636606871_3hexy07r4",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636606871_x2gm9dhxe",
"sourceNodeId": "1758636606871_ramtsopmx",
"targetNodeId": "1758636606871_wkmdmgfdw",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636831033_ojdk1yez2",
"sourceNodeId": "1758636606871_d00eo32m0",
"targetNodeId": "1758636827735_ghi1jyp6e",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636838409_vvu7h2oxv",
"sourceNodeId": "1758636827735_ghi1jyp6e",
"targetNodeId": "1758636783944_9xxk4gqyo",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636881443_9l4j91h2l",
"sourceNodeId": "1758636827735_ghi1jyp6e",
"targetNodeId": "1758636868515_9gnnfpbvg",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636900749_xnmxnysyq",
"sourceNodeId": "1758636868515_9gnnfpbvg",
"targetNodeId": "1758636606871_ramtsopmx",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636941918_meg9myb9f",
"sourceNodeId": "1758636606871_ramtsopmx",
"targetNodeId": "1758636926699_fkhgmqdd1",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636956983_adx271a9m",
"sourceNodeId": "1758636606871_ramtsopmx",
"targetNodeId": "1758636950500_y5gbq9gt9",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636979547_gcm5tlfpz",
"sourceNodeId": "1758636868515_9gnnfpbvg",
"targetNodeId": "1758636975617_40xzee108",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636983730_fkcf1oa0r",
"sourceNodeId": "1758636868515_9gnnfpbvg",
"targetNodeId": "1758636981864_rtfejtz1m",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637120534_9zvi0veg2",
"sourceNodeId": "1758636606871_d00eo32m0",
"targetNodeId": "1758636606871_73vz04ef6",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637146881_ff7nkp6qb",
"sourceNodeId": "1758636606871_73vz04ef6",
"targetNodeId": "1758637141288_y6xr4qiqo",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637156935_u4w7h7pm7",
"sourceNodeId": "1758636606871_73vz04ef6",
"targetNodeId": "1758637139642_lhe3fdfhi",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637192215_aee0g0293",
"sourceNodeId": "1758636606871_73vz04ef6",
"targetNodeId": "1758636606871_4cwadcn7f",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637199301_402o3lx5d",
"sourceNodeId": "1758637141288_y6xr4qiqo",
"targetNodeId": "1758636606871_o1bko71f4",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637201011_83nxti0fo",
"sourceNodeId": "1758637141288_y6xr4qiqo",
"targetNodeId": "1758636606871_kman1jm6o",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637238023_fcezi3h1o",
"sourceNodeId": "1758637139642_lhe3fdfhi",
"targetNodeId": "1758637233781_l0o4zg8uh",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758637240305_v6mf8e059",
"sourceNodeId": "1758637139642_lhe3fdfhi",
"targetNodeId": "1758637233781_vrbhvrzj7",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1.0893125857312862,
"canvasOffset": {
"x": 1076.4697723606591,
"y": 543.3385223005863
}
}

View File

@@ -0,0 +1,678 @@
{
"name": "example-npc1",
"description": "",
"nodes": [
{
"id": "1758635344069_hairxmvmh",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -60,
"y": -220
},
"parameters": {},
"children": [
"1758635421003_4s8uj787l",
"1758635605374_990xn0z9c",
"1758635344069_4yss1wz7d",
"1758636072669_whqacjf0i",
"1758636171277_d7th6ojvm"
],
"alias": "居民AI 选择节"
},
{
"id": "1758635344069_4yss1wz7d",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 220,
"y": -120
},
"parameters": {},
"children": [
"1758635344069_gg3q5rxes",
"1758635344069_7ecq7pfzw"
],
"alias": "工作"
},
{
"id": "1758635344069_gg3q5rxes",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": 20,
"y": -60
},
"parameters": {},
"children": [],
"alias": "在工作时间?"
},
{
"id": "1758635344069_7ecq7pfzw",
"className": "Selector",
"name": "选择节点",
"position": {
"x": 300,
"y": -40
},
"parameters": {},
"children": [
"1758635344069_8ck2fgr24",
"1758635344069_1wzefq3da",
"1758635344069_3ezjerufd"
],
"alias": "工作行为选择"
},
{
"id": "1758635344069_8ck2fgr24",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 160,
"y": 60
},
"parameters": {},
"children": [],
"alias": "商店经营"
},
{
"id": "1758635344069_1wzefq3da",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 300,
"y": 60
},
"parameters": {},
"children": [],
"alias": "田间劳作"
},
{
"id": "1758635344069_3ezjerufd",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 440,
"y": 60
},
"parameters": {},
"children": [],
"alias": "巡逻守卫"
},
{
"id": "1758635421003_4s8uj787l",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -1040,
"y": -120
},
"parameters": {},
"children": [
"1758635460230_zn5vibc1s",
"1758635463818_pn3pcjsxo",
"1758635545865_k2vgufpnb"
],
"alias": "紧急情况处理"
},
{
"id": "1758635460230_zn5vibc1s",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -1320,
"y": -40
},
"parameters": {},
"children": [
"1758635460230_j09ztl8mq",
"1758635460230_qvwu6fx64"
],
"alias": "火灾逃生"
},
{
"id": "1758635460230_j09ztl8mq",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -1380,
"y": 40
},
"parameters": {},
"children": [],
"alias": "发现火灾"
},
{
"id": "1758635460230_qvwu6fx64",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -1240,
"y": 60
},
"parameters": {},
"children": [],
"alias": "逃离火场"
},
{
"id": "1758635463818_pn3pcjsxo",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -1040,
"y": -40
},
"parameters": {},
"children": [
"1758635463818_pihq95w8k",
"1758635463818_5lxcl9204"
],
"alias": "怪物入侵"
},
{
"id": "1758635463818_pihq95w8k",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -1100,
"y": 40
},
"parameters": {},
"children": [],
"alias": "发现怪物"
},
{
"id": "1758635463818_5lxcl9204",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -960,
"y": 60
},
"parameters": {},
"children": [],
"alias": "躲避怪物"
},
{
"id": "1758635545865_k2vgufpnb",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -760,
"y": -40
},
"parameters": {},
"children": [
"1758635545865_zlzorqr1s",
"1758635545865_z6hmdd955"
],
"alias": "天气避难"
},
{
"id": "1758635545865_zlzorqr1s",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -820,
"y": 40
},
"parameters": {},
"children": [],
"alias": "恶劣天气"
},
{
"id": "1758635545865_z6hmdd955",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -680,
"y": 60
},
"parameters": {},
"children": [],
"alias": "寻找庇护所"
},
{
"id": "1758635605374_990xn0z9c",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -340,
"y": -120
},
"parameters": {},
"children": [
"1758635740579_fw4dk6ikf",
"1758635744921_j7amyl952"
],
"alias": "社交互动"
},
{
"id": "1758635624148_qew2aoutm",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -400,
"y": 60
},
"parameters": {},
"children": [],
"alias": "开始对话"
},
{
"id": "1758635652784_531a4s3wt",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -540,
"y": 40
},
"parameters": {},
"children": [],
"alias": "玩家靠近?"
},
{
"id": "1758635705235_zn4f5x42i",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -120,
"y": 60
},
"parameters": {},
"children": [],
"alias": "社交行为"
},
{
"id": "1758635740579_fw4dk6ikf",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -480,
"y": -40
},
"parameters": {},
"children": [
"1758635652784_531a4s3wt",
"1758635624148_qew2aoutm"
],
"alias": "与玩家对话"
},
{
"id": "1758635744921_j7amyl952",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -200,
"y": -40
},
"parameters": {},
"children": [
"1758635767133_koukdag8k",
"1758635705235_zn4f5x42i"
],
"alias": "与NPC交流"
},
{
"id": "1758635767133_koukdag8k",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -260,
"y": 40
},
"parameters": {},
"children": [],
"alias": "附近有其他NPC"
},
{
"id": "1758636072669_whqacjf0i",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 780,
"y": -120
},
"parameters": {},
"children": [
"1758636072669_23ygfl1xz",
"1758636072669_efwoobpa6"
],
"alias": "休息"
},
{
"id": "1758636072669_23ygfl1xz",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": 580,
"y": -60
},
"parameters": {},
"children": [],
"alias": "在休息时间?"
},
{
"id": "1758636072669_efwoobpa6",
"className": "Selector",
"name": "选择节点",
"position": {
"x": 860,
"y": -40
},
"parameters": {},
"children": [
"1758636072669_1a8wocwxo",
"1758636072669_2f7kryz2k",
"1758636072669_qq7v8cita"
],
"alias": "休闲行为选择"
},
{
"id": "1758636072669_1a8wocwxo",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 720,
"y": 60
},
"parameters": {},
"children": [],
"alias": "商店经营"
},
{
"id": "1758636072669_2f7kryz2k",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 860,
"y": 60
},
"parameters": {},
"children": [],
"alias": "酒馆聚会"
},
{
"id": "1758636072669_qq7v8cita",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 1000,
"y": 60
},
"parameters": {},
"children": [],
"alias": "街道闲逛"
},
{
"id": "1758636171277_d7th6ojvm",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 1200,
"y": -120
},
"parameters": {},
"children": [
"1758636171277_ga2mbrzxt",
"1758636171277_m9w7cla2o"
],
"alias": "睡眠"
},
{
"id": "1758636171277_ga2mbrzxt",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": 1140,
"y": -60
},
"parameters": {},
"children": [],
"alias": "睡觉时间"
},
{
"id": "1758636171277_m9w7cla2o",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 1280,
"y": -40
},
"parameters": {},
"children": [],
"alias": "睡觉"
}
],
"connections": [
{
"id": "conn_1758635344069_g5evt0a55",
"sourceNodeId": "1758635344069_hairxmvmh",
"targetNodeId": "1758635344069_4yss1wz7d",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635344069_635mfq9i3",
"sourceNodeId": "1758635344069_4yss1wz7d",
"targetNodeId": "1758635344069_gg3q5rxes",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635344069_9s3w5e0un",
"sourceNodeId": "1758635344069_4yss1wz7d",
"targetNodeId": "1758635344069_7ecq7pfzw",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635344069_8x0splgwg",
"sourceNodeId": "1758635344069_7ecq7pfzw",
"targetNodeId": "1758635344069_8ck2fgr24",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635344069_isl3zgjdk",
"sourceNodeId": "1758635344069_7ecq7pfzw",
"targetNodeId": "1758635344069_1wzefq3da",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635344069_qt7oa6p4i",
"sourceNodeId": "1758635344069_7ecq7pfzw",
"targetNodeId": "1758635344069_3ezjerufd",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635424147_iccjn2uwj",
"sourceNodeId": "1758635344069_hairxmvmh",
"targetNodeId": "1758635421003_4s8uj787l",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635460230_zvxht1t8t",
"sourceNodeId": "1758635460230_zn5vibc1s",
"targetNodeId": "1758635460230_j09ztl8mq",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635460230_buaa4nw9s",
"sourceNodeId": "1758635460230_zn5vibc1s",
"targetNodeId": "1758635460230_qvwu6fx64",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635463818_rukkjwv57",
"sourceNodeId": "1758635463818_pn3pcjsxo",
"targetNodeId": "1758635463818_pihq95w8k",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635463818_qqu2vn4ri",
"sourceNodeId": "1758635463818_pn3pcjsxo",
"targetNodeId": "1758635463818_5lxcl9204",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635482801_8qzraey6h",
"sourceNodeId": "1758635421003_4s8uj787l",
"targetNodeId": "1758635460230_zn5vibc1s",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635484959_b57b7mjv2",
"sourceNodeId": "1758635421003_4s8uj787l",
"targetNodeId": "1758635463818_pn3pcjsxo",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635545865_0gg6i98tc",
"sourceNodeId": "1758635545865_k2vgufpnb",
"targetNodeId": "1758635545865_zlzorqr1s",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635545865_kq0md4693",
"sourceNodeId": "1758635545865_k2vgufpnb",
"targetNodeId": "1758635545865_z6hmdd955",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635548778_wu79ybxfq",
"sourceNodeId": "1758635421003_4s8uj787l",
"targetNodeId": "1758635545865_k2vgufpnb",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635607282_il4fwt2yi",
"sourceNodeId": "1758635344069_hairxmvmh",
"targetNodeId": "1758635605374_990xn0z9c",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635743478_nh8my40cm",
"sourceNodeId": "1758635605374_990xn0z9c",
"targetNodeId": "1758635740579_fw4dk6ikf",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635756635_47q580ro0",
"sourceNodeId": "1758635740579_fw4dk6ikf",
"targetNodeId": "1758635652784_531a4s3wt",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635760244_jpdlqjzx6",
"sourceNodeId": "1758635740579_fw4dk6ikf",
"targetNodeId": "1758635624148_qew2aoutm",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635769637_f4ss1fpgi",
"sourceNodeId": "1758635744921_j7amyl952",
"targetNodeId": "1758635767133_koukdag8k",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635771670_kaec4j4lz",
"sourceNodeId": "1758635605374_990xn0z9c",
"targetNodeId": "1758635744921_j7amyl952",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758635814216_xduqega2f",
"sourceNodeId": "1758635744921_j7amyl952",
"targetNodeId": "1758635705235_zn4f5x42i",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636072669_zzey7i401",
"sourceNodeId": "1758636072669_whqacjf0i",
"targetNodeId": "1758636072669_23ygfl1xz",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636072669_ntj9ny811",
"sourceNodeId": "1758636072669_whqacjf0i",
"targetNodeId": "1758636072669_efwoobpa6",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636072669_65be02vyw",
"sourceNodeId": "1758636072669_efwoobpa6",
"targetNodeId": "1758636072669_1a8wocwxo",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636072669_tilypn8pf",
"sourceNodeId": "1758636072669_efwoobpa6",
"targetNodeId": "1758636072669_2f7kryz2k",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636072669_3eblz933g",
"sourceNodeId": "1758636072669_efwoobpa6",
"targetNodeId": "1758636072669_qq7v8cita",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636106650_2q3md7ywn",
"sourceNodeId": "1758635344069_hairxmvmh",
"targetNodeId": "1758636072669_whqacjf0i",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636171277_n2pvad7qp",
"sourceNodeId": "1758636171277_d7th6ojvm",
"targetNodeId": "1758636171277_ga2mbrzxt",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636186409_7udx1m2k5",
"sourceNodeId": "1758635344069_hairxmvmh",
"targetNodeId": "1758636171277_d7th6ojvm",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758636230675_q9z4toddg",
"sourceNodeId": "1758636171277_d7th6ojvm",
"targetNodeId": "1758636171277_m9w7cla2o",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1,
"canvasOffset": {
"x": -253,
"y": 424.5
}
}

View File

@@ -0,0 +1,494 @@
{
"name": "example-scanning1",
"description": "",
"nodes": [
{
"id": "1758633912545_7xy1se8pk",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -180,
"y": -240
},
"parameters": {},
"children": [
"1758633912545_z0wbw5zkn",
"1758633912545_ismgc4xad",
"1758633912545_cdy2pg1pn",
"1758634397890_nh8nat3ph"
],
"alias": "守卫AI"
},
{
"id": "1758633912545_26tx6w4f1",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -760,
"y": 140
},
"parameters": {},
"children": [],
"alias": "攻击"
},
{
"id": "1758633912545_df302i0u7",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -340,
"y": 60
},
"parameters": {},
"children": [],
"alias": "搜索敌人"
},
{
"id": "1758633912545_qdoxrynps",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -480,
"y": 140
},
"parameters": {},
"children": [],
"alias": "追击敌人"
},
{
"id": "1758633912545_z0wbw5zkn",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -680,
"y": -120
},
"parameters": {},
"children": [
"1758633987202_p7z2iewl8",
"1758634022458_f769kvf1x"
],
"alias": "战斗模式"
},
{
"id": "1758633912545_ismgc4xad",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -80,
"y": -120
},
"parameters": {},
"children": [
"1758633912545_q02k78ubn",
"1758634249975_c1i6wxc2w"
],
"alias": "警戒模式"
},
{
"id": "1758633912545_nawabdhem",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -160,
"y": 60
},
"parameters": {},
"children": [],
"alias": "调查可疑位置"
},
{
"id": "1758633912545_q02k78ubn",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -180,
"y": -60
},
"parameters": {},
"children": [],
"alias": "处于警戒状态?"
},
{
"id": "1758633912545_cdy2pg1pn",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 360,
"y": -120
},
"parameters": {},
"children": [
"1758634317404_8aaeb4ve2",
"1758634337943_93kaze24m"
],
"alias": "怀疑模式"
},
{
"id": "1758633912545_lgpy79s0o",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 280,
"y": 60
},
"parameters": {},
"children": [],
"alias": "查看声音方向"
},
{
"id": "1758633912545_i1kac3qvv",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 420,
"y": 60
},
"parameters": {},
"children": [],
"alias": "接近可以位置"
},
{
"id": "1758633912545_5cqcrrfkg",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 560,
"y": 60
},
"parameters": {},
"children": [],
"alias": "提高警觉"
},
{
"id": "1758633987202_p7z2iewl8",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -800,
"y": -60
},
"parameters": {},
"children": [],
"alias": "处于战斗状态?"
},
{
"id": "1758634022458_f769kvf1x",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -620,
"y": -40
},
"parameters": {},
"children": [
"1758634091921_6xr6c6cul",
"1758634094741_dk5mmim4z",
"1758633912545_df302i0u7"
],
"alias": "战斗行为选择"
},
{
"id": "1758634091921_6xr6c6cul",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -820,
"y": 60
},
"parameters": {},
"children": [
"1758634117284_29jp1jxyq",
"1758633912545_26tx6w4f1"
],
"alias": "攻击"
},
{
"id": "1758634094741_dk5mmim4z",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -540,
"y": 60
},
"parameters": {},
"children": [
"1758634119520_rz3hx4hno",
"1758633912545_qdoxrynps"
],
"alias": "追击"
},
{
"id": "1758634117284_29jp1jxyq",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -900,
"y": 120
},
"parameters": {},
"children": [],
"alias": "敌人在范围内?"
},
{
"id": "1758634119520_rz3hx4hno",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -620,
"y": 120
},
"parameters": {},
"children": [],
"alias": "敌人可见?"
},
{
"id": "1758634249975_c1i6wxc2w",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -20,
"y": -40
},
"parameters": {},
"children": [
"1758633912545_nawabdhem",
"1758634290870_im6rplw92",
"1758634284662_l7hvr7fuo"
],
"alias": "警戒行为选择"
},
{
"id": "1758634284662_l7hvr7fuo",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 120,
"y": 60
},
"parameters": {},
"children": [],
"alias": "扩大搜索范围"
},
{
"id": "1758634290870_im6rplw92",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -20,
"y": 60
},
"parameters": {},
"children": [],
"alias": "呼叫支援"
},
{
"id": "1758634317404_8aaeb4ve2",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": 260,
"y": -60
},
"parameters": {},
"children": [],
"alias": "处于怀疑状态?"
},
{
"id": "1758634337943_93kaze24m",
"className": "Selector",
"name": "选择节点",
"position": {
"x": 420,
"y": -40
},
"parameters": {},
"children": [
"1758633912545_lgpy79s0o",
"1758633912545_i1kac3qvv",
"1758633912545_5cqcrrfkg"
],
"alias": "怀疑行为选择"
},
{
"id": "1758634397890_nh8nat3ph",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 540,
"y": -120
},
"parameters": {},
"children": [],
"alias": "正常巡逻"
}
],
"connections": [
{
"id": "conn_1758633912545_72krgicoe",
"sourceNodeId": "1758633912545_7xy1se8pk",
"targetNodeId": "1758633912545_z0wbw5zkn",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633912545_bhua2nzbe",
"sourceNodeId": "1758633912545_7xy1se8pk",
"targetNodeId": "1758633912545_ismgc4xad",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633912545_qztd5a8yt",
"sourceNodeId": "1758633912545_ismgc4xad",
"targetNodeId": "1758633912545_q02k78ubn",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633912545_fv0m9fjvz",
"sourceNodeId": "1758633912545_7xy1se8pk",
"targetNodeId": "1758633912545_cdy2pg1pn",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633989141_2t28ad61w",
"sourceNodeId": "1758633912545_z0wbw5zkn",
"targetNodeId": "1758633987202_p7z2iewl8",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634024382_250r9sidn",
"sourceNodeId": "1758633912545_z0wbw5zkn",
"targetNodeId": "1758634022458_f769kvf1x",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634096585_wmf98bvny",
"sourceNodeId": "1758634022458_f769kvf1x",
"targetNodeId": "1758634091921_6xr6c6cul",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634098806_r2eard8uu",
"sourceNodeId": "1758634022458_f769kvf1x",
"targetNodeId": "1758634094741_dk5mmim4z",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634121545_kb9vs2npo",
"sourceNodeId": "1758634091921_6xr6c6cul",
"targetNodeId": "1758634117284_29jp1jxyq",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634123128_3oq7o7eyv",
"sourceNodeId": "1758634094741_dk5mmim4z",
"targetNodeId": "1758634119520_rz3hx4hno",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634125701_vu0xgjyca",
"sourceNodeId": "1758634094741_dk5mmim4z",
"targetNodeId": "1758633912545_qdoxrynps",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634168660_65ptgegud",
"sourceNodeId": "1758634022458_f769kvf1x",
"targetNodeId": "1758633912545_df302i0u7",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634191735_9dp24mq79",
"sourceNodeId": "1758634091921_6xr6c6cul",
"targetNodeId": "1758633912545_26tx6w4f1",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634251707_a24kslpjc",
"sourceNodeId": "1758633912545_ismgc4xad",
"targetNodeId": "1758634249975_c1i6wxc2w",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634271128_gpkx0yz3a",
"sourceNodeId": "1758634249975_c1i6wxc2w",
"targetNodeId": "1758633912545_nawabdhem",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634293633_vn1hyilmw",
"sourceNodeId": "1758634249975_c1i6wxc2w",
"targetNodeId": "1758634290870_im6rplw92",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634295590_opwzkozm3",
"sourceNodeId": "1758634249975_c1i6wxc2w",
"targetNodeId": "1758634284662_l7hvr7fuo",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634319737_nkogdm0cs",
"sourceNodeId": "1758633912545_cdy2pg1pn",
"targetNodeId": "1758634317404_8aaeb4ve2",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634344054_vo7vw8fmt",
"sourceNodeId": "1758633912545_cdy2pg1pn",
"targetNodeId": "1758634337943_93kaze24m",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634385597_4o9rgtnom",
"sourceNodeId": "1758634337943_93kaze24m",
"targetNodeId": "1758633912545_lgpy79s0o",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634387383_fdxkfmsjs",
"sourceNodeId": "1758634337943_93kaze24m",
"targetNodeId": "1758633912545_i1kac3qvv",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634389050_8ad7tojaj",
"sourceNodeId": "1758634337943_93kaze24m",
"targetNodeId": "1758633912545_5cqcrrfkg",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758634403465_it5m1di95",
"sourceNodeId": "1758633912545_7xy1se8pk",
"targetNodeId": "1758634397890_nh8nat3ph",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 0.7882997760000008,
"canvasOffset": {
"x": 758.2,
"y": 526.7
}
}

View File

@@ -0,0 +1,11 @@
{
"name": "test-bttree",
"description": "",
"nodes": [],
"connections": [],
"canvasScale": 1,
"canvasOffset": {
"x": 723,
"y": 531.5
}
}

View File

@@ -0,0 +1,86 @@
{
"name": "tree-example-move1",
"description": "",
"nodes": [
{
"id": "1758633158053_g12gp05tz",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -60,
"y": -220
},
"parameters": {},
"children": [
"1758633158053_n9lvsqtou",
"1758633158053_m7mptbzme",
"1758633230846_qqosra95l"
],
"alias": "巡逻顺序节点"
},
{
"id": "1758633158053_n9lvsqtou",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -200,
"y": -120
},
"parameters": {},
"children": [],
"alias": "移动到下一巡逻点"
},
{
"id": "1758633158053_m7mptbzme",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -60,
"y": -120
},
"parameters": {},
"children": [],
"alias": "等待片刻"
},
{
"id": "1758633230846_qqosra95l",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 80,
"y": -120
},
"parameters": {},
"children": [],
"alias": "更新巡逻点"
}
],
"connections": [
{
"id": "conn_1758633158053_o1n2n1h4x",
"sourceNodeId": "1758633158053_g12gp05tz",
"targetNodeId": "1758633158053_n9lvsqtou",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633175180_5ukpygitx",
"sourceNodeId": "1758633158053_g12gp05tz",
"targetNodeId": "1758633158053_m7mptbzme",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633234380_cyje40zf5",
"sourceNodeId": "1758633158053_g12gp05tz",
"targetNodeId": "1758633230846_qqosra95l",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1.2507982082066933,
"canvasOffset": {
"x": 569,
"y": 704.2467267515208
}
}

View File

@@ -0,0 +1,269 @@
{
"name": "tree-example-move2",
"description": "",
"nodes": [
{
"id": "1758633408841_o85luvhya",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -60,
"y": -220
},
"parameters": {},
"children": [
"1758633372295_1vww23k1k",
"1758633460046_alqdykjsd",
"1758633637964_a0khi5e5k"
],
"alias": "智能巡逻选择节点"
},
{
"id": "1758633372295_1vww23k1k",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -400,
"y": -120
},
"parameters": {},
"children": [
"1758633506673_f6rvm02zs",
"1758633372295_1vokt067a",
"1758633372295_7vyepkar1",
"1758633372295_86o7jk1k4"
],
"alias": "调查异常"
},
{
"id": "1758633372295_1vokt067a",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -480,
"y": -40
},
"parameters": {},
"children": [],
"alias": "移动到异常位置"
},
{
"id": "1758633372295_7vyepkar1",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -340,
"y": -40
},
"parameters": {},
"children": [],
"alias": "调查"
},
{
"id": "1758633372295_86o7jk1k4",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -200,
"y": -40
},
"parameters": {},
"children": [],
"alias": "返回巡逻路线"
},
{
"id": "1758633460046_alqdykjsd",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 20,
"y": -120
},
"parameters": {},
"children": [
"1758633584586_llol3kpvi",
"1758633460046_l5944c3nc"
],
"alias": "响应呼叫"
},
{
"id": "1758633460046_l5944c3nc",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 80,
"y": -40
},
"parameters": {},
"children": [],
"alias": "前往支援"
},
{
"id": "1758633506673_f6rvm02zs",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -620,
"y": -60
},
"parameters": {},
"children": [],
"alias": "发现异常?"
},
{
"id": "1758633584586_llol3kpvi",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -60,
"y": -60
},
"parameters": {},
"children": [],
"alias": "收到求援信号?"
},
{
"id": "1758633637964_a0khi5e5k",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 360,
"y": -120
},
"parameters": {},
"children": [
"1758633637964_dgyhnjuhl",
"1758633637964_d7uht9tgg",
"1758633637964_qc31zjqo5"
],
"alias": "巡逻"
},
{
"id": "1758633637964_dgyhnjuhl",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 220,
"y": -40
},
"parameters": {},
"children": [],
"alias": "移动到巡逻点"
},
{
"id": "1758633637964_d7uht9tgg",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 360,
"y": -40
},
"parameters": {},
"children": [],
"alias": "环顾四周"
},
{
"id": "1758633637964_qc31zjqo5",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 500,
"y": -40
},
"parameters": {},
"children": [],
"alias": "等待"
}
],
"connections": [
{
"id": "conn_1758633372295_qdmeu2m29",
"sourceNodeId": "1758633372295_1vww23k1k",
"targetNodeId": "1758633372295_1vokt067a",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633372295_myjl0d27a",
"sourceNodeId": "1758633372295_1vww23k1k",
"targetNodeId": "1758633372295_7vyepkar1",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633372295_1ron3sff3",
"sourceNodeId": "1758633372295_1vww23k1k",
"targetNodeId": "1758633372295_86o7jk1k4",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633410470_8lnhy9at6",
"sourceNodeId": "1758633408841_o85luvhya",
"targetNodeId": "1758633372295_1vww23k1k",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633460046_1zy4a0vls",
"sourceNodeId": "1758633460046_alqdykjsd",
"targetNodeId": "1758633460046_l5944c3nc",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633463466_ztkanoztc",
"sourceNodeId": "1758633408841_o85luvhya",
"targetNodeId": "1758633460046_alqdykjsd",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633508904_9pyqismh3",
"sourceNodeId": "1758633372295_1vww23k1k",
"targetNodeId": "1758633506673_f6rvm02zs",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633587533_wh3ccayol",
"sourceNodeId": "1758633460046_alqdykjsd",
"targetNodeId": "1758633584586_llol3kpvi",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633637964_8n9zrweqx",
"sourceNodeId": "1758633637964_a0khi5e5k",
"targetNodeId": "1758633637964_dgyhnjuhl",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633637964_y4rn7rwgc",
"sourceNodeId": "1758633637964_a0khi5e5k",
"targetNodeId": "1758633637964_d7uht9tgg",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633637964_x5ey2s8z7",
"sourceNodeId": "1758633637964_a0khi5e5k",
"targetNodeId": "1758633637964_qc31zjqo5",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758633639995_rdo0y6s9l",
"sourceNodeId": "1758633408841_o85luvhya",
"targetNodeId": "1758633637964_a0khi5e5k",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1.0680104605497773,
"canvasOffset": {
"x": 569,
"y": 513.5
}
}

View File

@@ -0,0 +1,168 @@
{
"name": "tree-example1",
"description": "",
"nodes": [
{
"id": "1758630775717_d1gipfamh",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -60,
"y": -220
},
"parameters": {},
"children": [
"1758630814199_qnitmm2sd",
"1758630832275_prflitgyu",
"1758630967937_2c0t3xi6t"
],
"alias": "根选择节点"
},
{
"id": "1758630814199_qnitmm2sd",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -260,
"y": -120
},
"parameters": {},
"children": [
"1758630875390_e3dlxo1jg",
"1758630940801_u6j12wj96"
],
"alias": "攻击顺序节点"
},
{
"id": "1758630832275_prflitgyu",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": 20,
"y": -120
},
"parameters": {},
"children": [
"1758630915741_ux73zz8ws",
"1758630955525_n0hw99t1q"
],
"alias": "逃跑顺序节点"
},
{
"id": "1758630875390_e3dlxo1jg",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -340,
"y": -60
},
"parameters": {},
"children": [],
"alias": "敌人在附近"
},
{
"id": "1758630915741_ux73zz8ws",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -60,
"y": -60
},
"parameters": {},
"children": [],
"alias": "血量低"
},
{
"id": "1758630940801_u6j12wj96",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -200,
"y": -40
},
"parameters": {},
"children": [],
"alias": "攻击"
},
{
"id": "1758630955525_n0hw99t1q",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 80,
"y": -40
},
"parameters": {},
"children": [],
"alias": "逃跑"
},
{
"id": "1758630967937_2c0t3xi6t",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 220,
"y": -120
},
"parameters": {},
"children": [],
"alias": "巡逻"
}
],
"connections": [
{
"id": "conn_1758630929220_k30loxdah",
"sourceNodeId": "1758630814199_qnitmm2sd",
"targetNodeId": "1758630875390_e3dlxo1jg",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758630930951_5wgaug4ju",
"sourceNodeId": "1758630775717_d1gipfamh",
"targetNodeId": "1758630814199_qnitmm2sd",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758630932626_fz1jivc35",
"sourceNodeId": "1758630775717_d1gipfamh",
"targetNodeId": "1758630832275_prflitgyu",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758630934663_zoq1ugzkq",
"sourceNodeId": "1758630832275_prflitgyu",
"targetNodeId": "1758630915741_ux73zz8ws",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758630951335_f8qdr57vl",
"sourceNodeId": "1758630814199_qnitmm2sd",
"targetNodeId": "1758630940801_u6j12wj96",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758630957361_s28qi8xnd",
"sourceNodeId": "1758630832275_prflitgyu",
"targetNodeId": "1758630955525_n0hw99t1q",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758630973456_60p9k2k07",
"sourceNodeId": "1758630775717_d1gipfamh",
"targetNodeId": "1758630967937_2c0t3xi6t",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1.2507982082066933,
"canvasOffset": {
"x": 465.5,
"y": 644.8338118617028
}
}

View File

@@ -0,0 +1,107 @@
{
"name": "tree-example2",
"description": "",
"nodes": [
{
"id": "1758631669066_247k1fo68",
"className": "Selector",
"name": "选择节点",
"position": {
"x": -60,
"y": -220
},
"parameters": {},
"children": [
"1758631669066_yqo3wjnns",
"1758631669066_g6lvqwonn"
],
"alias": "根选择节点"
},
{
"id": "1758631669066_yqo3wjnns",
"className": "Sequence",
"name": "顺序节点",
"position": {
"x": -120,
"y": -120
},
"parameters": {},
"children": [
"1758631669066_mr87yjkdq",
"1758631669066_e5qqjm0s8"
],
"alias": "攻击顺序节点"
},
{
"id": "1758631669066_mr87yjkdq",
"className": "BTConditionTest",
"name": "测试条件节点",
"position": {
"x": -200,
"y": -60
},
"parameters": {},
"children": [],
"alias": "敌人在附近"
},
{
"id": "1758631669066_e5qqjm0s8",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": -60,
"y": -40
},
"parameters": {},
"children": [],
"alias": "攻击"
},
{
"id": "1758631669066_g6lvqwonn",
"className": "BTTestNode2",
"name": "空行为节点",
"position": {
"x": 80,
"y": -120
},
"parameters": {},
"children": [],
"alias": "巡逻"
}
],
"connections": [
{
"id": "conn_1758631669066_ioakn40wn",
"sourceNodeId": "1758631669066_yqo3wjnns",
"targetNodeId": "1758631669066_mr87yjkdq",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758631669066_x29ua1dz1",
"sourceNodeId": "1758631669066_247k1fo68",
"targetNodeId": "1758631669066_yqo3wjnns",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758631669066_m60t8xsq3",
"sourceNodeId": "1758631669066_yqo3wjnns",
"targetNodeId": "1758631669066_e5qqjm0s8",
"sourcePointType": "child",
"targetPointType": "parent"
},
{
"id": "conn_1758631669066_3zbf492g0",
"sourceNodeId": "1758631669066_247k1fo68",
"targetNodeId": "1758631669066_g6lvqwonn",
"sourcePointType": "child",
"targetPointType": "parent"
}
],
"canvasScale": 1.2507982082066933,
"canvasOffset": {
"x": 465.5,
"y": 644.8338118617028
}
}

252
docs/BehaviorTree.md Normal file
View File

@@ -0,0 +1,252 @@
# 硬核游戏开发 - 使用BehaviorTree实现游戏AI决策的开发详解
## 🎮 一个让策划抓狂的Bug
> "这个BOSS太蠢了它明明看到玩家了为什么还在那里发呆"
这是我在某公司实习时听到最多的一句话。那是一个魔幻RPG项目我负责实现一个"智能"的龙王BOSS。按照策划的设计文档这个BOSS应该能够
- 🔍 **侦察阶段**:在玩家进入领域前巡逻,警戒四周
- ⚔️ **战斗阶段**:发现玩家后立即进入战斗状态,根据距离选择近战或远程攻击
- 🩸 **血怒阶段**血量低于30%时进入狂暴模式,攻击力翻倍
- 🛡️ **防御阶段**:受到大量伤害时短暂防御,恢复少量血量
- 💨 **逃跑阶段**:血量极低时尝试逃跑,寻找掩体
听起来很简单对吧?我天真地用了一堆 `if-else` 语句:
```javascript
function updateBoss() {
if (boss.hp < 0.1 * boss.maxHp) {
if (canEscape()) {
escape();
} else if (canDefend()) {
defend();
} else {
attack();
}
} else if (boss.hp < 0.3 * boss.maxHp) {
if (playerInRange()) {
berserkerAttack();
} else {
moveToPlayer();
}
} else if (playerDetected()) {
if (playerDistance() < 5) {
meleeAttack();
} else {
rangedAttack();
}
} else {
patrol();
}
}
```
**结果?** 一场灾难!
- BOSS经常在攻击和防御之间疯狂切换
- 有时候明明发现了玩家,却突然开始巡逻
- 血怒状态下居然还会尝试逃跑
- 最要命的是:每次策划要求调整优先级,我都要重写整个逻辑!
三个通宵后我的代码变成了一个800行的意大利面条连我自己都看不懂了。更糟糕的是每次修复一个bug就会产生三个新bug。
**直到我遇到了行为树...**
一周后同样的BOSS逻辑我用行为树重新实现了
```
龙王BOSS行为树
根节点(优先选择器)
├── 逃跑分支(血量 < 10%
│ ├── 寻找掩体
│ └── 快速移动
├── 防御分支(受到重击)
│ ├── 播放防御动画
│ └── 恢复少量血量
├── 血怒分支(血量 < 30%
│ ├── 进入狂暴状态
│ └── 疯狂攻击
├── 战斗分支(发现玩家)
│ ├── 距离判断
│ ├── 近战攻击 OR 远程攻击
│ └── 追击玩家
└── 巡逻分支(默认行为)
├── 沿路径移动
└── 警戒四周
```
**奇迹发生了!**
- ✅ BOSS行为逻辑清晰优先级明确
- ✅ 策划可以直接看懂并提出修改意见
- ✅ 新增行为只需要添加新分支,不影响现有逻辑
- ✅ 调试时可以清楚看到每一步的决策过程
- ✅ 代码从800行缩减到200行可读性提升10倍
更重要的是,当策划说"能不能让BOSS在血量50%时召唤小怪"时我只需要在行为树中插入一个新分支5分钟搞定
---
**这就是行为树的魅力。**
作为一名游戏开发者你是否也遇到过类似的问题当游戏中的怪物、NPC需要表现出复杂行为时——巡逻、追击、逃跑、施法、观察环境并做出判断——背后往往不应该是一条又一条 if-else 的堆叠,而是一套清晰、可扩展、可调试的决策框架:**行为树Behavior Tree**。
本指南将带你从零开始认识行为树,让你也能构建出让策划赞不绝口的游戏 AI 决策系统!
## 一、开篇
行为树是一种用于描述 AI 决策逻辑的树形结构由根节点驱动组合节点如「选择器」「序列」负责控制流程装饰节点用于修饰行为叶子节点则执行具体动作或进行条件判断。相较有限状态机FSM行为树更易组合与复用能自然表达“尝试 A 否则 B”“按顺序执行直到成功”等复杂模式并且非常适合可视化编辑与热更新。
## 二、行为树执行流程 - 一个哥布林的日常决策
想象一下,你是一只聪明的哥布林守卫,正在洞穴门口值班。每一秒钟,你的大脑都在运转着一套复杂的决策系统——这就是行为树!
### 1. 三种人生状态(节点状态)
就像人生一样,行为树中的每个节点都只有三种可能的状态:
* **成功** ✅ - "太好了!任务完成!"
* **失败** ❌ - "唉,这条路走不通..."
* **运行中** ⏳ - "别催,我还在努力呢!"
这就像你在思考"今晚吃什么"时的状态:要么想到了(成功),要么放弃了(失败),要么还在纠结中(运行中)。
### 2. 决策节点大家族 - 每个都有自己的性格
#### 2.1 选择节点 - "备胎专家"
**性格特点**永不放弃的乐观主义者总是有Plan B、Plan C...
想象你是个饿肚子的哥布林,面前有三个选择:
1. 去厨房找剩菜
2. 去花园抓虫子
3. 啃树皮充饥
选择节点就像一个不死心的你:
- 先试试厨房有没有剩菜(第一个子节点)
- 如果厨房空空如也(失败),那就去花园抓虫子(第二个子节点)
- 虫子也没有?那就啃树皮吧(第三个子节点)
- 只要有一个成功了,选择节点就满意地说:"搞定!"
**执行规则**
```
从左到右挨个试:
✅ 子节点成功 → "太好了!" → 选择节点成功
❌ 子节点失败 → "下一个!" → 继续尝试
⏳ 子节点运行中 → "等等..." → 选择节点也运行中
```
#### 2.2 顺序节点 - "完美主义者"
**性格特点**:严格按计划执行,一步都不能错
还是那只饿肚子的哥布林,但这次你决定做一顿大餐:
1. 先洗手
2. 然后准备食材
3. 接着开火做饭
4. 最后享用美食
顺序节点就像一个强迫症患者:
- 必须先洗手,洗不干净就不继续
- 洗手成功了,才能准备食材
- 食材准备好了,才能开火
- 任何一步失败,整个计划泡汤!
**执行规则**
```
严格按顺序来:
✅ 子节点成功 → "很好,下一步!" → 继续执行
❌ 子节点失败 → "完蛋了!" → 顺序节点失败
⏳ 子节点运行中 → "慢慢来..." → 顺序节点等待
```
#### 2.3 行为节点 - "实干家"
**性格特点**:话不多说,撸起袖子就是干
这是真正干活的节点,比如:
- "巡逻10秒钟"
- "攻击敌人"
- "播放死亡动画"
行为节点就像一个靠谱的员工,给它一个任务,它会:
- 立即开始执行(返回"运行中"
- 完成后汇报结果("成功"或"失败"
- 有些任务需要时间,会持续返回"运行中"
#### 2.4 条件节点 - "侦察兵"
**性格特点**:眼观六路,耳听八方,专门负责收集情报
条件节点就像哨兵,负责观察环境:
- "敌人在视野内吗?"
- "血量低于30%吗?"
- "身上有钥匙吗?"
它们动作很快,瞬间给出答案:要么"是"(成功),要么"不是"(失败),没有"也许"。
### 3. 一个完整的哥布林决策故事
让我们看看一只哥布林守卫的完整思考过程:
```
哥布林的行为树:
根节点(选择)
├── 战斗分支(顺序)
│ ├── 条件:发现敌人?
│ ├── 行为:冲向敌人
│ └── 行为:攻击
├── 巡逻分支(顺序)
│ ├── 条件:在巡逻路径上?
│ └── 行为:继续巡逻
└── 待机分支
└── 行为:原地等待
```
**执行过程**
1. **第一轮思考**
- 选择节点:"让我看看该做什么..."
- 尝试战斗分支 → 检查"发现敌人?" → 没有敌人(失败)
- 尝试巡逻分支 → 检查"在巡逻路径上?" → 是的(成功)→ 开始巡逻(运行中)
2. **第二轮思考**(巡逻进行中):
- 选择节点:继续之前的决策
- 巡逻分支:巡逻还在进行中...
3. **第三轮思考**(突然发现敌人):
- 选择节点:重新评估
- 尝试战斗分支 → "发现敌人?" → 有敌人!(成功)→ 冲向敌人(运行中)
这就是行为树的魅力:每一帧都在重新评估,动态调整策略,就像一个真正在思考的智能体!
### 4. 可视化流程图 - 让抽象变具体
看完了哥布林的故事,让我们用更直观的方式来理解行为树的执行过程。
#### 4.1 一颗简单的行为树结构
![image](../image/maunal/flow.png)
这就是我们刚才讲的哥布林决策树的可视化版本。每个方块代表一个节点,箭头表示执行流向。
#### 4.2 执行流程的"心跳"
行为树就像一颗跳动的心脏每一帧通常是1/60秒都会从根节点开始"心跳"一次:
![image](../image/maunal/flow2.png)
**执行流程就像这样**
1. **心跳开始** - 从根节点开始
2. **向下探索** - 根据节点类型决定如何执行子节点
3. **状态回传** - 叶子节点的结果层层向上传递
4. **等待下次心跳** - 一帧结束,等待下一帧继续
这种"心跳式"的执行方式让AI能够
- 🔄 **实时响应**:每帧都重新评估环境
- 🎯 **优先级明确**:重要的行为总是先被考虑
- 🔧 **易于调试**:可以清楚看到每一步的决策过程
- 🚀 **性能友好**:只执行必要的节点,避免浪费
> **小贴士**:想象行为树就像一个永不疲倦的大脑,每一瞬间都在问自己:"现在最应该做什么?"然后立即行动!

237
docs/GUI-USED.md Normal file
View File

@@ -0,0 +1,237 @@
# 行为树使用指南
本指南将详细介绍如何使用 kunpocc-behaviortree 库和行为树编辑器。
## 一、开发环境
- 引擎版本Cocos Creator 3.8.6
- 编程语言TypeScript
- 支持引擎版本Cocos Creator 3.7 及之后的所有版本
## 二、安装
1. 安装 kunpocc-behaviortree
```
npm install kunpocc-behaviortree
```
2. 下载扩展插件(bt-editor)
3. 项目脚本中引入库文件
```typescript
// 比如在项目代码目录下添加一个文件 header.ts
// 写上如下代码
import * as BT from "kunpocc-behaviortree";
export { BT };
```
4. 重启creator
5. 启用插件
* 在 Cocos Creator 中选择 `扩展` -> `扩展管理器` -> `已安装扩展`
* 找到 `bt-editor` 并启用
6. 打开扩展面板
* 在 Cocos Creator 顶部菜单栏中选择 `extension or 扩展` -> `kunpo` -> `行为树编辑器`
## 三、编辑器介绍
#### 快捷键
- **打开编辑器**: `Ctrl+Shift+K` (Windows) / `Cmd+Shift+K` (Mac)
- **导出配置**: `Ctrl+Shift+L` (Windows) / `Cmd+Shift+L` (Mac)
#### 菜单访问
在 Cocos Creator 顶部菜单栏中选择 `extension or 扩展` -> `kunpo` -> `行为树编辑器`
### 编辑器功能介绍
行为树编辑器提供了一个直观的可视化界面,让你可以轻松创建和管理复杂的行为树结构。
#### 可视化节点编辑
- **拖拽创建**:从左侧节点库拖拽节点到画布中
- **分组管理**:节点按功能分组显示,便于查找
- **实时预览**:节点显示类型图标和描述信息
#### 属性参数配置
- **类型校验**:支持数字、字符串、布尔值、对象、数组等类型
- **默认值**:自动填充装饰器中定义的默认值
- **约束验证**:支持最小值、最大值、步长等约束条件
#### 连接线管理
- **可视连接**:通过拖拽连接点创建父子关系
- **自动布局**:连接线自动避让,保持界面整洁
- **连接验证**:防止创建非法的节点连接关系
#### 画布操作
- **缩放平移**:鼠标滚轮缩放,拖拽平移画布
- **多选操作**:支持框选多个节点进行批量操作
#### 节点管理
- **别名设置**:为节点设置有意义的别名,便于理解
- **复制粘贴**:快速复制节点及其子树结构
- **删除操作**:删除节点时自动清理相关连接
### 导出文件使用
#### 在项目中使用导出配置
##### 1. 导出文件格式
```json
{
"boss1": [
{
"id": "1758206972710_bhxebhy7o",
"className": "Sequence",
"parameters": {},
"children": [
"1758090634327_mf36nwkdt"
]
},
{
"id": "1758090634327_mf36nwkdt",
"className": "Selector",
"parameters": {},
"children": [
"1758206988178_55b7kk5va"
]
},
{
"id": "1758206988178_55b7kk5va",
"className": "BTAnimation",
"parameters": {
"_name": "",
"_loop": false
},
"children": []
}
]
}
```
##### 2. 配置文件放入项目资源目录
将从编辑器导出的JSON文件放入项目资源目录
自行加载配置数据
```
assets/
├── resources/
│ └── config/
│ ├── bt_config.json // 所有行为树的信息都在这个里边
```
##### 3. 创建行为树实例
```typescript
// entity参数 可以是任意想要关联的类型
let btTree1: BT.INodeConfig[] = this.bt_config.json["bt-tree1"]
this._tree = BT.createBehaviorTree(btTree1, entity);
```
## 四、扩展编辑器节点池
### 节点装饰器
装饰器系统是连接自定义节点和编辑器的桥梁
只有通过装饰器装饰的节点,才能在编辑器中的节点池中显示
* 行为节点装饰器 ***ClassAction***
* 条件节点装饰器 ***ClassCondition***
* 组合节点装饰器 ***ClassComposite***
* 装饰节点装饰器 ***ClassDecorator***
* 属性装饰器 ***prop***
下面我们通过一段示例代码来展示一下装饰器的使用
```typescript
// BT.ClassAction 是行为节点装饰器
// MyNode参数需要和类名相同
@BT.ClassAction("MyNode", { name: "显示名称", group: "节点分组", desc: "节点描述" })
export class MyNode extends BT.LeafNode {
// 基础类型参数装饰器
// type: 参数类型
// description: 参数描述
// defaultValue: 参数默认值
// min: 参数最小值
// max: 参数最大值
// step:
@BT.prop({ type: BT.ParamType.string, description: "动画名称", defaultValue: "idle" })
private animationName: string = "idle";
@BT.prop({ type: BT.ParamType.float, description: "速度", min: 0, max: 10, step: 0.1, defaultValue: 1.0 })
private speed: number = 1.0;
@BT.prop({ type: BT.ParamType.bool, description: "是否循环" })
private loop: boolean = false;
// 对象参数
@BT.prop({
type: BT.ParamType.object,
description: "位置信息",
properties: {
x: { type: BT.ParamType.int, min: 0 },
y: { type: BT.ParamType.int, min: 0 }
}
})
private position: { x: number, y: number };
// 数组参数
@BT.prop({
type: BT.ParamType.array,
description: "巡逻点列表",
itemType: BT.ParamType.object,
itemProperties: {
x: { type: BT.ParamType.float },
y: { type: BT.ParamType.float },
name: { type: BT.ParamType.string }
}
})
private patrolPoints: Array<{ x: number, y: number, name: string }>;
}
```
为节点添加可在编辑器中配置的参数。
#### 参数类型详解
| 类型 | BT.ParamType | 描述 | 支持属性 |
|------|--------------|------|----------|
| 整数 | `int` | 整数类型 | `min`, `max`, `step`, `defaultValue` |
| 浮点数 | `float` | 浮点数类型 | `min`, `max`, `step`, `defaultValue` |
| 字符串 | `string` | 字符串类型 | `defaultValue` |
| 布尔 | `bool` | 布尔类型 | `defaultValue` |
| 对象 | `object` | 对象类型 | `properties` |
| 数组 | `array` | 数组类型 | `itemType`, `itemProperties` |
## 五、更新声明
## 0.0.1 (2025-09-23)
- 首版本
## 六、联系作者
* 邮箱: gong.xinhai@163.com
* 微信: G0900901
* 扫码加微信:
## 七、版权声明
此插件源代码可商业使用
商业授权范围仅限于在您自行开发的游戏作品中使用
不得进行任何形式的转售、租赁、传播等
## 八、购买须知
本产品为付费虚拟商品,一经购买成功概不退款,请在购买前谨慎确认购买内容。

View File

@@ -1,335 +0,0 @@
# 行为树使用指南
![image](../image/bt-gui.png)
本指南将详细介绍如何使用 kunpocc-behaviortree 库和行为树编辑器。
## 一、开发环境
- 引擎版本Cocos Creator 3.8.6
- 编程语言TypeScript
- 支持引擎版本Cocos Creator 3.7+
## 二、安装
1. 安装 kunpocc-behaviortree
```
npm install kunpocc-behaviortree
```
2. 下载扩展插件(bt-editor)
3. 项目脚本中引入库文件
```typescript
// 比如在项目代码目录下添加一个文件 header.ts
// 写上如下代码
import * as BT from "kunpocc-behaviortree";
export { BT };
```
4. 重启creator
5. 启用插件
* 在 Cocos Creator 中选择 `扩展` -> `扩展管理器` -> `已安装扩展`
* 找到 `bt-editor` 并启用
6. 打开扩展面板
* 在 Cocos Creator 顶部菜单栏中选择 `kunpo` -> `行为树编辑器`
7. 创建第一颗行为树 (见下方 `导出文件使用` 部分)
## 三、自定义节点 (扩展编辑器节点池)
### 节点装饰器
装饰器系统是连接自定义节点和编辑器的桥梁
只有通过装饰器装饰的节点,才能在编辑器中的节点池中显示
#### @ClassAction - 行为节点装饰器
用于装饰执行具体逻辑的叶子节点。
```typescript
@BT.ClassAction("NodeName", { name: "显示名称", group: "节点分组", desc: "节点描述" })
export class MyActionNode extends BT.LeafNode {
public tick(): BT.Status {
// 执行逻辑
return BT.Status.SUCCESS;
}
}
```
#### @ClassCondition - 条件节点装饰器
用于装饰判断条件的节点。
```typescript
@BT.ClassCondition("ConditionName", { name: "条件名称", group: "条件分组", desc: "节点描述" })
export class MyCondition extends BT.Condition {
protected isEligible(): boolean {
// 返回判断结果
return true;
}
}
```
#### @ClassComposite - 组合节点装饰器
用于装饰控制子节点执行流程的组合节点。
```typescript
@BT.ClassComposite("CompositeName", { name: "组合名称", group: "组合分组", desc: "节点描述" })
export class MyComposite extends BT.Composite {
public tick(dt: number): BT.Status {
// 控制子节点执行逻辑
for (const child of this.children) {
const status = child._execute(dt);
if (status !== BT.Status.SUCCESS) {
return status;
}
}
return BT.Status.SUCCESS;
}
}
```
#### @ClassDecorator - 装饰节点装饰器
用于装饰修改单个子节点行为的装饰节点。
```typescript
@BT.ClassDecorator("DecoratorName", { name: "装饰名称", group: "装饰分组", desc: "节点描述" })
export class MyDecorator extends BT.Decorator {
public tick(dt: number): BT.Status {
// 装饰逻辑,修改子节点行为
return this.children[0]._execute(dt);
}
}
```
### 节点属性装饰器 (扩展节点参数)
为节点添加可在编辑器中配置的参数。
```typescript
@BT.ClassAction("NodeName", { name: "显示名称", group: "节点分组", desc: "节点描述" })
export class MyNode extends BT.LeafNode {
// 基础类型参数
@BT.prop({ type: BT.ParamType.string, description: "动画名称", defaultValue: "idle" })
private animationName: string = "idle";
@BT.prop({ type: BT.ParamType.float, description: "速度", min: 0, max: 10, step: 0.1, defaultValue: 1.0 })
private speed: number = 1.0;
@BT.prop({ type: BT.ParamType.bool, description: "是否循环" })
private loop: boolean = false;
// 对象参数
@BT.prop({
type: BT.ParamType.object,
description: "位置信息",
properties: {
x: { type: BT.ParamType.int, min: 0 },
y: { type: BT.ParamType.int, min: 0 }
}
})
private position: { x: number, y: number };
// 数组参数
@BT.prop({
type: BT.ParamType.array,
description: "巡逻点列表",
itemType: BT.ParamType.object,
itemProperties: {
x: { type: BT.ParamType.float },
y: { type: BT.ParamType.float },
name: { type: BT.ParamType.string }
}
})
private patrolPoints: Array<{ x: number, y: number, name: string }>;
}
```
#### 参数类型详解
| 类型 | BT.ParamType | 描述 | 支持属性 |
|------|--------------|------|----------|
| 整数 | `int` | 整数类型 | `min`, `max`, `step`, `defaultValue` |
| 浮点数 | `float` | 浮点数类型 | `min`, `max`, `step`, `defaultValue` |
| 字符串 | `string` | 字符串类型 | `defaultValue` |
| 布尔 | `bool` | 布尔类型 | `defaultValue` |
| 对象 | `object` | 对象类型 | `properties` |
| 数组 | `array` | 数组类型 | `itemType`, `itemProperties` |
## 四、编辑器介绍
#### 快捷键
- **打开编辑器**: `Ctrl+Shift+K` (Windows) / `Cmd+Shift+K` (Mac)
- **导出配置**: `Ctrl+Shift+L` (Windows) / `Cmd+Shift+L` (Mac)
#### 菜单访问
在 Cocos Creator 顶部菜单栏中选择 `kunpo` -> `行为树编辑器`
### 编辑器功能介绍
行为树编辑器提供了一个直观的可视化界面,让你可以轻松创建和管理复杂的行为树结构。
#### 核心功能
##### 可视化节点编辑
- **拖拽创建**:从左侧节点库拖拽节点到画布中
- **分组管理**:节点按功能分组显示,便于查找
- **实时预览**:节点显示类型图标和描述信息
##### 属性参数配置
- **智能表单**:根据`@prop`装饰器自动生成配置界面
- **类型校验**:支持数字、字符串、布尔值、对象、数组等类型
- **默认值**:自动填充装饰器中定义的默认值
- **约束验证**:支持最小值、最大值、步长等约束条件
##### 连接线管理
- **可视连接**:通过拖拽连接点创建父子关系
- **自动布局**:连接线自动避让,保持界面整洁
- **连接验证**:防止创建非法的节点连接关系
##### 画布操作
- **缩放平移**:鼠标滚轮缩放,拖拽平移画布
- **多选操作**:支持框选多个节点进行批量操作
##### 节点管理
- **别名设置**:为节点设置有意义的别名,便于理解
- **复制粘贴**:快速复制节点及其子树结构
- **删除操作**:删除节点时自动清理相关连接
##### 编辑器界面布局
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 顶部工具栏 │
│ [设置导出路径] [过滤行为树] [选择行为树▼] [导出配置] │
├─────────────┬─────────────────────────────────────────────┬─────────────────┤
│ │ │ │
│ 节点库 │ │ 右侧面板 │
│ (左侧) │ │ │
│ │ ┌───────────────────────────────────────┐ │ ┌──────────────┐│
│ • 行为节点 │ │ 画布工具栏 │ │ │ 行为树名称 │ │
│ • 条件节点 │ │ [缩放] [重置] [清空] [复制] [粘贴] │ │ │ 行为树描述 │ │
│ • 组合节点 │ └─────────────────────────────────────────┘ │ └──────────────┘ │
│ • 装饰节点 │ │ │
│ • 内置节点 │ ┌─────────────────────────────────────────┐ │ ┌──────────────┐ │
│ │ │ │ │ │ │ │
│ │ │ 画布操作区 │ │ │ 节点参数区 │ │
│ │ │ │ │ │ │ │
│ │ │ ┌─────┐ │ │ │ • 节点名称 │ │
│ │ │ │根节点│ │ │ │ • 参数配置 │ │
│ │ │ └──┬──┘ │ │ │ • 描述信息 │ │
│ │ │ │ │ │ │ • 别名设置 │ │
│ │ │ ┌──▼──┐ ┌──────┐ │ │ │ │ │
│ │ │ │子节点│ │子节点│ │ │ └──────────────┘ │
│ │ │ └─────┘ └──────┘ │ │ │
│ │ │ │ │ ┌──────────────┐ │
│ │ │ │ │ │ [删除行为树] │ │
│ │ └────────────────────────────────────────┘ │ │ [创建新树] │ │
│ │ │ └──────────────┘ │
└────────────┴──────────────────────────────────────────────┴──────────────────┘
```
### 导出文件使用
#### 在项目中使用导出配置
##### 1. 配置文件格式
```json
{
"boss1": [
{
"id": "1758206972710_bhxebhy7o",
"className": "Sequence",
"parameters": {},
"children": [
"1758090634327_mf36nwkdt"
]
},
{
"id": "1758090634327_mf36nwkdt",
"className": "Selector",
"parameters": {},
"children": [
"1758206988178_55b7kk5va"
]
},
{
"id": "1758206988178_55b7kk5va",
"className": "BTAnimation",
"parameters": {
"_name": "",
"_loop": false
},
"children": []
}
]
}
```
##### 2. 配置文件放入项目资源目录
将从编辑器导出的JSON文件放入项目资源目录
自行加载配置数据
```
assets/
├── resources/
│ └── config/
│ ├── bt_config.json // 所有行为树的信息都在这个里边
```
##### 3. 创建行为树实例
* BT.createBehaviorTree(config["boss1"], entity);
* 函数详解
```typescript
// 工厂函数签名
function createBehaviorTree<T>(config: INodeConfig[], entity: T): BehaviorTree<T>
// 内部工作流程:
// 1. 验证配置格式
// 2. 创建节点映射表 (id -> config)
// 3. 递归创建节点树
// - 通过className查找构造函数
// - 根据节点类型选择创建方式
// - 设置节点参数
// - 建立父子关系
// 4. 返回行为树实例
```
## 五、更新声明
## 0.0.1 (2025-09-23)
- 首版本
## 六、联系作者
* 邮箱: gong.xinhai@163.com
* 微信: G0900901
* 扫码加微信:
## 七、版权声明
此插件源代码可商业使用
商业授权范围仅限于在您自行开发的游戏作品中使用
不得进行任何形式的转售、租赁、传播等
## 八、购买须知
本产品为付费虚拟商品,一经购买成功概不退款,请在购买前谨慎确认购买内容。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

BIN
image/maunal/extension.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
image/maunal/flow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

BIN
image/maunal/flow2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

BIN
image/maunal/scene.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB