#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime.Tasks { using Opsive.BehaviorDesigner.Runtime.Systems; using Opsive.GraphDesigner.Runtime.Variables; using Opsive.Shared.Utility; using System.Collections.Generic; using Unity.Entities; using UnityEngine; using static Opsive.BehaviorDesigner.Runtime.BehaviorTreeData; /// /// The base class for a Mono task. /// public abstract class Task : ISavableTask { protected GameObject m_GameObject; protected Transform m_Transform; protected BehaviorTree m_BehaviorTree; protected ushort m_RuntimeIndex; protected virtual GameObject gameObject { get => m_GameObject; } protected virtual Transform transform { get => m_Transform; } private TaskStatus m_Status; internal TaskStatus Status { get => m_Status; set => m_Status = value; } /// /// Adds the task to the behavior tree buffer. /// /// The world that the task runs in. /// The entity that the task is connected to. /// The ID of the behavior tree running the task. /// The index of the task. public virtual void AddBufferElement(World world, Entity entity, int behaviorTreeID, ushort index) { DynamicBuffer buffer; if (world.EntityManager.HasBuffer(entity)) { buffer = world.EntityManager.GetBuffer(entity); } else { buffer = world.EntityManager.AddBuffer(entity); } buffer.Add(new TaskObjectComponent() { Index = index, }); } /// /// Clears all component buffers from the behavior tree buffer. /// /// The world that the task runs in. /// The entity that the task is connected to. public virtual void ClearBufferElement(World world, Entity entity) { DynamicBuffer buffer; if (world.EntityManager.HasBuffer(entity)) { buffer = world.EntityManager.GetBuffer(entity); buffer.Clear(); } } /// /// Resets the task values back to their default. /// public virtual void Reset() { } /// /// Initializes the base task parameters. /// /// A reference to the owning BehaviorTree. /// The runtime index of the node. internal virtual void Initialize(BehaviorTree behaviorTree, ushort runtimeIndex) { if (!Application.isPlaying) { return; } m_BehaviorTree = behaviorTree; m_GameObject = m_BehaviorTree.gameObject; m_Transform = m_BehaviorTree.transform; m_RuntimeIndex = runtimeIndex; m_BehaviorTree.OnBehaviorTreeStarted += OnBehaviorTreeStarted; m_BehaviorTree.OnBehaviorTreeStopped += OnBehaviorTreeStopped; m_BehaviorTree.OnBehaviorTreeDestroyed += OnDestroy; if (ReceiveCollisionEnterCallback) { m_BehaviorTree.OnBehaviorTreeCollisionEnter += OnCollisionEnter; } if (ReceiveCollisionExitCallback) { m_BehaviorTree.OnBehaviorTreeCollisionExit += OnCollisionExit; } if (ReceiveCollisionEnter2DCallback) { m_BehaviorTree.OnBehaviorTreeCollisionEnter2D += OnCollisionEnter2D; } if (ReceiveCollisionExit2DCallback) { m_BehaviorTree.OnBehaviorTreeCollisionExit2D += OnCollisionExit2D; } if (ReceiveTriggerEnterCallback) { m_BehaviorTree.OnBehaviorTreeTriggerEnter += OnTriggerEnter; } if (ReceiveTriggerExitCallback) { m_BehaviorTree.OnBehaviorTreeTriggerExit += OnTriggerExit; } if (ReceiveTriggerEnter2DCallback) { m_BehaviorTree.OnBehaviorTreeTriggerEnter2D += OnTriggerEnter2D; } if (ReceiveTriggerExit2DCallback) { m_BehaviorTree.OnBehaviorTreeTriggerExit2D += OnTriggerExit2D; } if (ReceiveControllerColliderHitCallback) { m_BehaviorTree.OnBehaviorTreeControllerColliderHit += OnControllerColliderHit; } OnAwake(); } /// /// Callback when the behavior tree is initialized. /// public virtual void OnAwake() { } /// /// Callback when the behavior tree is started. /// public virtual void OnBehaviorTreeStarted() { } /// /// Callback when the behavior tree is started. /// [System.Obsolete("Task.OnStarted has been deprecated. Use Task.OnBehaviorTreeStarted instead.")] public virtual void OnStarted() { } /// /// Callback when the task is started. /// public virtual void OnStart() { } /// /// Executes the task logic. Returns a TaskStatus indicating how the behavior tree flow should proceed. /// /// The status of the task. public virtual TaskStatus OnUpdate() { return TaskStatus.Success; } /// /// Callback when the task stops. /// public virtual void OnEnd() { } /// /// Calls Unity's GetComponent method. /// /// The retrieved component (can be null). protected T GetComponent() { return gameObject.GetComponent(); } /// /// Calls Unity's GetComponent method. /// /// The component type that should be retrieved. /// The retrieved component (can be null). protected Component GetComponent(System.Type type) { return gameObject.GetComponent(type); } /// /// Calls Unity's TryGetComponent method. /// /// The type of component that should be retireved. /// The retrieved component. protected void TryGetComponent(out T component) where T : Component { gameObject.TryGetComponent(out component); } /// /// Calls Unity's TryGetComponent method. /// /// The type of component to get. /// The retrieved component. protected void TryGetComponent(System.Type type, out Component component) { gameObject.TryGetComponent(type, out component); } protected void StartCoroutine(string methodName) { m_BehaviorTree.StartTaskCoroutine(this, methodName); } protected Coroutine StartCoroutine(System.Collections.IEnumerator routine) { return m_BehaviorTree.StartCoroutine(routine); } protected Coroutine StartCoroutine(string methodName, object value) { return m_BehaviorTree.StartTaskCoroutine(this, methodName, value); } protected void StopCoroutine(string methodName) { m_BehaviorTree.StopTaskCoroutine(methodName); } protected void StopCoroutine(System.Collections.IEnumerator routine) { m_BehaviorTree.StopCoroutine(routine); } protected void StopAllCoroutines() { m_BehaviorTree.StopAllTaskCoroutines(); } protected virtual bool ReceiveCollisionEnterCallback => false; /// /// Callback when OnCollisionEnter is triggered. This callback will only be received when ReceiveCollisionEnterCallback is true. /// /// The resulting collision. protected virtual void OnCollisionEnter(Collision collision) { } protected virtual bool ReceiveCollisionExitCallback => false; /// /// Callback when OnCollisionExit is triggered. This callback will only be received when ReceiveCollisionExitCallback is true. /// /// The resulting collision. protected virtual void OnCollisionExit(Collision collision) { } protected virtual bool ReceiveCollisionEnter2DCallback => false; /// /// Callback when OnCollisionEnter2D is triggered. This callback will only be received when ReceiveCollisionEnter2DCallback is true. /// /// The resulting collision. protected virtual void OnCollisionEnter2D(Collision2D collision) { } protected virtual bool ReceiveCollisionExit2DCallback => false; /// /// Callback when OnCollisionExit2D is triggered. This callback will only be received when ReceiveCollisionExit2DCallback is true. /// /// The resulting collision. protected virtual void OnCollisionExit2D(Collision2D collision) { } protected virtual bool ReceiveTriggerEnterCallback => false; /// /// Callback when OnTriggerEnter is triggered. This callback will only be received when ReceiveTriggerEnterCallback is true. /// /// The overlapping collider. protected virtual void OnTriggerEnter(Collider other) { } protected virtual bool ReceiveTriggerExitCallback => false; /// /// Callback when OnTriggerExit is triggered. This callback will only be received when ReceiveTriggerExitCallback is true. /// /// The overlapping collider. protected virtual void OnTriggerExit(Collider other) { } protected virtual bool ReceiveTriggerEnter2DCallback => false; /// /// Callback when OnTriggerEnter2D is triggered. This callback will only be received when ReceiveTriggerEnter2DCallback is true. /// /// The overlapping collider. protected virtual void OnTriggerEnter2D(Collider2D other) { } protected virtual bool ReceiveTriggerExit2DCallback => false; /// /// Callback when OnTriggerExit2D is triggered. This callback will only be received when ReceiveTriggerExit2DCallback is true. /// /// The overlapping collider. protected virtual void OnTriggerExit2D(Collider2D other) { } protected virtual bool ReceiveControllerColliderHitCallback => false; /// /// Callback when OnControllerColliderHit is triggered. This callback will only be received when ReceiveControllerColliderHitCallback is true. /// /// The hit result. protected virtual void OnControllerColliderHit(ControllerColliderHit hit) { } /// /// Editor method which will draw the gizmos. /// /// A reference to the behavior tree component. internal void OnDrawGizmos(BehaviorTree behaviorTree) { if (m_BehaviorTree == null) { m_BehaviorTree = behaviorTree; m_Transform = behaviorTree.transform; m_GameObject = behaviorTree.gameObject; } OnDrawGizmos(); } /// /// Callback when OnDrawGizmos is triggered. /// protected virtual void OnDrawGizmos() { } /// /// Editor method which will draw the selected gizmos. /// /// A reference to the behavior tree component. internal void OnDrawGizmosSelected(BehaviorTree behaviorTree) { if (m_BehaviorTree == null) { m_BehaviorTree = behaviorTree; m_Transform = behaviorTree.transform; m_GameObject = behaviorTree.gameObject; } OnDrawGizmosSelected(); } /// /// Callback when OnDrawGizmosSelected is triggered. /// protected virtual void OnDrawGizmosSelected() { } /// /// Callback when the behavior tree is stopped. /// /// Is the behavior tree paused? public virtual void OnBehaviorTreeStopped(bool paused) { } /// /// Callback when the behavior tree is stopped. /// /// Is the behavior tree paused? [System.Obsolete("Task.OnStopped has been deprecated. Use Task.OnBehaviorTreeStopped instead.")] public virtual void OnStopped(bool paused) { } /// /// Callback when the behavior tree is destroyed. /// public virtual void OnDestroy() { if (m_BehaviorTree == null) { return; } m_BehaviorTree.OnBehaviorTreeStarted -= OnBehaviorTreeStarted; m_BehaviorTree.OnBehaviorTreeStopped -= OnBehaviorTreeStopped; m_BehaviorTree.OnBehaviorTreeDestroyed -= OnDestroy; if (ReceiveCollisionEnterCallback) { m_BehaviorTree.OnBehaviorTreeCollisionEnter -= OnCollisionEnter; } if (ReceiveCollisionExitCallback) { m_BehaviorTree.OnBehaviorTreeCollisionExit -= OnCollisionExit; } if (ReceiveCollisionEnter2DCallback) { m_BehaviorTree.OnBehaviorTreeCollisionEnter2D -= OnCollisionEnter2D; } if (ReceiveCollisionExit2DCallback) { m_BehaviorTree.OnBehaviorTreeCollisionExit2D -= OnCollisionExit2D; } if (ReceiveTriggerEnterCallback) { m_BehaviorTree.OnBehaviorTreeTriggerEnter -= OnTriggerEnter; } if (ReceiveTriggerExitCallback) { m_BehaviorTree.OnBehaviorTreeTriggerExit -= OnTriggerExit; } if (ReceiveTriggerEnter2DCallback) { m_BehaviorTree.OnBehaviorTreeTriggerEnter2D -= OnTriggerEnter2D; } if (ReceiveTriggerExit2DCallback) { m_BehaviorTree.OnBehaviorTreeTriggerExit2D -= OnTriggerExit2D; } if (ReceiveControllerColliderHitCallback) { m_BehaviorTree.OnBehaviorTreeControllerColliderHit -= OnControllerColliderHit; } } /// /// Overrides ToString providing a nicer string value of the task. /// /// The overloaded ToString value. public override string ToString() { return GetType().Name; } /// /// Specifies the type of reflection that should be used to save the task. /// /// The index of the sub-task. This is used for the task set allowing each contained task to have their own save type. public virtual MemberVisibility GetSaveReflectionType(int index) { return MemberVisibility.Public; } /// /// Returns the current task state. /// /// The DOTS world. /// The DOTS entity. /// The current task state. public virtual object Save(World world, Entity entity) { return null; } /// /// Loads the previous task state. /// /// The previous task state. /// The DOTS world. /// The DOTS entity. public virtual void Load(object saveData, World world, Entity entity) { } /// /// Loads the previous task state. /// /// The previous task state. /// The DOTS world. /// The DOTS entity. /// A reference to the map between the VariableAssignment and SharedVariable. /// A reference to the list of task references that need to be resolved later. public virtual void Load(object saveData, World world, Entity entity, Dictionary variableByNameMap, ref ResizableArray taskReferences) { Load(saveData, world, entity); } } /// /// A blob asset that stores the indicies array. /// public struct IndiciesBlob { [Tooltip("The indicies of the tasks.")] public BlobArray Indicies; } } #endif