Files
Cielonos/Assets/Opsive/BehaviorDesigner/Add-Ons/CielonosPack/Conditionals/HasReceivedContextEvent.cs

81 lines
2.9 KiB
C#
Raw Normal View History

2026-03-20 12:07:44 -04:00
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.GraphDesigner.Runtime;
using Opsive.Shared.Utility;
using UnityEngine;
namespace Cielonos.MainGame.Characters.AI
{
[Description("检查 AI 是否在近期收到了特定的上下文事件。极度稳定完美支持BD下沉式条件打断(Conditional Aborts)。")]
[NodeIcon("e6fc90c130121da4f9067b5e15b02975", "69959064b54a0cb4cb077dbb6967a3e1")]
[Category("Cielonos/Events")]
public class HasReceivedContextEvent : AutomataConditionalBase
{
[Tooltip("订阅的事件名称")]
public SharedVariable<string> eventName;
[Tooltip("事件判定的有效窗口期(秒)。超出此时长的事件将被视为过期无视。")]
public float validWindow = 0.2f;
[RequireShared] public SharedVariable storedValue1;
[RequireShared] public SharedVariable storedValue2;
[RequireShared] public SharedVariable storedValue3;
public override void OnStart()
{
base.OnStart();
if (behaviorSc != null && behaviorSc.EventMemory.TryGetValue(eventName.Value, out var e))
{
if (!e.IsValid(validWindow))
{
// 如果在条件开始时就已经有事件了,但它已经过期了,那就直接丢掉它,免得后续一直误触发。
behaviorSc.EventMemory.Remove(eventName.Value);
}
}
}
public override TaskStatus OnUpdate()
{
if (Evaluate(out BehaviorSubcontroller.AutomataEvent e))
{
TryAssignValues(e);
behaviorSc.EventMemory.Remove(eventName.Value);
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
public override TaskStatus OnReevaluateUpdate()
{
return Evaluate(out _) ? TaskStatus.Success : TaskStatus.Failure;
}
private bool Evaluate(out BehaviorSubcontroller.AutomataEvent e)
{
if (behaviorSc == null || string.IsNullOrEmpty(eventName.Value))
{
e = null;
return false;
}
if (behaviorSc.EventMemory.TryGetValue(eventName.Value, out e))
{
if (e.IsValid(validWindow))
{
return true;
}
}
return false;
}
private void TryAssignValues(BehaviorSubcontroller.AutomataEvent e)
{
if (storedValue1 != null && storedValue1.IsShared) storedValue1.SetValue(e.Arg1);
if (storedValue2 != null && storedValue2.IsShared) storedValue2.SetValue(e.Arg2);
if (storedValue3 != null && storedValue3.IsShared) storedValue3.SetValue(e.Arg3);
}
}
}