private bool addUnit()
        {
            // Get the player who owns this building.
            ModelComponent temp = building.Parent;
            while (!(temp is PlayerComponent))
            {
                temp = temp.Parent;
            }
            PlayerComponent player = (PlayerComponent)temp;

            // Get the Gameworld.
            while (!(temp is GameModel))
            {
                temp = temp.Parent;
            }
            GameModel model = (GameModel)temp;

            // Get the CellComponent to insert into.
            CellComponent insertCell = findEmptyNeighborCell(model);
            if (insertCell == null)
            {
                return false; // No empty CellComponent.
            }

            // Add Unit to the Map.
            UnitComponent unit = new UnitComponent(stats);
            unit.PointLocation = new PointF(insertCell.X + 0.5f, insertCell.Y + 0.5f);

            // Add Unit to the Player who owns the building.
            player.GetUnitList().AddChild(unit);
            return true;
        }
 public UnitComponent Create(string type)
 {
     UnitStats unitStats = getStats(type);
     UnitComponent unit = new UnitComponent();
     unit.Attack = unitStats.attack;
     unit.AttackRange = unitStats.attackRange;
     unit.AttackTicks = unitStats.attackTicks;
     unit.BuildSpeed = unitStats.buildSpeed;
     unit.CanAttack = unitStats.canAttack;
     unit.CanBuild = unitStats.canBuild;
     unit.CanHarvest = unitStats.canHarvest;
     unit.CurrentHealth = unitStats.maxHealth;
     unit.IsZombie = unitStats.isZombie;
     unit.MaxHealth = unitStats.maxHealth;
     unit.Speed = unitStats.speed;
     unit.Type = type;
     unit.VisibilityRange = unitStats.visibilityRange;
     return unit;
 }
示例#3
0
 public static void Add(this UnitComponent self, Unit unit)
 {
 }
示例#4
0
 private void Start()
 {
     mUnitComponent = GetComponent <UnitComponent>();
 }
示例#5
0
 internal void Initialize()
 {
     mUnitComponent = GetComponent <UnitComponent>();
 }
 public UnitOrientationChangedEventArgs(UnitComponent unit, UnitComponent.Orient oldOrientation, UnitComponent.Orient newOrientation)
 {
     this.unit           = unit;
     this.oldOrientation = oldOrientation;
     this.newOrientation = newOrientation;
 }
示例#7
0
    public void AddUnit(GameObject go, SimUnitConfig unit)
    {
        UnitComponent ucomp = go.AddComponent <UnitComponent>();

        ucomp.SetSimUnit(unit);
    }
