Beispiel #1
0
    void Start()
    {
        if (Instance != null)
        {
            Destroy(this);
            Debug.LogError("Two Pathfinding managers exist in the scene. Deleting one");
            return;
        }

        Instance = this;

        lightingManager = GetComponent <LightingManager>();
        probeData       = new NativeArray <TilePathfindingData>(lightingManager.totalProbes, Allocator.Persistent);
        for (int i = 0; i < lightingManager.totalProbes; i++)
        {
            probeData[i] = new TilePathfindingData
            {
                distance    = 99999,
                closestSeen = 99999,
                occupied    = true
            };
        }

        directionData = new NativeArray <float2>(lightingManager.totalProbes, Allocator.Persistent);

        lightingManager.OnLightingProbesMoved += HandleProbesMoved;
    }
Beispiel #2
0
    void Update()
    {
        for (int i = 0; i < TestsPerFrame; i++)
        {
            float2 probePos = lightingManager.probeIndexToXy(testIndex);
            bool   occupied = Physics2D.OverlapCircle(probePos, 0.3f, pathfindingBlockingLayers);

            //update data
            var currentData = probeData[testIndex];
            probeData[testIndex] = new TilePathfindingData
            {
                closestSeen = currentData.closestSeen,
                distance    = currentData.distance,
                occupied    = occupied
            };

            testIndex = (testIndex + 1) % lightingManager.totalProbes;
        }

        float3 playerPosition    = PlayerCharacter.GetPostion();
        float2 playerPosRelative = (playerPosition - lightingManager.getBottomLeft()).xy;

        if (math.all(new bool4(playerPosRelative > 0, playerPosRelative < lightingManager.ProbeCounts)))
        {
            int  index            = IndexFromPosition((int2)playerPosRelative, lightingManager.ProbeCounts);
            var  current          = probeData[index];
            int2 playerPosRounded = (int2)playerPosition.xy;
            probeData[index] = new TilePathfindingData
            {
                distance    = 0,
                closestSeen = playerPosRounded,
                occupied    = current.occupied
            };
        }

        NativeArray <TilePathfindingData> output = new NativeArray <TilePathfindingData>(probeData.Length, Allocator.TempJob);
        JobHandle dependency = default(JobHandle);

        var job = new UpdatePathfindingJob
        {
            TileData       = probeData,
            ProbeCounts    = lightingManager.ProbeCounts,
            Output         = output,
            PlayerPosition = PlayerCharacter.GetPostion()
        };
        var handle = job.Schedule(probeData.Length, 8, dependency);

        dependency = handle;

        dependency.Complete();

        output.CopyTo(probeData);
        output.Dispose();

        UpdateDirections();
    }
Beispiel #3
0
        /// <summary>
        /// Renders a path from the unit to the selected tile with active tile sprites
        /// </summary>
        public static void RenderPathToTile(TilePathfindingData selectedTilePathfindingData, IEnumerable <TilePathfindingData> unitPathfindingData)
        {
            var tilePathfindingData = unitPathfindingData.ToList();

            ChangeTileSprites(tilePathfindingData.Select(x => x.DestinationGridTile), TileState.Selected);
            if (selectedTilePathfindingData == null)
            {
                return;
            }
            var pathfindingDataList = PathfindingHelper.GetPathToTile(tilePathfindingData, selectedTilePathfindingData.DestinationGridTile);

            ChangeTileSprites(pathfindingDataList, TileState.Active);
        }
Beispiel #4
0
        public void Execute(int index)
        {
            int2 pos     = PositionFromIndex(index, ProbeCounts);
            var  current = TileData[index];

            int2 playerPos    = (int2)PlayerPosition.xy;
            int2 closestSeen  = 99999;
            int  smallestDist = 99999;

            if (!current.occupied)
            {
                for (int xOffset = -1; xOffset <= 1; xOffset++)
                {
                    for (int yOffset = -1; yOffset <= 1; yOffset++)
                    {
                        int2 newPos = pos + new int2(xOffset, yOffset);
                        if (math.any(new bool4(newPos < 0, newPos >= ProbeCounts)))
                        {
                            continue;
                        }
                        var data = TileData[IndexFromPosition(newPos, ProbeCounts)];
                        smallestDist = math.min(smallestDist, data.distance);
                        if (!data.occupied)
                        {
                            if (math.all(playerPos == data.closestSeen))
                            {
                                if (data.distance <= smallestDist)
                                {
                                    smallestDist = data.distance;
                                    closestSeen  = playerPos;
                                }
                            }
                        }
                    }
                }
            }


            Output[index] = new TilePathfindingData
            {
                distance    = math.min(smallestDist + 1, 99999),
                closestSeen = closestSeen,
                occupied    = current.occupied
            };
        }
