2025-10-03 00:31:34 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
|
|
namespace AI
|
|
|
|
|
|
{
|
|
|
|
|
|
public abstract class LeafNodeBase : BehaviorTreeBase
|
|
|
|
|
|
{
|
|
|
|
|
|
// 已经运行的帧数
|
|
|
|
|
|
protected int _elapsedFrames;
|
2025-10-10 14:08:23 +08:00
|
|
|
|
|
2025-10-03 00:31:34 +08:00
|
|
|
|
// 默认超时帧数
|
2025-10-10 14:08:23 +08:00
|
|
|
|
protected int _timeoutFrames = 180;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// 获取或设置该叶节点的超时帧数。确保超时帧数至少为1。
|
2025-10-03 00:31:34 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int TimeoutFrames
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _timeoutFrames;
|
|
|
|
|
|
set => _timeoutFrames = Math.Max(1, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 剩余帧数
|
|
|
|
|
|
public int RemainingFrames => TimeoutFrames - _elapsedFrames;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// 抽象方法,由具体的叶节点实现其核心业务逻辑。
|
|
|
|
|
|
/// <see cref="LeafNodeBase" /> 会在计时器管理后调用此方法。
|
2025-10-03 00:31:34 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>节点的执行状态(Running, Success, Failure)。</returns>
|
|
|
|
|
|
protected abstract Status ExecuteLeafLogic();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// <see cref="LeafNodeBase" /> 的 Tick 方法,包含了计时器和状态管理逻辑。
|
|
|
|
|
|
/// 此方法被密封,子类应实现 <see cref="ExecuteLeafLogic" /> 而不是重写 Tick。
|
2025-10-03 00:31:34 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public sealed override Status Tick()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (CurrentStatus == Status.Ready)
|
|
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
CurrentStatus = Status.Running;
|
|
|
|
|
|
_elapsedFrames = 0;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (CurrentStatus == Status.Running)
|
|
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
_elapsedFrames++;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
|
|
|
|
|
|
if (_elapsedFrames > _timeoutFrames)
|
|
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
CurrentStatus = Status.Failure;
|
|
|
|
|
|
Reset();
|
2025-10-03 00:31:34 +08:00
|
|
|
|
return Status.Failure;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var logicResult = ExecuteLeafLogic();
|
|
|
|
|
|
|
|
|
|
|
|
if (logicResult != Status.Running)
|
|
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
CurrentStatus = logicResult;
|
|
|
|
|
|
Reset();
|
2025-10-03 00:31:34 +08:00
|
|
|
|
}
|
2025-10-10 14:08:23 +08:00
|
|
|
|
|
2025-10-03 00:31:34 +08:00
|
|
|
|
return logicResult;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return CurrentStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// 重置叶节点的状态,包括基类状态和内部计时器。
|
2025-10-03 00:31:34 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public override void Reset()
|
|
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
base.Reset();
|
|
|
|
|
|
_elapsedFrames = 0;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-10 14:08:23 +08:00
|
|
|
|
}
|