Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using HexagonSurvive.Game.Character.ECS;
- using HexagonSurvive.Map.Aspects;
- using HexagonSurvive.Map.Components;
- using Unity.Burst;
- using Unity.Collections;
- using Unity.Collections.LowLevel.Unsafe;
- using Unity.Entities;
- using Unity.Mathematics;
- using UnityEngine;
- namespace HexagonSurvive.Game.Navigation
- {
- [BurstCompile]
- public partial struct PathFindingJob : IJobEntity
- {
- [NativeDisableUnsafePtrRestriction]
- private RefRW<HexMapContainerData> _map;
- private const int MaxSearchStep = 100;
- public PathFindingJob(RefRW<HexMapContainerData> container) : this()
- {
- _map = container;
- }
- private void Execute(CharacterAspect character, ref DynamicBuffer<PathBuffer> path)
- {
- RefRW<PathFindingTaskData> taskData = character.pathFindingTask;
- int3 origin = taskData.ValueRO.origin;
- PathUnit destination = new PathUnit { coordinate = taskData.ValueRO.dest };
- bool ignoreNonWalkable = taskData.ValueRO.ignoreNonWalkable;
- int curStepNum = 0;
- NativeHashSet<int3> explored = new NativeHashSet<int3>(8, Allocator.TempJob);
- NativeList<int3> toExplore = new NativeList<int3>(Allocator.TempJob);
- NativeHashMap<int3, PathUnit> pathRecords = new NativeHashMap<int3, PathUnit>(8, Allocator.TempJob);
- toExplore.Add(taskData.ValueRO.origin);
- pathRecords.Add(taskData.ValueRO.origin, new PathUnit(0, default, taskData.ValueRO.origin, destination.coordinate));
- while (toExplore.Length != 0)
- {
- int cur = FindBestUnit(toExplore, pathRecords);
- PathUnit curUnit = pathRecords[toExplore[cur]];
- if ((curUnit.coordinate == destination.coordinate) is { x: true, y: true, z: true })
- {
- while ((curUnit.coordinate == origin) is not { x: true, y: true, z: true })
- {
- path.Add(new PathBuffer { coord = curUnit.coordinate });
- curUnit = pathRecords[curUnit.prior];
- }
- Debug.LogError($"寻路完成: 长度{path.Length}");
- Complete(character, explored, toExplore, pathRecords);
- return;
- }
- if (curStepNum == MaxSearchStep)
- {
- Debug.LogError($"未找到合适路径");
- Complete(character, explored, toExplore, pathRecords);
- return;
- }
- explored.Add(toExplore[cur]);
- toExplore.RemoveAtSwapBack(cur);
- curStepNum++;
- foreach (int3 coord in curUnit.GetNeighbours())
- {
- if (!_map.ValueRW.map.TryGetValue(coord, out HexUnitAspect u)) return;
- // InvalidOperationException: The ComponentLookup<HexagonSurvive.Map.Components.HexUnitData> has been declared as [WriteOnly] in the job, but you are reading from it. ↓↓↓↓↓
- if ((!ignoreNonWalkable && !u.Data.walkable) || explored.Contains(coord)) continue;
- bool alreadyScheduled = toExplore.Contains(coord);
- pathRecords.TryAdd(coord, new PathUnit(int.MaxValue, default, coord, destination.coordinate));
- if (!alreadyScheduled || curUnit.G + 1 < pathRecords[coord].G)
- {
- PathUnit newUnit = pathRecords[coord];
- newUnit.G = curUnit.G + 1;
- newUnit.H = PathUnit.GetUnitDistance(newUnit.coordinate, destination.coordinate);
- newUnit.prior = curUnit.coordinate;
- pathRecords[coord] = newUnit;
- if (!alreadyScheduled)
- toExplore.Add(coord);
- }
- }
- }
- }
- private int FindBestUnit(NativeList<int3> toExplore, NativeHashMap<int3, PathUnit> pathRecords)
- {
- int best = 0;
- for (int i = 0; i < toExplore.Length; i++)
- if (pathRecords[toExplore[i]].CompareTo(pathRecords[toExplore[best]]) == -1)
- best = i;
- return best;
- }
- private void Complete(CharacterAspect character, NativeHashSet<int3> explored,
- NativeList<int3> toExplore, NativeHashMap<int3, PathUnit> pathRecords)
- {
- character.pathFindingTask.ValueRW.isReady = false;
- character.pathFindingTask.ValueRW.isComplete = true;
- toExplore.Dispose();
- explored.Dispose();
- pathRecords.Dispose();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement