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();