#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime.Tasks.Conditionals { using Opsive.GraphDesigner.Runtime; using Opsive.GraphDesigner.Runtime.Variables; using Opsive.Shared.Events; using UnityEngine; /// /// A TaskObject implementation of the Conditional task. This class can be used when the task should not be grouped by the StackedConditional task. /// [NodeIcon("e6fc90c130121da4f9067b5e15b02975", "69959064b54a0cb4cb077dbb6967a3e1")] [NodeDescription("Returns success as soon as the event specified by eventName has been received.")] public class HasReceivedEvent : TargetBehaviorTreeConditional { [Tooltip("The name of the event that should be registered.")] [SerializeField] protected SharedVariable m_EventName; [Tooltip("Is the event a global event?")] [SerializeField] protected SharedVariable m_GlobalEvent; [Tooltip("Optionally store the first sent argument.")] [RequireShared] [SerializeField] protected SharedVariable m_StoredValue1; [Tooltip("Optionally store the second sent argument.")] [RequireShared] [SerializeField] protected SharedVariable m_StoredValue2; [Tooltip("Optionally store the third sent argument.")] [RequireShared] [SerializeField] protected SharedVariable m_StoredValue3; private string m_RegisteredEventName; private bool m_EventRegistered; private bool m_EventReceived; /// /// The behavior tree has started. /// public override void OnBehaviorTreeStarted() { base.OnBehaviorTreeStarted(); RegisterEvents(); } /// /// Initializes the target behavior tree. /// protected override void InitializeTarget() { if (m_ResolvedBehaviorTree != null) { UnregisterEvents(); } base.InitializeTarget(); RegisterEvents(); } /// /// Registers for the events. /// private void RegisterEvents() { if (m_EventRegistered) { return; } if (string.IsNullOrEmpty(m_EventName.Value)) { Debug.LogError("Error: Unable to receive event. The event name is empty."); return; } if (m_StoredValue1 == null || !m_StoredValue1.IsShared) { if (m_GlobalEvent.Value) { EventHandler.RegisterEvent(m_EventName.Value, ReceivedEvent); } else { EventHandler.RegisterEvent(m_ResolvedBehaviorTree, m_EventName.Value, ReceivedEvent); } } else { if (m_StoredValue2 == null || !m_StoredValue2.IsShared) { if (m_GlobalEvent.Value) { EventHandler.RegisterEvent(m_EventName.Value, ReceivedEvent); } else { EventHandler.RegisterEvent(m_ResolvedBehaviorTree, m_EventName.Value, ReceivedEvent); } } else { if (m_StoredValue3 == null || !m_StoredValue3.IsShared) { if (m_GlobalEvent.Value) { EventHandler.RegisterEvent(m_EventName.Value, ReceivedEvent); } else { EventHandler.RegisterEvent(m_ResolvedBehaviorTree, m_EventName.Value, ReceivedEvent); } } else { if (m_GlobalEvent.Value) { EventHandler.RegisterEvent(m_EventName.Value, ReceivedEvent); } else { EventHandler.RegisterEvent(m_ResolvedBehaviorTree, m_EventName.Value, ReceivedEvent); } } } } m_EventName.OnValueChange += UpdateEvents; if (m_StoredValue1 != null) { m_StoredValue1.OnValueChange += UpdateEvents; } if (m_StoredValue2 != null) { m_StoredValue2.OnValueChange += UpdateEvents; } if (m_StoredValue3 != null) { m_StoredValue3.OnValueChange += UpdateEvents; } m_EventRegistered = true; m_RegisteredEventName = m_EventName.Value; } /// /// The event name or parameter count has changed. Update the events. /// private void UpdateEvents() { UnregisterEvents(); RegisterEvents(); } /// /// A parameterless event has been recevied. /// private void ReceivedEvent() { // The task has to be reevaluated in order for the event to be received. if (!IsReevaluating()) { return; } m_EventReceived = true; } /// /// A single parameter event has been received. /// /// The first parameter. private void ReceivedEvent(object arg1) { // The task has to be reevaluated in order for the event to be received. if (!IsReevaluating()) { return; } m_EventReceived = true; if (m_StoredValue1 != null && m_StoredValue1.IsShared) { m_StoredValue1.SetValue(arg1); } } /// /// A two parameter event has been received. /// /// The first parameter. /// The second parameter. private void ReceivedEvent(object arg1, object arg2) { // The task has to be reevaluated in order for the event to be received. if (!IsReevaluating()) { return; } m_EventReceived = true; if (m_StoredValue1 != null && m_StoredValue1.IsShared) { m_StoredValue1.SetValue(arg1); } if (m_StoredValue2 != null && m_StoredValue2.IsShared) { m_StoredValue2.SetValue(arg2); } } /// /// A three parameter event has been received. /// /// The first parameter. /// The second parameter. /// The third parameter. private void ReceivedEvent(object arg1, object arg2, object arg3) { // The task has to be reevaluated in order for the event to be received. if (!IsReevaluating()) { return; } m_EventReceived = true; if (m_StoredValue1 != null && m_StoredValue1.IsShared) { m_StoredValue1.SetValue(arg1); } if (m_StoredValue2 != null && m_StoredValue2.IsShared) { m_StoredValue2.SetValue(arg2); } if (m_StoredValue3 != null && m_StoredValue3.IsShared) { m_StoredValue3.SetValue(arg3); } } /// /// The task has been updated. /// /// True if an event has been received. public override TaskStatus OnUpdate() { if (string.IsNullOrEmpty(m_EventName.Value)) { return TaskStatus.Failure; } return m_EventReceived ? TaskStatus.Success : TaskStatus.Failure; } /// /// The task has ended. /// public override void OnEnd() { base.OnEnd(); m_EventReceived = false; } /// /// The behavior tree has been stopped. /// /// Is the behavior tree paused? public override void OnBehaviorTreeStopped(bool paused) { base.OnBehaviorTreeStopped(paused); UnregisterEvents(); m_EventReceived = false; } /// /// Unregisters for the events that were registered. /// private void UnregisterEvents() { // The events must be registered first in order to be unregistered. if (string.IsNullOrEmpty(m_RegisteredEventName)) { return; } // Unregister from all parameters. This will ensure no events are subscribed if the parameters change. if (m_GlobalEvent.Value) { EventHandler.UnregisterEvent(m_RegisteredEventName, ReceivedEvent); EventHandler.UnregisterEvent(m_RegisteredEventName, ReceivedEvent); EventHandler.UnregisterEvent(m_RegisteredEventName, ReceivedEvent); EventHandler.UnregisterEvent(m_RegisteredEventName, ReceivedEvent); } else { EventHandler.UnregisterEvent(m_ResolvedBehaviorTree, m_RegisteredEventName, ReceivedEvent); EventHandler.UnregisterEvent(m_ResolvedBehaviorTree, m_RegisteredEventName, ReceivedEvent); EventHandler.UnregisterEvent(m_ResolvedBehaviorTree, m_RegisteredEventName, ReceivedEvent); EventHandler.UnregisterEvent(m_ResolvedBehaviorTree, m_RegisteredEventName, ReceivedEvent); } m_EventName.OnValueChange -= UpdateEvents; if (m_StoredValue1 != null) { m_StoredValue1.OnValueChange -= UpdateEvents; } if (m_StoredValue2 != null) { m_StoredValue2.OnValueChange -= UpdateEvents; } if (m_StoredValue3 != null) { m_StoredValue3.OnValueChange -= UpdateEvents; } m_EventRegistered = false; m_RegisteredEventName = string.Empty; } } } #endif