public static void DrawUnitPaths(MinionPathData minionPathInfo, NativeSlice <float3> path)
    {
        if (EditorApplication.isPaused)
        {
            return;
        }
        if ((minionPathInfo.bitmasks & 4) == 0)
        {
            // No path finding
            return;
        }

        for (int i = minionPathInfo.currentCornerIndex; i < minionPathInfo.pathSize; i++)
        {
            if (i < 1)
            {
                continue;
            }
            Debug.DrawLine(path[i - 1], path[i], Color.green, Time.deltaTime * 2);
        }
    }
    public unsafe Entity Spawn(FormationData formationData, float3 spawnPointOffset, FormationWaypoint[] waypoints, bool spawnedFromPortals = false, float3?forward = null)
    {
        var formationEntity = entityManager.CreateEntity();

        RaycastHit hit;

        if (Physics.Raycast(new Ray((Vector3)formationData.Position + new Vector3(0, 1000000, 0), Vector3.down), out hit))
        {
            formationData.Position.y = hit.point.y;
        }
        if (!spawnedFromPortals)
        {
            formationData.SpawnedCount = formationData.UnitCount;
        }

        if (forward == null)
        {
            formationData.Forward = new float3(0, 0, formationData.Position.z > 0 ? -1 : 1);
        }
        else
        {
            formationData.Forward = forward.Value;
        }

        formationData.HighLevelPathIndex = 1;
        entityManager.AddComponentData(formationEntity, formationData);
        entityManager.AddComponentData(formationEntity, new FormationClosestData());
        entityManager.AddComponentData(formationEntity, new FormationNavigationData {
            TargetPosition = formationData.Position
        });
        entityManager.AddComponent(formationEntity, typeof(EntityBuffer));
        entityManager.AddComponent(formationEntity, typeof(PolygonIdBuffer));
        entityManager.AddComponentData(formationEntity, new FormationIntegrityData());

        var unitType = (UnitType)formationData.UnitType;

        GameObject minionPrefab;

        minionPrefab = GetMinionPrefab(unitType);

        var prototypeMinion = entityManager.Instantiate(minionPrefab);

        entityManager.AddComponentData(prototypeMinion, new MinionBitmask(formationData.IsFriendly, spawnedFromPortals));
        entityManager.AddComponentData(prototypeMinion, new MinionAttackData(new Entity()));
        entityManager.AddComponentData(prototypeMinion, new MinionPathData());
        entityManager.AddComponent(prototypeMinion, typeof(PolygonIdBuffer));
        entityManager.AddComponentData(prototypeMinion, new IndexInFormationData(-1));
        entityManager.AddComponentData(prototypeMinion, new NavMeshLocationComponent());


        var minions = new NativeArray <Entity>(formationData.UnitCount, Allocator.Temp);

        entityManager.Instantiate(prototypeMinion, minions);

        for (int i = 0; i < minions.Length; ++i)
        {
            var entity           = minions[i];
            var transform        = entityManager.GetComponentData <UnitTransformData>(entity);
            var animator         = entityManager.GetComponentData <TextureAnimatorData>(entity);
            var minion           = entityManager.GetComponentData <MinionData>(entity);
            var indexInFormation = entityManager.GetComponentData <IndexInFormationData>(entity);

            transform.FormationEntity         = formationEntity;
            indexInFormation.IndexInFormation = i;
            transform.UnitType = (int)unitType;
            transform.Forward  = formationData.Forward;


            var randf3 = Random.insideUnitSphere * 100f;
            transform.Position   = randf3;
            transform.Position.y = 0f;

            animator.UnitType = (int)unitType;
            animator.AnimationSpeedVariation = UnityEngine.Random.Range(SimulationSettings.Instance.MinionAnimationSpeedMin,
                                                                        SimulationSettings.Instance.MinionAnimationSpeedMax);

            minion.attackCycle = -1;

            MinionPathData pathComponent = new MinionPathData()
            {
                bitmasks           = 0,
                pathSize           = 0,
                currentCornerIndex = 0
            };

            entityManager.SetComponentData(entity, pathComponent);

            entityManager.SetComponentData(entity, transform);
            entityManager.SetComponentData(entity, animator);
            entityManager.SetComponentData(entity, minion);
            entityManager.SetComponentData(entity, indexInFormation);
        }

        minions.Dispose();
        entityManager.DestroyEntity(prototypeMinion);

        return(formationEntity);
    }
    public unsafe Entity Spawn(FormationData formationData, float3 spawnPointOffset, FormationWaypoint[] waypoints, bool spawnedFromPortals = false, float3?forward = null)
    {
        var formationEntity = entityManager.CreateEntity();

        RaycastHit hit;

        if (Physics.Raycast(new Ray((Vector3)formationData.Position + new Vector3(0, 1000000, 0), Vector3.down), out hit))
        {
            formationData.Position.y = hit.point.y;
        }
        if (!spawnedFromPortals)
        {
            formationData.SpawnedCount = formationData.UnitCount;
        }
        var location = mapLocationQuery.MapLocation(formationData.Position, new Vector3(100, 100, 100), 0);

        formationData.Position = location.position;

        if (forward == null)
        {
            formationData.Forward = new float3(0, 0, formationData.Position.z > 0 ? -1 : 1);
        }
        else
        {
            formationData.Forward = forward.Value;
        }

        formationData.HighLevelPathIndex = 1;

        FormationWaypoint bridgeStart = GetClosestWaypoint(waypoints, formationData.Position, !formationData.IsFriendly);
        FormationWaypoint bridgeEnd   = Array.Find(waypoints, x => x.index == bridgeStart.index && x.isLeft != bridgeStart.isLeft);

        FormationHighLevelPath highLevelPath = new FormationHighLevelPath
        {
            target1             = bridgeStart.transform.position,
            target2             = bridgeEnd.transform.position,
            ultimateDestination = new float3(formationData.Position.x, formationData.Position.y, -Mathf.Sign(formationData.Position.z) * 200)
        };

        entityManager.AddComponentData(formationEntity, formationData);
        entityManager.AddComponentData(formationEntity, new FormationClosestData()
        {
        });
        entityManager.AddComponentData(formationEntity, new FormationNavigationData {
            TargetPosition = formationData.Position
        });

        entityManager.AddComponentData(formationEntity, new CrowdAgent {
            worldPosition = formationData.Position, type = 0, location = location
        });
        entityManager.AddComponentData(formationEntity, highLevelPath);
        entityManager.AddComponent(formationEntity, ComponentType.FixedArray(typeof(EntityRef), formationData.UnitCount));
        entityManager.AddComponent(formationEntity, ComponentType.FixedArray(typeof(PolygonId), 128));
        entityManager.AddComponentData(formationEntity, new FormationIntegrityData()
        {
        });

        var crowd = new CrowdAgentNavigator()
        {
            active = true,
            newDestinationRequested = false,
            goToDestination         = false,
            destinationInView       = false,
            destinationReached      = true,
        };

        entityManager.AddComponentData(formationEntity, crowd);

        var unitType = (UnitType)formationData.UnitType;

        GameObject minionPrefab;

        minionPrefab = GetMinionPrefab(unitType);

        var prototypeMinion = entityManager.Instantiate(minionPrefab);

        entityManager.AddComponentData(prototypeMinion, new MinionBitmask(formationData.IsFriendly, spawnedFromPortals));
        entityManager.AddComponentData(prototypeMinion, new MinionAttackData(new Entity()));
        entityManager.AddComponentData(prototypeMinion, new MinionPathData());
        entityManager.AddComponent(prototypeMinion, ComponentType.FixedArray(typeof(float3), SimulationState.MaxPathSize));
        entityManager.AddComponentData(prototypeMinion, new IndexInFormationData(-1));
        entityManager.AddComponentData(prototypeMinion, new NavMeshLocationComponent());


        var minions = new NativeArray <Entity>(formationData.UnitCount, Allocator.Temp);

        entityManager.Instantiate(prototypeMinion, minions);

        for (int i = 0; i < minions.Length; ++i)
        {
            var entity           = minions[i];
            var transform        = entityManager.GetComponentData <UnitTransformData>(entity);
            var animator         = entityManager.GetComponentData <TextureAnimatorData>(entity);
            var minion           = entityManager.GetComponentData <MinionData>(entity);
            var indexInFormation = entityManager.GetComponentData <IndexInFormationData>(entity);

            transform.FormationEntity         = formationEntity;
            indexInFormation.IndexInFormation = i;
            transform.UnitType = (int)unitType;
            transform.Forward  = formationData.Forward;

            float scale = entityManager.GetSharedComponentData <RenderingData>(entity).LodData.Scale;
            transform.Scale = UnityEngine.Random.Range(SimulationSettings.Instance.MinionScaleMin, SimulationSettings.Instance.MinionScaleMax) * scale;
            if (unitType != UnitType.Skeleton)
            {
                transform.HeightOffset = UnityEngine.Random.Range(SimulationSettings.Instance.MinionHeightOffsetMin,
                                                                  SimulationSettings.Instance.MinionHeightOffsetMax);
            }

            if (!spawnedFromPortals)
            {
                transform.Position = formationData.GetOffsetFromCenter(i) + formationData.Position;
            }
            else
            {
                float3 unitOffset = new float3((i % SimulationSettings.countPerSpawner), 0f, 0);
                transform.Position = formationData.Position + unitOffset + spawnPointOffset;
            }

            entityManager.SetComponentData(entity, new NavMeshLocationComponent(mapLocationQuery.MapLocation(transform.Position, Vector3.one * 10, 0)));

            animator.UnitType = (int)unitType;
            animator.AnimationSpeedVariation = UnityEngine.Random.Range(SimulationSettings.Instance.MinionAnimationSpeedMin,
                                                                        SimulationSettings.Instance.MinionAnimationSpeedMax);

            minion.attackCycle = -1;

            MinionPathData pathComponent = new MinionPathData()
            {
                bitmasks           = 0,
                pathSize           = 0,
                currentCornerIndex = 0
            };

            entityManager.SetComponentData(entity, pathComponent);

            entityManager.SetComponentData(entity, transform);
            entityManager.SetComponentData(entity, animator);
            entityManager.SetComponentData(entity, minion);
            entityManager.SetComponentData(entity, indexInFormation);
        }

        minions.Dispose();
        entityManager.DestroyEntity(prototypeMinion);

        return(formationEntity);
    }