示例#8
0
        protected override async ETTask Run(ETModel.Session session, M2C_CreateUnits message)
        {
            UnitComponent unitComponent = ETModel.Game.Scene.GetComponent <UnitComponent>();

            foreach (UnitInfo unitInfo in message.Units)
            {
                //TODO 暂时先忽略除英雄之外的Unit(如技能碰撞体),后期需要配表来解决这一块的逻辑,并且需要在协议里指定Unit的类型Id(注意不是运行时的Id,是Excel表中的类型Id)
                //TODO 诺手UnitTypeId暂定10001
                if (unitComponent.Get(unitInfo.UnitId) != null || unitInfo.UnitTypeId != 10001)
                {
                    continue;
                }

                //根据不同名称和ID,创建英雄
                Unit unit = UnitFactory.CreateHero("NuoKe", unitInfo.UnitId);
                //因为血条需要,创建热更层unit
                HotfixUnit hotfixUnit = HotfixUnitFactory.CreateHotfixUnit(unit, true);

                hotfixUnit.AddComponent <FallingFontComponent>();

                unit.Position = new Vector3(unitInfo.X, unitInfo.Y, unitInfo.Z);
                unit.AddComponent <NP_RuntimeTreeManager>();

                //Log.Info("开始创建行为树");
                ConfigComponent configComponent = Game.Scene.GetComponent <ConfigComponent>();
                NP_RuntimeTreeFactory
                .CreateSkillNpRuntimeTree(unit, configComponent.Get <Client_SkillCanvasConfig>(10001).NPBehaveId,
                                          configComponent.Get <Client_SkillCanvasConfig>(10001).BelongToSkillId).Start();
                NP_RuntimeTreeFactory
                .CreateSkillNpRuntimeTree(unit, configComponent.Get <Client_SkillCanvasConfig>(10002).NPBehaveId,
                                          configComponent.Get <Client_SkillCanvasConfig>(10002).BelongToSkillId).Start();
                //Log.Info("行为树创建完成");

                //添加英雄数据
                M2C_GetHeroDataResponse M2C_GetHeroDataResponse = await Game.Scene.GetComponent <SessionComponent>()
                                                                  .Session.Call(new C2M_GetHeroDataRequest()
                {
                    UnitID = unitInfo.UnitId
                }) as M2C_GetHeroDataResponse;

                ETModel.Game.Scene.GetComponent <UnitComponent>().Get(unitInfo.UnitId)
                .AddComponent <HeroDataComponent, long>(M2C_GetHeroDataResponse.HeroDataID);

                // 创建头顶Bar
                Game.EventSystem.Run(EventIdType.CreateHeadBar, unitInfo.UnitId);
                // 挂载头顶Bar
                hotfixUnit.AddComponent <HeroHeadBarComponent, Unit, FUI>(unit,
                                                                          Game.Scene.GetComponent <FUIComponent>().Get(unitInfo.UnitId));
            }

            if (ETModel.Game.Scene.GetComponent <UnitComponent>().MyUnit == null)
            {
                // 给自己的Unit添加引用
                ETModel.Game.Scene.GetComponent <UnitComponent>().MyUnit =
                    ETModel.Game.Scene.GetComponent <UnitComponent>().Get(PlayerComponent.Instance.MyPlayer.UnitId);
                ETModel.Game.Scene.GetComponent <UnitComponent>().MyUnit
                .AddComponent <CameraComponent, Unit>(ETModel.Game.Scene.GetComponent <UnitComponent>().MyUnit);

                Game.EventSystem.Run(EventIdType.EnterMapFinish);
            }

            //ETModel.Log.Info($"{DateTime.UtcNow}完成一次创建Unit");
            await ETTask.CompletedTask;
        }
示例#9
0
    public int RegisterUnitComponent(UnitComponent component, System.Enum[] stateExtensions)
    {
        bool add = true;
        int UCcompID = -1;
        if (PluggedStateExtendingComponents.ContainsValue(component))
        {
            foreach (int key in PluggedStateExtendingComponents.Keys)
            {
                if (component == PluggedStateExtendingComponents[key])
                {
                    UCcompID = key;
                    Component.Destroy(component);
                    return UCcompID;
                }
            }
        }
        else
        {
            foreach (System.Enum extension in stateExtensions)
            {

                EnumProvider.ORDERSLIST KEY = (EnumProvider.ORDERSLIST)extension;
                if (KEY < EnumProvider.ORDERSLIST.Cancel)
                {
                    string VALUE = System.Enum.GetName(typeof(EnumProvider.ORDERSLIST), KEY);
                    if ((int)KEY > (int)EnumProvider.ORDERSLIST.Stay)
                        OptionalStatesOrder.Remove((int)KEY);
                    if (!OptionalStatesOrder.ContainsKey((int)KEY))
                        OptionalStatesOrder.Add((int)KEY, VALUE);
                }
                else
                    add = false;
            }
            if (add)
            {
                UCcompID = PluggedStateExtendingComponents.Count;
                PluggedStateExtendingComponents.Add(UCcompID, component);

                optionalstateIDs = RefreshStatelist();
            }
        }
        return UCcompID;
    }
