81 lines
2.9 KiB
C#
81 lines
2.9 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|