行为树新增StepSequence

Post a reply

Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :arrow: :| :mrgreen: :geek: :ugeek:

BBCode is ON
[img] is ON
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: 行为树新增StepSequence

Re: 行为树新增StepSequence

by caitsithware » 2024/09/13 08:27

我忘记用 OnDeactivated 停止执行。
修改后的脚本如下。

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LogicToolkit;

[System.Serializable]
public class StepTask : TaskComponent, IPauseReceiver
{
    [SerializeField]
    [FieldPlacement(FieldPlacement.Top)]
    private List<OutputExecutePort> _Steps;

    private int _Index;
    private OutputExecutePort _Current;
    private TaskStatus _TaskStatus;

    protected override void OnActivated()
    {
        _Current = _Steps[_Index];

        _TaskStatus = TaskStatus.Running;
        if (_Current == null || !_Current.Play(OnExit))
        {
            _TaskStatus = TaskStatus.Failure;
        }
    }

    bool OnExit(OutputExecutePort execute, FlowExitNode exitNode)
    {
        _Index = (_Index + 1) % _Steps.Count;

        if (exitNode == null
            || exitNode is ExitNode)
        {
            _TaskStatus = TaskStatus.Success;
            return true;
        }

        return false;
    }

    protected override TaskStatus OnExecute()
    {
        _Current?.Update();

        return _TaskStatus;
    }

    protected override void OnDeactivated()
    {
        base.OnDeactivated();

        _Current?.Stop();
    }

    void IPauseReceiver.OnPause(bool pause)
    {
        if (pause)
        {
            _Current?.Pause();
        }
        else
        {
            _Current?.Resume();
        }
    }
}

Re: 行为树新增StepSequence

by caitsithware » 2024/09/13 08:16

这是由于 Unity 内部规范造成的问题。
“当 Foldout 关闭时,不会构建内部 UI,因此你不知道 Foldout 内部的电线连接在哪里。”
如果展开它,将显示端口,您可以确认它已连接。
我创建了一个编辑器扩展,以便 Foldout 不用于 If 节点等内容。
我们还将考虑将此编辑器扩展用于用户脚本。

Re: 行为树新增StepSequence

by kvfreedom » 2024/09/13 07:53

caitsithware wrote: 2024/09/04 13:54 您可以使用 OutputExecutePort 创建一个 TaskComponent。
例如,创建如下所示的脚本。

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LogicToolkit;

[System.Serializable]
public class StepTask : TaskComponent, IPauseReceiver
{
    [SerializeField]
    [FieldPlacement(FieldPlacement.Top)]
    private List<OutputExecutePort> _Steps;

    private int _Index;
    private OutputExecutePort _Current;
    private TaskStatus _TaskStatus;

    protected override void OnActivated()
    {
        _Current = _Steps[_Index];

        _TaskStatus = TaskStatus.Running;
        if (_Current == null || !_Current.Play(OnExit))
        {
            _TaskStatus = TaskStatus.Failure;
        }
    }

    bool OnExit(OutputExecutePort execute, FlowExitNode exitNode)
    {
        _Index = (_Index + 1) % _Steps.Count;

        if (exitNode == null
            || exitNode is ExitNode)
        {
            _TaskStatus = TaskStatus.Success;
            return true;
        }

        return false;
    }

    protected override TaskStatus OnExecute()
    {
        _Current?.Update();

        return _TaskStatus;
    }

    void IPauseReceiver.OnPause(bool pause)
    {
        if (pause)
        {
            _Current?.Pause();
        }
        else
        {
            _Current?.Resume();
        }
    }
}
StepTask.png
1.png
1.png (12.13 KiB) Viewed 14820 times
3.png
3.png (9.92 KiB) Viewed 14820 times
2.png
2.png (10.86 KiB) Viewed 14820 times
收起Steps列表,关闭Logic编辑器再打开Logic编辑器,会显示连线错误

Re: 行为树新增StepSequence

by kvfreedom » 2024/09/04 14:13

caitsithware wrote: 2024/09/04 13:54 您可以使用 OutputExecutePort 创建一个 TaskComponent。
自己写一个StepTask可能是不错的方式,如果父节点是一个行为树节点,似乎只需要再加一个ExecuteTask就可以了

Re: 行为树新增StepSequence

by caitsithware » 2024/09/04 13:59

主要问题是该图没有显示该组件维护其子节点的执行索引。
组件的复杂性也会根据是否中途重置而增加。
目前,请创建您自己的脚本来处理该问题。

Re: 行为树新增StepSequence

by caitsithware » 2024/09/04 13:54

您可以使用 OutputExecutePort 创建一个 TaskComponent。
例如,创建如下所示的脚本。

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LogicToolkit;

[System.Serializable]
public class StepTask : TaskComponent, IPauseReceiver
{
    [SerializeField]
    [FieldPlacement(FieldPlacement.Top)]
    private List<OutputExecutePort> _Steps;

    private int _Index;
    private OutputExecutePort _Current;
    private TaskStatus _TaskStatus;

    protected override void OnActivated()
    {
        _Current = _Steps[_Index];

        _TaskStatus = TaskStatus.Running;
        if (_Current == null || !_Current.Play(OnExit))
        {
            _TaskStatus = TaskStatus.Failure;
        }
    }

    bool OnExit(OutputExecutePort execute, FlowExitNode exitNode)
    {
        _Index = (_Index + 1) % _Steps.Count;

        if (exitNode == null
            || exitNode is ExitNode)
        {
            _TaskStatus = TaskStatus.Success;
            return true;
        }

        return false;
    }

    protected override TaskStatus OnExecute()
    {
        _Current?.Update();

        return _TaskStatus;
    }

    void IPauseReceiver.OnPause(bool pause)
    {
        if (pause)
        {
            _Current?.Pause();
        }
        else
        {
            _Current?.Resume();
        }
    }
}
StepTask.png
StepTask.png (55.86 KiB) Viewed 16280 times

Re: 行为树新增StepSequence

by kvfreedom » 2024/09/04 13:19

caitsithware wrote: 2024/09/04 11:55 该提案将取决于“自己节点的父节点”来确定如何执行“自己节点的子节点”,从而使行为树不那么通用。
首先请重新考虑一下是否有必要使用行为树。
1.png
1.png (180.82 KiB) Viewed 16295 times
StepSequence似乎并不需要“自己节点的父节点”来确定如何执行“自己节点的子节点”,StepSequence只需要记录一个Index,就可以判断需要执行哪一个子节点。
如图上的方式来实现,节点会比较多。StepSequence确实没有Sequence和Selector那么常用,最初我准备自己实现StepSequence,但是发现CompositeComponent是internal。

Re: 行为树新增StepSequence

by caitsithware » 2024/09/04 11:55

该提案将取决于“自己节点的父节点”来确定如何执行“自己节点的子节点”,从而使行为树不那么通用。
首先请重新考虑一下是否有必要使用行为树。

行为树新增StepSequence

by kvfreedom » 2024/09/04 11:20

1.png
1.png (76.09 KiB) Viewed 16304 times
希望行为树新增StepSequence,如图例可以实现输出"a" "b1" "a" "b2" "a" "b1"

Top