/// <summary> /// Sets the node occupation at the node index. It can also be freed from any character that /// may be occupying it. /// </summary> /// <param name="nodeIndex"></param> /// <param name="occupiedReason"></param> public void SetNodeOccupation(int nodeIndex, NodeType occupiedReason) { if (NodeIndexOutOfBounds(nodeIndex)) { Logger.LogWarning("Trying to occupy a node, but it is not possible because the node index is invalid."); return; } nodesTypes[nodeIndex] = occupiedReason; }
/// <summary> /// Creates the grid of nodes. /// </summary> public void CreateGrid() { DestroyGrid(); // TODO: Perhaps we might want to snap the extents value when editing the bounding box // in the editor? Bounds scanBounds = scanCollider.bounds; ScanAreaSettings scanSettings = new ScanAreaSettings((float3)scanBounds.center, (float3)scanBounds.extents, walkableMask); int expectedGridDimension = scanSettings.gridDimension; // TODO: Could I use nodesTypes invalid to avoid any kind of computation from them? nodesTransforms = new NativeArray <NodeTransform>(expectedGridDimension, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); nodesTypes = new NativeArray <NodeType>(expectedGridDimension, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); nodesNeighbors = new NativeArray <NodeNeighbor>(expectedGridDimension * NodeNumNeighbors, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); // calculate the initial raycast commands NativeArray <RaycastCommand> mainCommands = new NativeArray <RaycastCommand>(expectedGridDimension, Allocator.TempJob); JobHandle createNodesHandle = new CalculateRaycastCommandsJob { commands = mainCommands, scanSettings = scanSettings, } .ScheduleParallel(expectedGridDimension, 64, default(JobHandle)); // schedule the commands to retrieve the initial hits NativeArray <RaycastHit> nodeHits = new NativeArray <RaycastHit>(expectedGridDimension, Allocator.TempJob); createNodesHandle = RaycastCommand.ScheduleBatch(mainCommands, nodeHits, 32, createNodesHandle); JobHandle.ScheduleBatchedJobs(); // build the nodes using the received hits and the main raycast commands createNodesHandle = new CreateNodesJob { nodesTransforms = nodesTransforms, nodesTypes = nodesTypes, hits = nodeHits, commands = mainCommands, } .ScheduleParallel(expectedGridDimension, 32, createNodesHandle); // calculate the boxcasts to bake obstacles NativeArray <BoxcastCommand> boxcastCommands = new NativeArray <BoxcastCommand>(expectedGridDimension, Allocator.TempJob); JobHandle bakeObstaclesHandle = new CalculateBoxcastCommandsJob { commands = boxcastCommands, nodesTransforms = nodesTransforms, mask = obstacleMask, boxNodePercentage = boxToNodeObstaclePercentage, maxCharacterHeight = maxCharacterHeight, } .ScheduleParallel(expectedGridDimension, 64, createNodesHandle); // schedule the boxcasts to find possible obstacles NativeArray <RaycastHit> obstacleHits = new NativeArray <RaycastHit>(expectedGridDimension, Allocator.TempJob); bakeObstaclesHandle = BoxcastCommand.ScheduleBatch(boxcastCommands, obstacleHits, 32, bakeObstaclesHandle); // prepare the bake obstacles job bakeObstaclesHandle = new BakeObstaclesJob { nodesTypes = nodesTypes, boxcastHits = obstacleHits, } .ScheduleParallel(expectedGridDimension, 128, bakeObstaclesHandle); // now calculate the neighbors JobHandle calculateNeighborsHandle = new CalculateNeighborsJob { neighbors = nodesNeighbors, nodesTransforms = nodesTransforms, scanSettings = scanSettings, maxWalkableHeightWithStep = maxWalkableHeightWithStep, } .ScheduleParallel(expectedGridDimension, 32, createNodesHandle); JobHandle finalHandle = JobHandle.CombineDependencies(calculateNeighborsHandle, bakeObstaclesHandle); JobHandle disposeHandle = JobHandle.CombineDependencies(mainCommands.Dispose(finalHandle), nodeHits.Dispose(finalHandle)); disposeHandle = JobHandle.CombineDependencies(disposeHandle, boxcastCommands.Dispose(finalHandle), obstacleHits.Dispose(finalHandle)); // wait to complete all the scheduled stuff finalHandle.Complete(); gridWidth = scanSettings.gridWidth; gridDepth = scanSettings.gridDepth; isGridCreated = true; OnGridCreation?.Invoke(); Logger.LogFormat("Grid was created with dimension {0}. Width: {1}. Height: {2}.", expectedGridDimension, gridWidth, gridDepth); disposeHandle.Complete(); }