Trouble with Vector3.Angle() and RotateAround()

Hello everyone, I’m scripting a “turret” that looks at a target position (ignoring the Y difference between the two if any).

Unfortunately I’ve become stuck on a problem where I can never (on purpose) get Vector3.Angle() to be 0. At this point, the value will become close to 0 (say 0.03) then start flipping back and forth between the positive and negative value of that small number) which you can see in the screenshot. Occasionally, the value does become 0, but I don’t know why.

I thought that the way I have the relevant part of this script would handle this (in that the desired rotation amount, at a small value, becomes the remainder of the current rotation to 0, meaning the angle should be 0 on the next frame), but obviously it does not.

				//check if the Turret has a clear los according to whatever its impassible layers are:
				Debug.DrawLine(transform.position, currentTargetPosition, Color.red);
				if(!Physics.Linecast(transform.position, currentTargetPosition, impassibleLayer) ) //if raycast dosen't hit anything...
				{
					if(turretCentered) //update Turret so it knows it is not centered anymore
					{
						turretCentered = false;
					}
					
					//Turret does not care about any Y position differences...
					Vector3 currCustom = currentTargetPosition;
					currCustom.y = transform.position.y; //ignore Y differences...
					
					Vector3 directionVector = currCustom - transform.position;
					
					float angle = Vector3.Angle(transform.forward, directionVector);
					Debug.Log("angle is: " + angle);
					
					float rotAmount = maxRotationSpeed * Time.deltaTime;
					Debug.Log("initial rotAmount is: " + rotAmount);
					
					if(Mathf.Abs(angle) - Mathf.Abs(rotAmount) <= 0f) //don't overshoot desired angle (which is 0)...
					{
						//Debug.Log("RotateTurret() breaking...");
						//Debug.Break();
						
						rotAmount = angle; //set rotation amount to the remaining angle...
						Debug.Log("rotAmount = angle: " + rotAmount);
					}
					
					//now figure out if turret should rotate to the left or right:
					if(Vector3.Cross(transform.forward, directionVector).y < 0f)
					{
						//Debug.Log("cross.y is <= 0f");
						rotAmount = -rotAmount;
					}
					else
					{
						//Debug.Log("cross.y is > 0f");
					}
					
					Debug.Log("final rotAmount is: " + rotAmount);
					transform.RotateAround(transform.position, transform.up, rotAmount);
					//

Any ideas on what is happening is appreciated, thank you for reading.

I just skimmed the first part and glanced at the script, but: Unity has RotateTowards (and MoveTowards) for just such overshoot problems. Both are written so they will never overshoot, and do nothing if you are at the target.

They aren’t complicated, and easy to write yourself (it looks like you did?) but they make code a little nicer. I suspect your overshoot math may have a problem.

RotateTowards always make the one most direct rotation – it picks the rotation axis itself. Which is often what you really wanted. But, seems you could use MoveTowards directly on your angle var.