#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime.Utility { using System; using Unity.Entities; using UnityEngine; /// /// Bridges the public runtime assembly to the ECS execution systems. /// public interface IBehaviorTreeExecutionController { void AddCleanupSystems(World world, ComponentSystemGroup behaviorTreeSystemGroup); void AddReevaluateSystem(World world, ComponentSystemGroup beforeTraversalSystemGroup); void AddTaskObjectSystem(World world, ComponentSystemGroup traversalTaskSystemGroup); Type TaskObjectReevaluateSystemType { get; } bool CompleteTraversal(World world, EntityManager entityManager); void CompleteEvaluation(World world, EntityManager entityManager, bool stopRunning); bool IsActive(World world, EntityManager entityManager); } /// /// Runtime access point for the Behavior Designer ECS execution systems. /// public static class BehaviorTreeExecution { private const string c_ControllerTypeName = "Opsive.BehaviorDesigner.Runtime.Utility.BehaviorTreeExecutionController, Opsive.BehaviorDesigner.Runtime.Systems"; private static IBehaviorTreeExecutionController s_Controller; private static bool s_ControllerResolveFailed; /// /// Registers the execution controller implementation. /// /// The controller implementation. public static void Register(IBehaviorTreeExecutionController controller) { s_Controller = controller; s_ControllerResolveFailed = false; } /// /// Adds the core cleanup systems to the behavior tree group. /// /// The ECS world. /// The behavior tree system group. public static void AddCleanupSystems(World world, ComponentSystemGroup behaviorTreeSystemGroup) { if (!EnsureController()) { return; } s_Controller.AddCleanupSystems(world, behaviorTreeSystemGroup); } /// /// Adds the reevaluation system to the before-traversal group. /// /// The ECS world. /// The before-traversal group. public static void AddReevaluateSystem(World world, ComponentSystemGroup beforeTraversalSystemGroup) { if (!EnsureController()) { return; } s_Controller.AddReevaluateSystem(world, beforeTraversalSystemGroup); } /// /// Adds the TaskObject system to the traversal task group. /// /// The ECS world. /// The traversal task group. public static void AddTaskObjectSystem(World world, ComponentSystemGroup traversalTaskSystemGroup) { if (!EnsureController()) { return; } s_Controller.AddTaskObjectSystem(world, traversalTaskSystemGroup); } /// /// Returns the TaskObject reevaluation system type. /// public static Type TaskObjectReevaluateSystemType { get { return EnsureController() ? s_Controller.TaskObjectReevaluateSystemType : null; } } /// /// Completes one traversal loop and returns true if another evaluation pass should run. /// /// The ECS world. /// The entity manager. /// True if the traversal group should evaluate again. public static bool CompleteTraversal(World world, EntityManager entityManager) { return EnsureController() && s_Controller.CompleteTraversal(world, entityManager); } /// /// Completes the evaluation system. /// /// The ECS world. /// The entity manager. /// Is the traversal group stopping? public static void CompleteEvaluation(World world, EntityManager entityManager, bool stopRunning) { if (!EnsureController()) { return; } s_Controller.CompleteEvaluation(world, entityManager, stopRunning); } /// /// Returns true if any behavior tree is still active. /// /// The ECS world. /// The entity manager. /// True if any behavior tree is still active. public static bool IsActive(World world, EntityManager entityManager) { return EnsureController() && s_Controller.IsActive(world, entityManager); } /// /// Ensures the execution controller is available. /// /// True if the controller is available. private static bool EnsureController() { if (s_Controller != null) { return true; } if (s_ControllerResolveFailed) { return false; } var controllerType = Type.GetType(c_ControllerTypeName); if (controllerType == null) { Debug.LogError("Behavior Designer could not find the Runtime.Systems assembly. The package must include Opsive.BehaviorDesigner.Runtime.Systems for ECS behavior tree execution."); s_ControllerResolveFailed = true; return false; } s_Controller = Activator.CreateInstance(controllerType) as IBehaviorTreeExecutionController; if (s_Controller != null) { return true; } Debug.LogError($"Behavior Designer could not create the execution controller type {c_ControllerTypeName}."); s_ControllerResolveFailed = true; return false; } } } #endif