/// --------------------------------------------- /// 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 Opsive.GraphDesigner.Runtime; using Unity.Entities; using Unity.Transforms; using UnityEngine; using System; [Tooltip("Fires any entity that has the HealthComponent.")] [Shared.Utility.Category("Behavior Designer Samples/DOTS")] public class Fire : ECSActionTask { /// /// The type of flag that should be enabled when the task is running. /// public override ComponentType Flag { get => typeof(FireFlag); } /// /// Returns a new TBufferElement for use by the system. /// /// A new TBufferElement for use by the system. public override FireComponent GetBufferElement() { return new FireComponent() { Index = RuntimeIndex, }; } } /// /// The DOTS data structure for the Fire struct. /// public struct FireComponent : IBufferElementData { [Tooltip("The index of the node.")] public ushort Index; } /// /// A DOTS flag indicating when a Fire node is active. /// public struct FireFlag : IComponentData, IEnableableComponent { } /// /// Runs the Fire logic. /// [DisableAutoCreation] public partial struct FireTaskSystem : ISystem { /// /// Updates the logic. /// /// The current SystemState. private void OnUpdate(ref SystemState state) { var ecb = new EntityCommandBuffer(state.WorldUpdateAllocator); foreach (var (branchComponents, taskComponents, fireComponents, entity) in SystemAPI.Query, DynamicBuffer, DynamicBuffer>().WithAll().WithEntityAccess()) { for (int i = 0; i < fireComponents.Length; ++i) { var fireComponent = fireComponents[i]; var taskComponent = taskComponents[fireComponent.Index]; var branchComponent = branchComponents[taskComponent.BranchIndex]; if (!branchComponent.CanExecute) { continue; } if (taskComponent.Status != TaskStatus.Queued) { continue; } // Find the target. There will only be one entity with the TargetEntityTag. foreach (var (target, localTransform, targetEntity) in SystemAPI.Query, RefRO>().WithEntityAccess()) { ecb.AddComponent(targetEntity); break; } // The task will always return immediately. taskComponent.Status = TaskStatus.Success; var taskComponentBuffer = taskComponents; taskComponentBuffer[fireComponent.Index] = taskComponent; // The turret has fired - apply a recoil. foreach (var (target, turretEntity) in SystemAPI.Query>().WithOptions(EntityQueryOptions.IgnoreComponentEnabledState).WithEntityAccess()) { ecb.SetComponentEnabled(turretEntity, true); break; } } } ecb.Playback(state.EntityManager); ecb.Dispose(); } } }