Beispiel #5
0
        public void Execute(int index)
        {
            int2 pos       = PositionFromIndex(index, ProbeCounts);
            int2 offsetPos = pos + Delta;

            if (math.any(new bool4(offsetPos < 0, offsetPos >= ProbeCounts)))
            {
                Output[index] = new TilePathfindingData
                {
                    closestSeen = 99999,
                    distance    = 99999,
                    occupied    = true
                };
            }
            else
            {
                Output[index] = TileData[IndexFromPosition(offsetPos, ProbeCounts)];
            }
        }
Beispiel #6
0
        /// <summary>
        /// Calculates and returns the tilePathfindingData of every available move for the selected unit in the grid, using Dijkstra pathfinding algorithm
        /// </summary>
        private static List <TilePathfindingData> CalculatePathfindingForAvailableMoves(GridTile[,] tileGrid, GridTile startingGridTile, int moveCount)
        {
            var remainingTilesToAnalyze = new List <TilePathfindingData>();
            var analyzedTiles           = new List <TilePathfindingData>();

            //pathfindingData for the starting tile
            var startingTilePathfindingData = new TilePathfindingData(startingGridTile, null, 0, 0);

            remainingTilesToAnalyze.Add(startingTilePathfindingData);

            //We check the adjacent tiles of the first tile in remainingTilesToAnalyze, then we remove that tile from the list and then we order the list by totalTilePathCost
            do
            {
                var tileToAnalyze = remainingTilesToAnalyze[0];
                var adjacentTilesPathfindingData = CalculateAdjacentTilePathfindingData(tileGrid, tileToAnalyze, analyzedTiles);
                foreach (var tilePathfindingData in adjacentTilesPathfindingData)
                {
                    var existingTilePathfindingData = remainingTilesToAnalyze.FirstOrDefault(x => x.DestinationGridTile == tilePathfindingData.DestinationGridTile);
                    //If we find a faster way to get to a tile that is already on the remainingTilesToAnalyze, we replace it with the new pathfinding data
                    if (existingTilePathfindingData != null && existingTilePathfindingData.MoveCost > tilePathfindingData.MoveCost)
                    {
                        remainingTilesToAnalyze.Remove(existingTilePathfindingData);
                        remainingTilesToAnalyze.Add(tilePathfindingData);
                    }
                    //if the destinationTile is not on the remainingTilesToAnalyze list, we add it
                    else if (existingTilePathfindingData == null)
                    {
                        remainingTilesToAnalyze.Add(tilePathfindingData);
                    }
                }
                analyzedTiles.Add(tileToAnalyze);
                remainingTilesToAnalyze.Remove(tileToAnalyze);
                remainingTilesToAnalyze = remainingTilesToAnalyze.OrderBy(x => x.TotalTilePathCost).ToList();
            } while (remainingTilesToAnalyze.Any(x => x.MoveCost <= moveCount)); //we stop the pathfinding when all our moves cost more than the unit's movementSpeed
            return(analyzedTiles);
        }
Beispiel #7
0
 /// <summary>
 /// Takes a tile's pathfinding data, and calculates the adjacent tiles' pathfinding data
 /// </summary>
 private static IEnumerable <TilePathfindingData> CalculateAdjacentTilePathfindingData(GridTile[,] tileGrid, TilePathfindingData sourceTilePathfindingData, IReadOnlyCollection <TilePathfindingData> analyzedTiles)
 {
     return((from adjacentTile in tileGrid.GetAdjacentGridTiles(sourceTilePathfindingData.DestinationGridTile)
             where (adjacentTile.TerrainType != TerrainType.Impassable &&
                    (ReferenceEquals(adjacentTile.CurrentUnit, null) ||
                     adjacentTile.CurrentUnit.Faction != UnitFaction.Monster)) && analyzedTiles.All(x => x.DestinationGridTile != adjacentTile)
             let tileMoveCost = sourceTilePathfindingData.MoveCost + TerrainMoveCost[adjacentTile.TerrainType]
                                select new TilePathfindingData(adjacentTile, sourceTilePathfindingData, tileMoveCost, 0)).ToList());
 }