RVO Controller and Terrain Slope

Hi Aron,

I have the Pro version of the A* Pathfinding Project and I’m working with your RVO obstacle system. I havn’t worked with Unity’s character controller much, so I’m not too familiar with it. I was using a rigidbody + collider for the longest time, until I bought your package.

My problem is this: When my units come to the end of their path they sometimes start rotating endlessly about a point on the ground, like they refuse to just stand up straight and face forward. I’ve tried offsetting the path’s endpoint by a certain y-axis amount, but that didn’t work. I’ve tried modifying the vectorpath itself. And I’ve tried messing with the rotation, the rigidbody settings etc… But nothing I’ve tried has kept the units from “freaking out” at the end of their paths.

Again this only happens at the end of a path, and usually if the terrain is sloped at the end of the path. I have a feeling it’s something I’m doing wrong with my own code, but I just wanted to see if you had any ideas. So, my main question is, how can I force my units to remain upright at the end of their paths?

My first guess would be an offset error, something that is a sad by true consequence of most all pathfinders, luckily its an easy fix :slight_smile:

With any path finding solution its best to do all the movement from a position exactly on the graph. Then offset all your meshes and colliders to make the unit look like its walking above the graph~

So if you have a 3f tall unit, you want to the meshes and colliders to be 1.5f above the unit.transform.

BUT, if that’s not the issue~ I got some tests for you

#1!! Check if its a RVO raycast issue, you can do this by either disabling the Raycasting function in the RVO Controller script… Or you can download My Stable RVO Controller beta update thingy and just replace it at (AstarPathfindingProject/RVO)~

FYI there will be two new check boxes in the inspector, turn off raycasting there:

#2!! Check if its a collider issue by… turning off the collider?? :stuck_out_tongue:

#3!! Check if the Endpath is not being called by inserting a Debug.Log(“Something”) to the appropriate location in your code

Thanks Burdock, I will hopefully be able to work on it some more tomorrow and let you know if anything works. Thanks for the reply.

Np, I ran in to this same issue my self and had to do quite a few things to end up fixing it(My bugs was pretty large, units walking under slopes, colliders freezing unity, and the above)~

So if you cant solve it with the above info, I can always cross reference your scene and scripts :slight_smile:

Just wanted to give an update so far. I was finally able to work on it a little bit today, and I figured out some new info.

My main problem (in my case), with the units rotating around at the end of a path, had to do with the “nextWaypointDistance” variable. For some reason, when adding the RVO controller to a unit, if the nextWaypointDistance is too small, it won’t detect that the unit has completed the path, and so it never sets the path null. So like you suggested Burdock, the Endpath was not being called.

Once I set the nextWaypointDistance to a much larger number, the endpath was detected, and my endpath code runs okay. The drawback to this, is that I can’t get pinpoint accuracy on where my units are supposed to end their paths, since I’m forced to increase the nextWaypointDistance.

I’m now getting some other issues that you mentioned, such as units going underneath the terrain now, and staying underneath it. My next project is to get the units to always face the direction the RVO controller is leading it, instead of at the next waypoint like I have it now. I guess that’s the life of a game programmer though lol. Thanks for the help Burdock.

Lucky you, I have solved most of these issue :slight_smile:

Here is my turning code~
`
public void TurnAB(float UnitTurnSpeed, Vector3 LastPosition){
if(LastPosition == Vector3.zero){
return;
}

	Vector3 LookAt = Player.position - LastPosition;
	
	if(LookAt == Vector3.zero){
	 return;	
	}
	
	Quaternion LookRotation = Quaternion.LookRotation(LookAt);
	Quaternion rotation = Quaternion.Slerp(Player.rotation, LookRotation , Time.deltaTime * UnitTurnSpeed);
	Player.rotation = Quaternion.Euler(0, rotation.eulerAngles.y, 0);
}
`

This keeps the unit always looking away from its last position, it seems to work pretty well :slight_smile:

Also, make sure you don’t look at the point exactly one frame ago… at very heigh frame rates This can cause some major jitter (160+ for my game)

Also note~ When moving from a End path to a start path this can bug out… its best to new path best passed instantly

Something like this helps, it makes a 2 frame list
`
public List LastPositionList;
private Vector3 LastPosition;

void LastPositionCheck(){
if(TIMESCALE != 1){
StopCheck();// not important
return;
}
if(LastPositionList.Count >= 2){
LastPositionList.Add (this.transform.position);
LastPosition = LastPositionList[0];
LastPositionList.RemoveAt(0);
}

	else{
		LastPositionList.Add (this.transform.position);
	}
}`

Now as for smoothing~ Just make the smoothing for the last waypoint smaller then the rest:
Here is my code:
Whatever your units movement speed * Time.deltaTime * 4 is the smallest value I call 99.9% safe… this way at low fps it scales :slight_smile:
`
if (NextGridSpace >= CurrentPath.vectorPath.Count-1){
Smoothing = (UnitSpeed*Time.deltaTime)*4;
}
if (NextGridSpace >= CurrentPath.vectorPath.Count){
//If where I am now is the end of the path…Reset smooting, and Return
Smoothing = 3f;
Debug.Log (“end path called”);

		}

`