kanzi状态机插件

kanzi自带的状态机功能有限,做了一个插件拓展其功能

1. 起因

kanzi通过绑定输入值,控制状态机的状态切换。
如果期望输入值0->1,
动画如下:

请添加图片描述
1->0动画,
动画如下:
请添加图片描述

kanzi自带的状态机无法实现,因为这本质是3个状态。

而kanzi自带状态机实现完效果如下:
不满足特殊要求
请添加图片描述

2. 插件设计

2.1插件属性

  1. InputIntValueProperty用于绑定输入值,方便插件根据输入值设置状态
  2. InputStateValueProperty是字符串数组,代表输入值影响状态的规则
  3. IdleStateValueProperty初始化状态,用于规则不匹配的情况下默认状态

2.2 kanzi使用

在这里插入图片描述
根据2.1的说明,我们在kanzi中使用插件

  • 绑定处优化处理,因为0会反复触发,影响对属性的判定,我们这里把输入值优化为1-2区间
{@../Untitled11gear.NewPropertyTypeTest}+1
  • 规则设置为,
    • 输入值从1-》2,状态先立刻切换到状态1,在按动画效果切换到状态2
    • 输入值从2-》1,状态先立刻切换到状态2,在按动画效果切换到状态3
      在这里插入图片描述
      这样通过3个状态达到目的效果,而且动画具备打断效果。

注意:状态机不能有控制属性
在这里插入图片描述

3. 代码实现

3.1 属性声明

在这里插入图片描述
InputStateValueProperty比较特殊,是数组类型

解析时候
InputStateValueProperty=0|1->2,State1->State2|2->1,State2->State3
根据|把字符串切割即可得到每一条规则
再根据->把数据提取为StateInfo

typedef struct  
{
    int startIndex;
    int endIndex;
    std::string startState;
    std::string endState;
}StateInfo;

3.2 切换状态

根据InputIntValuePropertylastValue逻辑,去遍历数组,匹配StateInfo
匹配后调用apigoToState切换状态。

int len = m_StateInfos.size();
    for (int i = 0; i < len; i++) {
        const StateInfo info = m_StateInfos[i];
        if (info.startIndex == m_lastIntValue && info.endIndex == value) {
            stateManagerPtr->goToState((Node*)(this), "StateGroup", info.startState, true);
            stateManagerPtr->goToState((Node*)(this), "StateGroup", info.endState, false);
            kzLogDebug(("{} info: {} ->{}", getName(),  info.startState, info.endState));
            break;
        }
        //kzLogDebug(("info: {} ->{}", info.startIndex, info.endIndex));
        if (i == len - 1) {
            kzLogDebug(("{} error: {} ->{} = {}", getName(), m_lastIntValue, value, getProperty(IdleStateValueProperty)));
            stateManagerPtr->goToState((Node*)(this), "StateGroup", getProperty(IdleStateValueProperty), false);
        }
    }

3.3 初始化状态

一般第一个输入值是不需要做动画的,为了达到目的,插件的做法是提供默认状态IdleStateValueProperty,在遍历规则时候提供容错

stateManagerPtr->goToState((Node*)(this), "StateGroup", getProperty(IdleStateValueProperty), false);

实际操作发现问题,onNodePropertyChanged触发时机比onAttached
为此补充规则
在这里插入图片描述
在这里插入图片描述
时序解释

  1. 运行后先触发容错,PluginStateManager error: 0 ->2 = State2,因为没有节点加载完成,状态没有切换过去,等加载完成,触发状态动画,导致第一个输入值有动画
  2. onAttached时候重新触发规则,满足2->2,State2->State2,达成 PluginStateManager info: State2 ->State2,实现无动画。

4. 优化

如果有多条类似规则,一条条创建过于麻烦,优化后变成一条。
在这里插入图片描述
比如输入值0,1->1,都符合同一个状态切换,可以写入一行。

  • @ 用于切割前后端
  • , 用于查找匹配多个值
  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值