Example #1
0
        protected override void OnUpdate()
        {
            if (_flowFieldEntity.Equals(Entity.Null))
            {
                return;
            }
            float         deltaTime       = Time.DeltaTime;
            FlowFieldData flowFieldData   = _flowFieldData;
            int2          destinationCell = _destinationCellData.destinationIndex;
            JobHandle     jobHandle       = new JobHandle();

            jobHandle = Entities.ForEach((ref PhysicsVelocity physVelocity, ref EntityMovementData entityMovementData,
                                          ref Translation translation) =>
            {
                int2 curCellIndex = FlowFieldHelper.GetCellIndexFromWorldPos(translation.Value, flowFieldData.gridSize,
                                                                             flowFieldData.cellRadius * 2);

                if (curCellIndex.Equals(destinationCell))
                {
                    entityMovementData.destinationReached = true;
                }

                int flatCurCellIndex = FlowFieldHelper.ToFlatIndex(curCellIndex, flowFieldData.gridSize.y);
                float2 moveDirection = _cellDataContainer[flatCurCellIndex].bestDirection;
                float finalMoveSpeed = (entityMovementData.destinationReached ? entityMovementData.destinationMoveSpeed : entityMovementData.moveSpeed) * deltaTime;

                physVelocity.Linear.xz = moveDirection * finalMoveSpeed;
                translation.Value.y    = 0f;
            }).ScheduleParallel(jobHandle);
            jobHandle.Complete();
        }
        protected override void OnUpdate()
        {
            EntityCommandBuffer commandBuffer = _ecbSystem.CreateCommandBuffer();

            Entities.ForEach((Entity entity, in NewFlowFieldData newFlowFieldData, in FlowFieldData flowFieldData) =>
            {
                commandBuffer.RemoveComponent <NewFlowFieldData>(entity);

                DynamicBuffer <EntityBufferElement> buffer = newFlowFieldData.isExistingFlowField
                                        ? GetBuffer <EntityBufferElement>(entity)
                                        : commandBuffer.AddBuffer <EntityBufferElement>(entity);
                DynamicBuffer <Entity> entityBuffer = buffer.Reinterpret <Entity>();

                float cellRadius   = flowFieldData.cellRadius;
                float cellDiameter = cellRadius * 2;

                int2 gridSize = flowFieldData.gridSize;

                for (int x = 0; x < gridSize.x; x++)
                {
                    for (int y = 0; y < gridSize.y; y++)
                    {
                        float3 cellWorldPos  = new float3(cellDiameter * x + cellRadius, 0, cellDiameter * y + cellRadius);
                        byte cellCost        = CostFieldHelper.instance.EvaluateCost(cellWorldPos, cellRadius);
                        CellData newCellData = new CellData
                        {
                            worldPos      = cellWorldPos,
                            gridIndex     = new int2(x, y),
                            cost          = cellCost,
                            bestCost      = ushort.MaxValue,
                            bestDirection = int2.zero
                        };

                        Entity curCell;
                        if (newFlowFieldData.isExistingFlowField)
                        {
                            int flatIndex = FlowFieldHelper.ToFlatIndex(new int2(x, y), gridSize.y);
                            curCell       = entityBuffer[flatIndex];
                        }
                        else
                        {
                            curCell = commandBuffer.CreateEntity(_cellArchetype);
                            entityBuffer.Add(curCell);
                        }
                        commandBuffer.SetComponent(curCell, newCellData);
                    }
                }

                int2 destinationIndex = FlowFieldHelper.GetCellIndexFromWorldPos(flowFieldData.clickedPos, gridSize, cellDiameter);
                DestinationCellData newDestinationCellData = new DestinationCellData {
                    destinationIndex = destinationIndex
                };
                if (!newFlowFieldData.isExistingFlowField)
                {
                    commandBuffer.AddComponent <DestinationCellData>(entity);
                }
                commandBuffer.SetComponent(entity, newDestinationCellData);
                commandBuffer.AddComponent <CalculateFlowFieldTag>(entity);
            }).Run();
        protected override void OnUpdate()
        {
            var commandBuffer = _ecbSystem.CreateCommandBuffer();

            Entities.ForEach((Entity entity, ref DynamicBuffer <EntityBufferElement> buffer,
                              in CalculateFlowFieldTag calculateFlowFieldTag, in DestinationCellData destinationCellData,
                              in FlowFieldData flowFieldData) =>
            {
                commandBuffer.RemoveComponent <CalculateFlowFieldTag>(entity);

                DynamicBuffer <Entity> entityBuffer      = buffer.Reinterpret <Entity>();
                NativeArray <CellData> cellDataContainer = new NativeArray <CellData>(entityBuffer.Length, Allocator.TempJob);

                int2 gridSize = flowFieldData.gridSize;

                for (int i = 0; i < entityBuffer.Length; i++)
                {
                    cellDataContainer[i] = GetComponent <CellData>(entityBuffer[i]);
                }

                int flatDestinationIndex = FlowFieldHelper.ToFlatIndex(destinationCellData.destinationIndex, gridSize.y);
                CellData destinationCell = cellDataContainer[flatDestinationIndex];
                destinationCell.cost     = 0;
                destinationCell.bestCost = 0;
                cellDataContainer[flatDestinationIndex] = destinationCell;

                NativeQueue <int2> indicesToCheck = new NativeQueue <int2>(Allocator.TempJob);
                NativeList <int2> neighborIndices = new NativeList <int2>(Allocator.TempJob);

                indicesToCheck.Enqueue(destinationCellData.destinationIndex);

                // Integration Field
                while (indicesToCheck.Count > 0)
                {
                    int2 cellIndex       = indicesToCheck.Dequeue();
                    int cellFlatIndex    = FlowFieldHelper.ToFlatIndex(cellIndex, gridSize.y);
                    CellData curCellData = cellDataContainer[cellFlatIndex];
                    neighborIndices.Clear();
                    FlowFieldHelper.GetNeighborIndices(cellIndex, GridDirection.CardinalDirections, gridSize, ref neighborIndices);
                    foreach (int2 neighborIndex in neighborIndices)
                    {
                        int flatNeighborIndex     = FlowFieldHelper.ToFlatIndex(neighborIndex, gridSize.y);
                        CellData neighborCellData = cellDataContainer[flatNeighborIndex];
                        if (neighborCellData.cost == byte.MaxValue)
                        {
                            continue;
                        }

                        if (neighborCellData.cost + curCellData.bestCost < neighborCellData.bestCost)
                        {
                            neighborCellData.bestCost            = (ushort)(neighborCellData.cost + curCellData.bestCost);
                            cellDataContainer[flatNeighborIndex] = neighborCellData;
                            indicesToCheck.Enqueue(neighborIndex);
                        }
                    }
                }

                // Flow Field
                for (int i = 0; i < cellDataContainer.Length; i++)
                {
                    CellData curCullData = cellDataContainer[i];
                    neighborIndices.Clear();
                    FlowFieldHelper.GetNeighborIndices(curCullData.gridIndex, GridDirection.AllDirections, gridSize, ref neighborIndices);
                    ushort bestCost    = curCullData.bestCost;
                    int2 bestDirection = int2.zero;
                    foreach (int2 neighborIndex in neighborIndices)
                    {
                        int flatNeighborIndex     = FlowFieldHelper.ToFlatIndex(neighborIndex, gridSize.y);
                        CellData neighborCellData = cellDataContainer[flatNeighborIndex];
                        if (neighborCellData.bestCost < bestCost)
                        {
                            bestCost      = neighborCellData.bestCost;
                            bestDirection = neighborCellData.gridIndex - curCullData.gridIndex;
                        }
                    }
                    curCullData.bestDirection = bestDirection;
                    cellDataContainer[i]      = curCullData;
                }

                GridDebug.instance.ClearList();

                for (int i = 0; i < entityBuffer.Length; i++)
                {
                    commandBuffer.SetComponent(entityBuffer[i], cellDataContainer[i]);
                    commandBuffer.AddComponent <AddToDebugTag>(entityBuffer[i]);
                }

                neighborIndices.Dispose();
                cellDataContainer.Dispose();
                indicesToCheck.Dispose();
                commandBuffer.AddComponent <CompleteFlowFieldTag>(entity);
            }).Run();