Procedural grid updating

I am not sure how I can achieve this, I want to be able to update my grid to follow my procedural infinite terrain.
Basically move the grid to the center of the 9 grids (1.5,1.5) Grids in the “Big tile”, but how would I do this, I would need to first, change the center, then update the height for the whole tile. Is there a more efficient way of doing this?
Note: I can’t seem to make sense of the procedural example scene.

Why doesn’t this code do the job?

`function UpdatePathFinding() {
var Center = Vector3(((CurrentTileX + 1) * terrainSize) - (terrainSize/2), 0, ((CurrentTileZ + 1) * terrainSize) - (terrainSize/2));

graph.center = Center;
graph.GenerateMatrix ();

var tmp = new GridNode[graph.nodes.Length];

var width = graph.width;
var depth = graph.depth;
var nodes : GridNode[] = graph.nodes;

for (var z = 0; z < depth; z++ ) {
	for (var x = 0; x < width; x++ ) {
		graph.UpdateNodePositionCollision(nodes[z*width + x], x, z, false);
		graph.CalculateConnections (nodes, x, z, nodes[z*width+x]);
	}
}

}`

Hi
Sorry for the late answer.

I would strongly suggest that you take a look at the procedural example scene again. I mean, you don’t have to understand the scripts, but it is definitely usable and follows the player. It also does it in a more optimised way (e.g it doesn’t recalculate the nodes in the middle of the graph, it just shifts them in one direction, the nodes at the edge of the graph will be shifted out of the graph and then placed at the other end, think of it like a conveyor belt, the nodes will fall off the edge of the belt and then be placed on the start of it again, in the middle of the belt the nodes don’t need to be updated).

Your code works for the most part. There are just some small tweaks.

  1. You need to call FloodFill after the update, that will recalculate the connected components in the graph which is necessary for pathfinding.

  2. You need to update the position for the nodes before you calculate the connections, otherwise when a node updates its connections, it will look at neighbours of which all might not have had their positions updated already.

  3. It is good practise to wrap it in a AstarPath.RegisterSafeUpdate, otherwise you might end up changing the graph at the same time as a pathfinding request was calculated, and that could cause odd paths to be generated.

Here is a rewritten script which I tested. I wrote it in C# because I know C# better than JS:
http://pastebin.com/X4c8NABj

This code seem to make the game lag for about a second:
`function UpdatePathFinding() {
if ( AstarPath.active == null || AstarPath.active.astarData == null) {
Debug.LogError(“There is no AstarPath object in the scene”);
}
var graph = AstarPath.active.astarData.gridGraph;
if (graph == null) {
Debug.LogError(“There wasn’t found any AStarPath component”);
}

var Center = Vector3(((CurrentTileX + 1) * terrainSize) - (terrainSize/2), 0, ((CurrentTileZ + 1) * terrainSize) - (terrainSize/2));
graph.center = Center;
graph.GenerateMatrix ();
			    
var width = graph.width;
var depth = graph.depth;
var nodes : GridNode[] = graph.nodes;

yield;

for (var z = 0; z < depth; z++ ) {
	for (var x = 0; x < width; x++ ) {
		graph.UpdateNodePositionCollision(nodes[z*width+x], x, z, false);
		if (z % depth && x % 15 == 0) {
			yield;
		}
	}
}

yield;

for (var z1 = 0; z1 < depth; z1++ ) {
	for (var x1 = 0; x1 < width; x1++ ) {
		graph.CalculateConnections(nodes, x1, z1, nodes[z1*width+x1]);
		if (z1 % depth && x1 % 15 == 0) {
			yield;
		}
	}
}

yield;

AstarPath.active.FloodFill();

}`
How can I optimize it?
The awake scan also takes 687ms, still 300x300
nodeSize = 2.5

2 questions:

What does this piece of code mean?
AstarPath.RegisterSafeUpdate (delegate () {});

Why do you call this 2 times?
graph.UpdateNodePositionCollision (nodes[z * width + x], x, z, false);

Normally pathfinding is running all the time, if you use multithreading, it is literally running at the same time as your game code. If you try to update the graph when pathfinding is running, you might get weird results, or in worst case, it could crash (multithreading can do horrible stuff sometimes, even things like “if (a != null) a.something()” could fail with a null reference exception).
The RegisterSafeUpdate method takes a callback, then it tells the pathfinding threads to finish calculating what they were doing and then stop, after the threads have stopped (which might be the next frame or even more frames if the current path takes a long time to calculate), it will call the callback.

  1. That’s a mistake, it shouldn’t be in the second loop.
    It doesn’t really change anything, but it is completely unnecessary.

If I have the threads set to 1 is that the main thread?

I don’t understand why you don’t use the ProceduralGridMover script. It does exactly what your script is supposed to do, but much faster.

Also, I would suggest that you do not yield there, that will cause even more problems if the pathfinding happens to be running at the same time.

Also
z1 % depth && x1 % 15 == 0
Does that even compile??

If I have the threads set to 1 is that the main thread?
No, that will run it in a single separate thread. Set it to None to run it in the Unity thread.
z1 % depth && x1 % 15 == 0

Does that even compile??


Yeah, it does :slight_smile:
I don't understand why you don't use the ProceduralGridMover script. It does exactly what your script is supposed to do, but much faster.
I will try, and I have a question concerning that, I should enabled floodfill right, and what does floodfill do?

Ah, you are using unityscript, not C#.

The graph is divided into multiple connected components, the pathfinding scripts use these to quickly abort if there is no possible path between two points (instead of searching the whole component which takes quite a lot of time). FloodFill is what recalculates these connected components.

Okay, so now I am trying to use the ProceduralGridMover, but can’t get it working, I call it like this:
player.GetComponent(ProceduralGridMover).UpdateGraph; //Because it is attached to my player.

Nvm, figured it out. Now I have another problem, I have to set the target to be the center of the middle tile, so I get the middle tile and add half the size of it to both x and z axis center and when the terrain then moves, the center’s x axis will follow while the z axis will stay the same. (0)

Code?