/// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Samples { using Opsive.BehaviorDesigner.Runtime.Components; using Opsive.BehaviorDesigner.Runtime.Tasks; using Unity.Burst; using Unity.Entities; using Unity.Collections; using Unity.Transforms; using UnityEngine; [Opsive.Shared.Utility.Description("Destroys the Entity.")] [Shared.Utility.Category("Behavior Designer Samples/DOTS")] public class Destroy : ECSActionTask { /// /// Returns a new TBufferElement for use by the system. /// /// A new TBufferElement for use by the system. public override DestroyComponent GetBufferElement() { return new DestroyComponent() { Index = RuntimeIndex, }; } } /// /// The DOTS data structure for the Destroy struct. /// public struct DestroyComponent : IBufferElementData { [Tooltip("The index of the node.")] public ushort Index; } /// /// A DOTS flag indicating when a Destroy node is active. /// public struct DestroyFlag : IComponentData, IEnableableComponent { } /// /// Runs the Destroy logic. /// [DisableAutoCreation] public partial struct DestroyTaskSystem : ISystem { private EntityQuery m_DestroyQuery; /// /// Creates the required objects for use within the job system. /// /// The current SystemState. [BurstCompile] private void OnCreate(ref SystemState state) { m_DestroyQuery = new EntityQueryBuilder(Allocator.Temp) .WithAllRW().WithAllRW() .WithAll() .Build(ref state); } /// /// Updates the logic. /// /// The current state of the system. [BurstCompile] private void OnUpdate(ref SystemState state) { var ecb = new EntityCommandBuffer(state.WorldUpdateAllocator); foreach (var (branchComponents, destroyComponents, taskComponents, entity) in SystemAPI.Query, DynamicBuffer, DynamicBuffer>().WithAll().WithEntityAccess()) { for (int i = 0; i < destroyComponents.Length; ++i) { var destroyComponent = destroyComponents[i]; var taskComponent = taskComponents[destroyComponent.Index]; var branchComponent = branchComponents[taskComponent.BranchIndex]; if (!branchComponent.CanExecute) { continue; } if (taskComponent.Status != TaskStatus.Queued) { continue; } // The DestroyEntityTag will destroy the entity. ecb.AddComponent(entity); // The task always returns success. taskComponent.Status = TaskStatus.Success; var taskComponentBuffer = taskComponents; taskComponentBuffer[destroyComponent.Index] = taskComponent; } } ecb.Playback(state.EntityManager); ecb.Dispose(); } } }