using System; using System.Collections.Generic; using Unity.Collections; using Unity.Entities; using UnityEngine; [DisableAutoCreation] public class DestroyPrimsInChannel : BaseComponentSystem { struct GroupType { public EntityArray entities; [ReadOnly] public ComponentDataArray prims; } [Inject] GroupType Group; public DestroyPrimsInChannel(GameWorld world) : base(world) {} public int channel; List entityBuffer = new List(16); protected override void OnUpdate() { entityBuffer.Clear(); for (int i = 0, c = Group.prims.Length; i < c; i++) { var prim = Group.prims[i]; if (prim.channel != channel) continue; GameDebug.Assert(!entityBuffer.Contains(Group.entities[i])); entityBuffer.Add(Group.entities[i]); } foreach (var entity in entityBuffer) { var go = EntityManager.GetComponentObject(entity).gameObject; m_world.RequestDespawn(go, PostUpdateCommands); } } } public class DebugPrimitiveModule { struct SphereRequest { public int channel; public Vector3 center; public float radius; public Color color; public float duration; } struct LineRequest { public int channel; public Vector3 pA; public Vector3 pB; public Color color; public float duration; } struct CapsuleRequest { public int channel; public Vector3 pA; public Vector3 pB; public float radius; public Color color; public float duration; } public DebugPrimitiveModule(GameWorld world, float colorScale, float heigthOffset) { m_world = world; m_settings = Resources.Load("DebugPrimitiveSystemSettings"); m_colorScale = colorScale; m_heigthOffset = new Vector3(0, heigthOffset, 0); m_DrawCapsulePrimitives = m_world.GetECSWorld().CreateManager(); m_DrawSpherePrimitive = m_world.GetECSWorld().CreateManager(); m_DrawLinePrimitive = m_world.GetECSWorld().CreateManager(); m_DestroyPrimsInChannel = m_world.GetECSWorld().CreateManager(m_world); } public void Shutdown() { m_world.GetECSWorld().DestroyManager(m_DrawCapsulePrimitives); m_world.GetECSWorld().DestroyManager(m_DrawSpherePrimitive); m_world.GetECSWorld().DestroyManager(m_DrawLinePrimitive); m_world.GetECSWorld().DestroyManager(m_DestroyPrimsInChannel); } public void DrawPrimitives() { m_DrawCapsulePrimitives.Update(); m_DrawSpherePrimitive.Update(); m_DrawLinePrimitive.Update(); } public static void ClearChannel(int channel) { var i = 0; while (i < m_SphereRequest.Count) { if (m_SphereRequest[i].channel == channel) m_SphereRequest.EraseSwap(i); else i++; } i = 0; while (i < m_CapsuleRequest.Count) { if (m_CapsuleRequest[i].channel == channel) m_CapsuleRequest.EraseSwap(i); else i++; } i = 0; while (i < m_LineRequest.Count) { if (m_LineRequest[i].channel == channel) m_LineRequest.EraseSwap(i); else i++; } if (m_PendingChannelClear.Contains(channel)) return; m_PendingChannelClear.Add(channel); } public static void CreateSpherePrimitive(int channel, Vector3 center, float radius, Color color, float duration) { m_SphereRequest.Add(new SphereRequest() { channel = channel, center = center, radius = radius, color = color, duration = duration }); } public static void CreateCapsulePrimitive(int channel, Vector3 pA, Vector3 pB, float radius, Color color, float duration) { m_CapsuleRequest.Add(new CapsuleRequest() { channel = channel, pA = pA, pB = pB, radius = radius, color = color, }); } public static void CreateLinePrimitive(int channel, Vector3 pA, Vector3 pB, Color color, float duration) { m_LineRequest.Add(new LineRequest() { channel = channel, pA = pA, pB = pB, color = color, }); } public void HandleRequests() { foreach (var channel in m_PendingChannelClear) { m_DestroyPrimsInChannel.channel = channel; m_DestroyPrimsInChannel.Update(); } m_PendingChannelClear.Clear(); foreach (var request in m_SphereRequest) { var prim = m_world.Spawn(m_settings.spherePrefab.gameObject); prim.center = request.center + m_heigthOffset; prim.radius = request.radius; prim.color = request.color*m_colorScale; var entity = prim.gameObject.GetComponent().Entity; m_world.GetEntityManager().AddComponentData(entity, new DebugPrimitive() { channel = request.channel }); } m_SphereRequest.Clear(); foreach (var request in m_CapsuleRequest) { var prim = m_world.Spawn(m_settings.capsulePrefab.gameObject); prim.pA = request.pA + m_heigthOffset; prim.pB = request.pB + m_heigthOffset; prim.radius = request.radius; prim.color = request.color*m_colorScale; var entity = prim.gameObject.GetComponent().Entity; m_world.GetEntityManager().AddComponentData(entity, new DebugPrimitive() { channel = request.channel }); } m_CapsuleRequest.Clear(); foreach (var request in m_LineRequest) { var prim = m_world.Spawn(m_settings.linePrefab.gameObject); prim.pA = request.pA + m_heigthOffset; prim.pB = request.pB + m_heigthOffset; prim.color = request.color*m_colorScale; var entity = prim.gameObject.GetComponent().Entity; m_world.GetEntityManager().AddComponentData(entity, new DebugPrimitive() { channel = request.channel }); } m_LineRequest.Clear(); } static GameWorld m_world; static DebugPrimitiveSystemSettings m_settings; static float m_colorScale; static Vector3 m_heigthOffset; private static List m_SphereRequest = new List(32); private static List m_CapsuleRequest = new List(32); private static List m_LineRequest = new List(32); private static List m_PendingChannelClear = new List(32); DrawCapsulePrimitives m_DrawCapsulePrimitives; DrawSpherePrimitives m_DrawSpherePrimitive; DrawLinePrimitives m_DrawLinePrimitive; DestroyPrimsInChannel m_DestroyPrimsInChannel; }