Better way to penalty for stationary units

I am using grid graph and I am having dificult to change node penalty when a unit stop. After a lot of random programing I finished with something like the code below, not so beatiful, but functional.

The problem is that some times, expecially when I create many units near of same node, I receive the warning log (see LogWarning below) and could not restore node penalty.

Everything indicates that it was caused by nodes assyncronos update, I try to remove the penalty before it had been applied. I can’t remove the if because it could cause numeric underflow, probably I can solve by creating a custom GraphUpdateObject to check for underflow and then apply.

Something is smelling bad here. Some one know a better way or it is ok with the path that I choose? Because I desire to use AlternativePath and things will become more fun :stuck_out_tongue:

`private var node: Node;

function Start() { 
    OnStop();
}

function OnStop() {
	node = AstarPath.active.GetNearest(transform.position).node;
	var bounds = new Bounds(node.position,new Vector3(0.1f,0.1f,0.1f)); 
	var update = new GraphUpdateObject(bounds);
	update.addPenalty = PENALITY_BLOCKED;
	update.requiresFloodFill = false;
	update.resetPenaltyOnPhysics = false;
	update.updatePhysics = false;
	AstarPath.active.UpdateGraphs(update);
}

function OnMove() {
	if (node.penalty >= PENALITY_BLOCKED) {
		var bounds = new Bounds(node.position,new Vector3(0.1f,0.1f,0.1f));
		var update = new GraphUpdateObject(bounds);
		update.addPenalty = -PENALITY_BLOCKED;
		update.requiresFloodFill = false;
		update.resetPenaltyOnPhysics = false;
		update.updatePhysics = false;
		AstarPath.active.UpdateGraphs(update);
	} else {
		Debug.LogWarning("Invalid node penalty " node.penalty);
	}
}`

Ok, so OnMove is called before the OnStop GUO has been applied. Actually, just as long as you are sure that OnStop has issued a GUO already, you can safely call UpdateGraphs with the new GUO. GUOs are put in a queue so they will be applied sequentially.

The solution you have is otherwise a good one as far as I can see.

PS: Yay, it’s nice to see people using all useful settings to gain performance like requiresFloodFill = false.

Really thanks. When you are lost, it is good to receive a simple approve.

About underflows. I didn’t know the reasons why there is no bound check on GraphUpdateObject.Apply, but in scenaries where you must reduce penalty assynchronous could be really nice addition. I will create my custom GraphUpdateObject.

PS: I change requiresFloodFill more by random to reduce amount of changes that really knowing what I was doing :stuck_out_tongue:

Hi, I am making a RTS and I tried this so that the path generated avoids units. However, my units aren’t moving at all.

I called OnStop() in the Awake(). Whenever I set a new destination, I call OnMove() and then set CanMove to true. If I dont call OnStop() nor OnMove() my units move.

Could you help me with this problem? Not sure why it ain’t working.

if (hit.transform.tag == "Terrain") { mover.objetivo = targetPoint; mover.OnMove(); mover.canMove=true; }

Here are the functions posted in the link:

` public void OnStop() {
node = AstarPath.active.GetNearest(transform.position).node;
Bounds bounds = new Bounds (new Vector3(node.position.x,node.position.y,node.position.z), new Vector3 (0.1f, 0.1f, 0.1f));
guo = new GraphUpdateObject(bounds);
guo.addPenalty = Penalty;
guo.requiresFloodFill = false;
guo.resetPenaltyOnPhysics = false;
guo.updatePhysics = false;
AstarPath.active.UpdateGraphs(guo);
}

public void OnMove() {
	if (node.Penalty >= Penalty) {
		Bounds bounds = new Bounds(new Vector3(node.position.x,node.position.y,node.position.z),new Vector3(0.1f,0.1f,0.1f));
		guo = new GraphUpdateObject(bounds);
		guo.addPenalty = -Penalty;
		guo.requiresFloodFill = false;
		guo.resetPenaltyOnPhysics = false;
		guo.updatePhysics = false;
		AstarPath.active.UpdateGraphs(guo);
	} else {
		Debug.LogWarning("Invalid node penalty " + node.Penalty);
	}
}`

I’m getting NULLReference exceptions in:

node = AstarPath.active.GetNearest(transform.position).node;

and

if (node.Penalty >= Penalty)
Thanks in advance