示例#10
0
    protected override void OnUpdate()
    {
        var ecb = bi_ECB.CreateCommandBuffer();

        elapsedTime += Time.DeltaTime;


        int unitsToSpawn    = 0;
        int currentTimeSlot = UnitManager.Instance.CurrentSlotNumber;

        // need to wait one second after each generation because at the moment the distribution of the units
        // among the delay before/after the start of a time slot ahs a resolution of one sec
        if (elapsedTime > 0.05 && currentTimeSlot <= finalTimeSlot)
        {
            elapsedTime = 0;

            int currentCloseTimeSlot = UnitManager.Instance.GetCloseTimeSlot();
            // when the sim enters the delay range for the before the next time slot
            if (currentCloseTimeSlot >= 0 && currentCloseTimeSlot <= finalTimeSlot)
            {
                unitsToSpawn = timeSlotSpawners[currentCloseTimeSlot].GetUnitsToSpawnNow();
                if (currentCloseTimeSlot > prevCloseTimeSlot)
                {
                    // update prevNeighbour to avoid reenter next frame
                    prevCloseTimeSlot = currentCloseTimeSlot;
                    // compute courses for next slots
                    availableCourseIDsInCurrentSlot = availableCourseIDsPerSlot[currentCloseTimeSlot];
                }
            }
        }

        //spawn units when sim starts and every if another slot has passed and there are still some courses beginning in a later slot i enter the lambda
        if (unitsToSpawn > 0 && availableCourseIDsInCurrentSlot.Count > 0)
        {
            Entities
            .WithoutBurst()
            .ForEach((Entity e, int entityInQueryIndex, in UnitInitializerComponent uic, in LocalToWorld ltw) =>
            {
                for (int j = 0; j < unitsToSpawn; j++)
                {
                    Entity defEntity      = ecb.Instantiate(uic.prefabToSpawn);
                    float3 position       = new float3(UnityEngine.Random.Range(0, 36), uic.baseOffset, 0) + uic.currentPosition; //value 36 based on the spawner position (-28,0,-47)
                    bool hasCovid         = false;
                    bool wearMask         = false;
                    Material unitMaterial = UnitManager.Instance.healthyMoveMaterial;

                    ecb.SetComponent(defEntity, new Translation {
                        Value = position
                    });
                    ecb.AddComponent <UnitComponent>(defEntity);
                    ecb.AddComponent <PersonComponent>(defEntity);
                    ecb.AddComponent <CourseComponent>(defEntity);
                    ecb.AddBuffer <UnitBuffer>(defEntity);
                    DynamicBuffer <ScheduleBuffer> sb = ecb.AddBuffer <ScheduleBuffer>(defEntity);

                    //select randomly a course from the available ones
                    int selectedCourseId = availableCourseIDsInCurrentSlot[Utils.GenerateInt(availableCourseIDsInCurrentSlot.Count)];

                    Course selectedCourse = courses[selectedCourseId];
                    float3 currentDest;
                    float3 firstDest = 0;

                    //add lectures to Schedule_Buffer
                    for (int k = 0; k < selectedCourse.Lectures.Count; k++)
                    {
                        currentDest = Utils.FindDestination("Aula" + selectedCourse.Lectures[k].Room);
                        if (k == 0)
                        {
                            firstDest = currentDest;
                        }
                        sb.Add(new ScheduleBuffer
                        {
                            destination = currentDest,
                            duration    = selectedCourse.Lectures[k].Duration
                        });
                    }

                    currentDest = Utils.FindExit("UscitaCastelidardo");
                    sb.Add(new ScheduleBuffer
                    {
                        destination = currentDest,
                        duration    = -1
                    });
                    UnitComponent uc = new UnitComponent
                    {
                        fromLocation       = position,
                        toLocation         = firstDest,
                        speed              = UnitManager.Instance.Speed,
                        minDistanceReached = uic.minDistanceReached,
                        count              = 0,
                        currentBufferIndex = 0,
                        routed             = false
                    };

                    if (!hasCovidAlreadySpawned)     //only the first entity in the first slot has covid to simulate what can be the infection
                    {
                        hasCovidAlreadySpawned = true;
                        hasCovid = true;
                    }

                    CourseComponent courseComponent = new CourseComponent
                    {
                        id           = selectedCourse.Id,
                        lectureStart = selectedCourse.LectureStart
                    };

                    if (UnityEngine.Random.Range(0, 100) <= (UnitManager.Instance.ProbabilityOfWearingMask * 100))
                    {
                        wearMask = true;
                    }

                    PersonComponent personComponent = new PersonComponent
                    {
                        age      = Utils.GenerateInt(19, 30),
                        sex      = Utils.GenerateSex(),
                        hasCovid = hasCovid,
                        wearMask = wearMask
                    };

                    if (hasCovid)
                    {
                        unitMaterial = UnitManager.Instance.covidMoveMaterial;
                    }

                    ecb.AddSharedComponent(e, new RenderMesh
                    {
                        mesh     = UnitManager.Instance.unitMesh,
                        material = unitMaterial
                    });

                    ecb.SetComponent(defEntity, uc);
                    ecb.SetComponent(defEntity, courseComponent);
                    ecb.SetComponent(defEntity, personComponent);
                }
            }).Run();
示例#11
0
 // Housekeeping
 private void Awake()
 {
     _unit = GetComponent <UnitComponent> ();
 }
示例#12
0
    //---------------------- Collision Avoidance ---------------------------

    protected override void OnUpdate()
    {
        float innerProbabilityOfInfectionWithMaskWait = probabilityOfInfectionWithMaskWait;
        float innerProbabilityOfInfectionWait         = probabilityOfInfectionWait;
        float innerProbabilityOfInfectionWithMask     = probabilityOfInfectionWithMask;
        float innerProbabilityOfInfection             = probabilityOfInfection;
        float innerInfectionDistance     = infectionDistance;
        float innerInfectionDistanceWait = infectionDistanceWait;

        frameCounter++;

        totalCurrentNumberOfStudents      = 0;
        totalCurrentNumberOfStudentsCovid = 0;

        float deltaTime = Time.DeltaTime;

        var ecb = bi_ECB.CreateCommandBuffer();
        var ecbParallel = bi_ECB.CreateCommandBuffer().AsParallelWriter();
        var randomArray = World.GetExistingSystem <RandomSystem>().RandomArray;
        int i = 0, counter = 0;

        Entities.
        WithNone <WaitComponent>().
        WithoutBurst().
        WithStructuralChanges().
        ForEach((Entity e, ref UnitComponent uc, ref DynamicBuffer <UnitBuffer> ub, ref Translation trans, ref PersonComponent pc) =>
        {
            if (i <= UnitManager.Instance.MaxEntitiesRoutedPerFrame)
            {
                string key = uc.fromLocation.x + "_" + uc.fromLocation.z + "_" + uc.toLocation.x + "_" + uc.toLocation.z;

                //Cached path
                if (UnitManager.Instance.UseCache && allPaths.ContainsKey(key) && (!uc.routed || ub.Length == 0))
                {
                    allPaths.TryGetValue(key, out float3[] cachedPath);
                    for (int h = 0; h < cachedPath.Length; h++)
                    {
                        ub.Add(new UnitBuffer {
                            wayPoints = cachedPath[h]
                        });
                    }
                    uc.routed          = true;
                    uc.usingCachedPath = true;
                    EntityManager.AddComponent <UnitRoutedComponent>(e);
                    return;
                }
                //Job
                else if (!uc.routed || ub.Length == 0)
                {
                    keys[counter]             = key;
                    NavMeshQuery currentQuery = new NavMeshQuery(navMeshWorld, Allocator.Persistent, UnitManager.Instance.MaxPathNodePoolSize);
                    SinglePathFindingJob spfj = new SinglePathFindingJob()
                    {
                        query            = currentQuery,
                        nml_FromLocation = uc.nml_FromLocation,
                        nml_ToLocation   = uc.nml_ToLocation,
                        fromLocation     = uc.fromLocation,
                        toLocation       = uc.toLocation,
                        extents          = extents,
                        maxIteration     = UnitManager.Instance.MaxIterations,
                        result           = results[counter],
                        statusOutput     = statusOutputs[counter],
                        maxPathSize      = UnitManager.Instance.MaxPathSize,
                        ub = ub
                    };
                    routedEntities.Add(e);
                    queries.Add(currentQuery);
                    jobHandles.Add(spfj.Schedule());
                    counter++;
                }
                i++;
            }
            else
            {
                return;
            }
        }).Run();

        //Waiting for the completion of jobs
        int n                       = 0;
        NativeArray <JobHandle> jhs = new NativeArray <JobHandle>(jobHandles.Count, Allocator.Temp);

        foreach (JobHandle jh in jobHandles)
        {
            jhs[n] = jh;
            n++;
        }
        JobHandle.CompleteAll(jhs);
        jhs.Dispose();

        int j = 0;

        foreach (JobHandle jh in jobHandles)
        {
            if (statusOutputs[j][0] == 1)
            {
                if (UnitManager.Instance.UseCache && !allPaths.ContainsKey(keys[j]))
                {
                    float3[] wayPoints = new float3[statusOutputs[j][1]];
                    for (int k = 0; k < statusOutputs[j][1]; k++)
                    {
                        wayPoints[k] = results[j][k];
                    }
                    if (wayPoints.Length > 0)
                    {
                        allPaths.Add(keys[j], wayPoints);
                    }
                }

                UnitComponent uc = EntityManager.GetComponentData <UnitComponent>(routedEntities[j]);
                uc.routed = true;
                EntityManager.SetComponentData <UnitComponent>(routedEntities[j], uc);
                EntityManager.AddComponent <UnitRoutedComponent>(routedEntities[j]);
            }
            queries[j].Dispose();
            j++;
        }
        routedEntities.Clear();
        jobHandles.Clear();
        queries.Clear();

        //----------- Collision Avoidance Code -----------------

        EntityQuery eq = GetEntityQuery(typeof(UnitComponent));

        cellVsEntityPositions.Clear();
        if (eq.CalculateEntityCount() > cellVsEntityPositions.Capacity)
        {
            cellVsEntityPositions.Capacity = eq.CalculateEntityCount();
        }

        NativeMultiHashMap <int, CovidPos> .ParallelWriter cellVsEntityPositionsParallel = cellVsEntityPositions.AsParallelWriter();
        Entities
        .WithNone <WaitComponent>()
        .WithBurst(synchronousCompilation: true)
        .ForEach((ref UnitComponent uc, ref Translation trans, ref PersonComponent pc) =>
        {
            cellVsEntityPositionsParallel.Add(GetUniqueKeyForPosition(trans.Value, 5), new CovidPos {
                pos = trans.Value, hasCovid = pc.hasCovid
            });
        }).ScheduleParallel();



        NativeMultiHashMap <int, CovidPos> cellVsEntityPositionsForJob = cellVsEntityPositions;

        Entities
        .WithNone <WaitComponent>()
        .WithBurst(synchronousCompilation: true)
        .WithReadOnly(cellVsEntityPositionsForJob)
        .WithNativeDisableParallelForRestriction(randomArray)
        .ForEach((Entity e, int entityInQueryIndex, int nativeThreadIndex, ref UnitComponent uc, ref Translation trans, ref PersonComponent pc) =>
        {
            var random = randomArray[nativeThreadIndex];
            int key    = GetUniqueKeyForPosition(trans.Value, 5);
            NativeMultiHashMapIterator <int> nmhKeyIterator;
            CovidPos otherEntityData;
            float3 otherEntityPos;
            bool otherEntityHasCovid;
            float currentDistance = 0.3f;
            uc.avoidanceDirection = float3.zero;
            int total             = 0;
            int totalInCell       = 0;

            if (cellVsEntityPositionsForJob.TryGetFirstValue(key, out otherEntityData, out nmhKeyIterator))
            {
                otherEntityPos      = otherEntityData.pos;
                otherEntityHasCovid = otherEntityData.hasCovid;

                do
                {
                    if (!trans.Value.Equals(otherEntityPos))
                    {
                        totalInCell++;

                        if (currentDistance > math.sqrt(math.lengthsq(trans.Value - otherEntityPos)))
                        {
                            currentDistance       = math.sqrt(math.lengthsq(trans.Value - otherEntityPos));
                            float3 distanceFromTo = trans.Value - otherEntityPos;
                            uc.avoidanceDirection = math.normalize(distanceFromTo / currentDistance);
                            total++;
                        }
                    }
                } while (cellVsEntityPositionsForJob.TryGetNextValue(out otherEntityData, ref nmhKeyIterator) && totalInCell < 20);
                if (total > 0)
                {
                    uc.avoidanceDirection /= total;
                }
            }
            randomArray[nativeThreadIndex] = random;
        }).ScheduleParallel();

        //----------- Collision Avoidance Code -----------------

        cellVsEntityPositionsForJob = cellVsEntityPositions;

        if (frameCounter % 30 == 0)
        {
            Entities
            .WithoutBurst()
            .WithReadOnly(cellVsEntityPositionsForJob)
            .WithNativeDisableParallelForRestriction(randomArray)
            .WithNone <WaitComponent>()
            .ForEach((Entity e, int entityInQueryIndex, int nativeThreadIndex, ref UnitComponent uc, ref Translation trans, ref PersonComponent pc) =>
            {
                if (!pc.hasCovid)
                {
                    var random = randomArray[nativeThreadIndex];
                    int key    = GetUniqueKeyForPosition(trans.Value, 5);
                    NativeMultiHashMapIterator <int> nmhKeyIterator;
                    CovidPos otherEntityData;
                    float3 otherEntityPos;
                    bool otherEntityHasCovid;
                    float contagionPercentageValue = 0;
                    float covidPercentage          = 0;
                    //int totalInCell = 0;
                    if (cellVsEntityPositionsForJob.TryGetFirstValue(key, out otherEntityData, out nmhKeyIterator))
                    {
                        otherEntityPos      = otherEntityData.pos;
                        otherEntityHasCovid = otherEntityData.hasCovid;

                        do
                        {
                            if (!trans.Value.Equals(otherEntityPos))
                            {
                                if (otherEntityHasCovid && math.abs(otherEntityPos.x - trans.Value.x) < innerInfectionDistanceWait && math.abs(otherEntityPos.z - trans.Value.z) < innerInfectionDistanceWait)
                                {
                                    contagionPercentageValue = random.NextInt(0, 100);

                                    if (pc.wearMask)
                                    {
                                        covidPercentage = innerProbabilityOfInfectionWithMask;
                                    }
                                    else
                                    {
                                        covidPercentage = innerProbabilityOfInfection;
                                    }

                                    if (contagionPercentageValue <= covidPercentage)
                                    {
                                        pc.hasCovid = true;

                                        ecbParallel.SetSharedComponent(entityInQueryIndex, e, new RenderMesh
                                        {
                                            mesh     = UnitManager.Instance.unitMesh,
                                            material = UnitManager.Instance.covidMoveMaterial
                                        });

                                        break;
                                    }
                                }
                            }
                        } while (cellVsEntityPositionsForJob.TryGetNextValue(out otherEntityData, ref nmhKeyIterator));
                    }
                    randomArray[nativeThreadIndex] = random;
                }
            }).ScheduleParallel();

            Entities
            .WithoutBurst()
            .WithReadOnly(cellVsEntityPositionsForJob)
            .WithNativeDisableParallelForRestriction(randomArray)
            .WithAll <WaitComponent>().ForEach((Entity e, int entityInQueryIndex, int nativeThreadIndex, ref UnitComponent uc, ref Translation trans, ref PersonComponent pc) =>
            {
                if (!pc.hasCovid)
                {
                    var random = randomArray[nativeThreadIndex];
                    int key    = GetUniqueKeyForPosition(trans.Value, 5);
                    NativeMultiHashMapIterator <int> nmhKeyIterator;
                    CovidPos otherEntityData;
                    float3 otherEntityPos;
                    bool otherEntityHasCovid;
                    float contagionPercentageValue = 0;
                    float covidPercentage          = 0;
                    int totalInCell = 0;

                    if (cellVsEntityPositionsForJob.TryGetFirstValue(key, out otherEntityData, out nmhKeyIterator))
                    {
                        otherEntityPos      = otherEntityData.pos;
                        otherEntityHasCovid = otherEntityData.hasCovid;

                        do
                        {
                            if (!trans.Value.Equals(otherEntityPos))
                            {
                                totalInCell++;

                                if (otherEntityHasCovid && math.abs(otherEntityPos.x - trans.Value.x) < innerInfectionDistanceWait || math.abs(otherEntityPos.z - trans.Value.z) < innerInfectionDistanceWait)
                                {
                                    contagionPercentageValue = random.NextInt(0, 100);

                                    if (pc.wearMask)
                                    {
                                        covidPercentage = innerProbabilityOfInfectionWithMaskWait;
                                    }
                                    else
                                    {
                                        covidPercentage = innerProbabilityOfInfectionWait;
                                    }

                                    if (contagionPercentageValue <= covidPercentage)
                                    {
                                        pc.hasCovid = true;

                                        ecbParallel.SetSharedComponent(entityInQueryIndex, e, new RenderMesh
                                        {
                                            mesh     = UnitManager.Instance.unitMesh,
                                            material = UnitManager.Instance.covidWaitMaterial
                                        });

                                        break;
                                    }
                                }
                            }
                        } while (cellVsEntityPositionsForJob.TryGetNextValue(out otherEntityData, ref nmhKeyIterator) && totalInCell < 30);
                    }
                    randomArray[nativeThreadIndex] = random;
                }
            }).ScheduleParallel();
        }


        //Movement
        Entities
        .WithoutBurst()
        .WithNone <WaitComponent>()
        .WithAll <UnitRoutedComponent>().ForEach((Entity e, int entityInQueryIndex, ref UnitComponent uc, ref DynamicBuffer <UnitBuffer> ub, ref DynamicBuffer <ScheduleBuffer> sb, ref Translation trans, ref PersonComponent pc, in RenderMesh rm) =>
        {
            UnityEngine.AI.NavMeshHit outResult;
            Translation newTrans = trans;

            if (ub.Length > 0 && uc.routed)
            {
                uc.waypointDirection    = math.normalize(ub[uc.currentBufferIndex].wayPoints - trans.Value);
                uc.avoidanceDirection.y = 0;
                uc.waypointDirection.y  = 0;
                uc.waypointDirection    = uc.waypointDirection + uc.avoidanceDirection;

                newTrans.Value   = trans.Value + uc.waypointDirection * uc.speed * deltaTime;
                newTrans.Value.y = 1.791667f;

                if (!UnityEngine.AI.NavMesh.SamplePosition(newTrans.Value, out outResult, 0.8f, NavMesh.AllAreas))
                {
                    uc.waypointDirection -= uc.avoidanceDirection;
                }

                trans.Value         += uc.waypointDirection * uc.speed * deltaTime;
                float3 finalWayPoint = uc.toLocation;
                finalWayPoint.y      = ub[uc.currentBufferIndex].wayPoints.y;

                if (math.distance(trans.Value, ub[uc.currentBufferIndex].wayPoints) <= uc.minDistanceReached)
                {
                    if (uc.currentBufferIndex < ub.Length - 1 && !ub[uc.currentBufferIndex].wayPoints.Equals(finalWayPoint))
                    {
                        uc.currentBufferIndex = uc.currentBufferIndex + 1;
                    }

                    else if (uc.count < sb.Length - 1)
                    {
                        uc.count             += 1;
                        uc.fromLocation       = uc.toLocation;
                        uc.toLocation         = sb[uc.count].destination;
                        uc.routed             = false;
                        uc.usingCachedPath    = false;
                        uc.currentBufferIndex = 0;
                        ub.Clear();
                        ecb.RemoveComponent <UnitRoutedComponent>(e);
                        ecb.AddComponent(e, new WaitComponent
                        {
                            slotsToWait = sb[uc.count - 1].duration,
                            waitEndTime = 0
                        });

                        ecb.SetSharedComponent(e, new RenderMesh
                        {
                            mesh     = UnitManager.Instance.unitMesh,
                            material = pc.hasCovid ? UnitManager.Instance.covidWaitMaterial : UnitManager.Instance.healthyWaitMaterial
                        });
                    }
                    else if (uc.count == sb.Length - 1)
                    {
                        ecb.DestroyEntity(e);

                        totalNumberOfStudentsExit++;
                        if (pc.hasCovid)
                        {
                            totalNumberOfCovidExit++;
                        }
                    }
                }
            }
        }).Run();

        Entities.
        WithoutBurst().
        ForEach((PersonComponent pc) =>
        {
            totalCurrentNumberOfStudents++;

            if (pc.hasCovid)
            {
                totalCurrentNumberOfStudentsCovid++;
            }
        }).Run();

        UnitManager.Instance.TotNumberOfStudentsExit = totalNumberOfStudentsExit;
        UnitManager.Instance.TotNumberOfCovidExit    = totalNumberOfCovidExit;
        UnitManager.Instance.CurrentNumberOfStudents = totalCurrentNumberOfStudents;
        UnitManager.Instance.CurrentNumberOfCovid    = totalCurrentNumberOfStudentsCovid;
    }