行为树

==
AI




有限状态机(FSM),分层有限状态机(HFSM),决策树(Decision Tree),行为树(Behavior Tree)

======
有限状态机(FSM)

//输入一个字符 从当前状态转移到下一个状态
//一个6*6的表。

//竖为当前状态
//横为下一状态
//表里面的值为条件

//new 6个state状态,然后对里面的dic字典赋值
//字典的key 为输入的字符,value 为对应的输出状态
//

const int range = CHAR_MAX + 1;

class State
{
public:
    State();
    State* transition[range];
};

struct TransGraph   // use triple to describe map
{
    int current_state;
    char input_char;
    int next_state;
};

//使用前先填充所有key 和value

    static TransGraph graph[] =
    {
        {1, 'A', 2}, {1, 'B', 3}, {1, 'C', 4}, {1, 'D', 5},
        {2, 'E', 2}, {2, 'I', 0},
        {3, 'F', 3}, {3, 'J', 0}, {3, 'M', 4},
        {4, 'G', 4}, {4, 'K', 0},
        {5, 'H', 5}, {5, 'L', 0}, {5, 'O', 2}, {5, 'N', 4},
        {0, 0, 0}
    };

    for (TransGraph* p_tg = graph; p_tg->current_state != 0; ++p_tg)
        state[p_tg->current_state].transition[p_tg->input_char] = &state[p_tg->next_state];

//输入一个值获取下一个值

void Fsm::Advance(char c)
{
    if (p_current != NULL)
        p_current = p_current->transition[c];
}




//Simple Finite State Machine – Unity3d (C#)
初始化的时候根据类的方法命名绑定所有方法
然后切换状态

如果需要根据输入来切换就要定义一个另外的方法
只根据输入来切换状态









====
分层有限状态机(HFSM)

//因为有的时候源状态一样 。输入一样。但是输出不一样

1. 每个状态都是一个类,他们继承于一个公共类,其包含进入,退出,处理事件的虚方法;
2. 状态机有一个状态堆栈,这里使用List来实现;
3. 状态机初始化时有一个初始状态,一般为idle状态,其成为堆栈的第一个元素;
4. 状态转移分为3种情况:a 进入目标状态,b 退出当前状态,c 切换到目标状态(即先退出当前状态,再进入目标状态);
5. 当前有效的状态就是状态堆栈里面栈顶的那个状态,即:_smList[0];


//另外一种解释
简单来说,就是FSM当状态太多的时候,不好维护,于是将状态分类,抽离出来,将同类型的
状态做为一个状态机,然后再做一个大的状态机,来维护这些子状态机。





====
行为树

它只有4大类型的Node:
* Composite Node  组合节点
* Decorator Node   修饰节点
* Condition Node   条件节点(叶节点)
* Action Node    动作节点(叶节点)

任何Node被执行后,必须向其Parent Node报告执行结果:成功 / 失败。
这简单的成功 / 失败汇报原则被很巧妙地用于控制整棵树的决策方向。

———————————————————————

先看 组合节点Composite Node,其实它按复合性质还可以细分为4种:

1 Selector Node  选择节点/优先选择节点
当执行本类型Node时,它将从begin到end迭代执行自己的Child Node:
如遇到一个Child Node执行后返回True,那停止迭代,
本Node向自己的Parent Node也返回True;否则所有Child Node都返回False,
那本Node向自己的Parent Node返回False。

2 Sequence Node  顺序节点
当执行本类型Node时,它将从begin到end迭代执行自己的Child Node:
如遇到一个Child Node执行后返回False,那停止迭代,
本Node向自己的Parent Node也返回False;否则所有Child Node都返回True,
那本Node向自己的Parent Node返回True。

3 Parallel Node  并行节点
并发执行它的所有Child Node。
而向Parent Node返回的值和Parallel Node所采取的具体策略相关:
Parallel Selector Node: 一False则返回False,全True才返回True。
Parallel Sequence Node: 一True则返回True,全False才返回False。
Parallel Hybird Node: 指定数量的Child Node返回True或False后才决定结果。
不需要像Selector/Sequence那样预判哪个Child Node应摆前,哪个应摆后,
常见情况是:
(1)用于并行多棵Action子树。
(2)在Parallel Node下挂一棵子树,并挂上多个Condition Node,
以提供实时性和性能。

4 Decorator  修饰节点
Until Success和Until Failure
循环执行子节点,直到返回“成功”或“失败”为止
Limit
执行子节点一定次数后强制返回“失败”
Time
子节点不会立即执行,而会在指定的时间到达后才开始执行。
TimeLimit
指定子节点的最长运行时间,如果子节点在指定时间到达后还在运行则强制返回“失败”
Invert
对子节点的返回结果取“非”,即子节点返回“成功”则该节点返回“失败”,子节点返回“失败”则该节点返回成功


叶节点
1条件节点(Condition)
2行为节点(Action)


把tick 作为一个变量
每次调用update函数的时候
从上往下传递同一个tick

所有节点继承basenode
basenode包含子列表,唯一id

https://github.com/chenjd/TTBT-Framework


剑雨state
actionstate
分为 A B C D E F
每个对应的actionstate里面有不同的can
分为 1 2 3 4 5 6 和 cur

基本上是1对应canA

每次转换之前把上一个的cur 设置为false
当前的cur设置为true

1 2 3 4 5 6 通过2倍处理来实现,然后叠加。可以获取能否转换为某个状态

防锁死处理。增加时间deadline



====
https://github.com/Tencent/behaviac
==
unity Behavior Designer

猜你喜欢

转载自blog.csdn.net/a133900029/article/details/80184256