Accuracy issues with Float (Vector3)


I wrote an NPC movement script, which includes the rotation of the NPC-character in order to make it look forwards after changing its direction. It works like follows: After the movement to a certain point, it the NPC turns around until the correct rotation is reached, and then starts moving.

The problem is that it sometimes get stuck at rotating. Obviously this is caused by the floating point inaccuracy. I checked that by printing the result of the == opertion where I compare the normalized vectors, and it returns false. I also printed the values of the vectors to see how big the inaccuracy is:

(0.9831, 0.0000, 0.1830)
(0.9824, 0.0000, 0.1866)

I know that the == operator has approximation integrated, so I am quite astonished that this simple rotation already causes problems.

Are there any ways to prevent this (globally or in that special case). I honestly don’t even know if the script does a good job, I started with unity a few days ago. Any advice would be appreciated.

Here the complete code. Nothing is accessed by other scripts.

public class Patrol : MonoBehaviour {
    public Transform[] patrolPoints;
    private Transform current;
    private int currentPoint = 0;
    public float moveSpeed;
    public float animSpeed = 1.5f;
    private Animator anim;

    public float rotationSpeed;

	void Start () {
        transform.position = patrolPoints[currentPoint].position;
        current = patrolPoints[currentPoint];
        anim = gameObject.GetComponent<Animator>();
        anim.speed = animSpeed;
        anim.SetFloat("Speed", moveSpeed);

    private bool rotating = false;
    void Update() {
        if (equals(transform.position,current.position))
            currentPoint = (currentPoint + 1) % patrolPoints.Length;
            current = patrolPoints[currentPoint];
            rotating = true;

        if (!rotating)
            transform.position = Vector3.MoveTowards(transform.position, current.position, moveSpeed * Time.deltaTime);
        else {
            Vector3 targetDir = current.position- transform.position ;
            transform.rotation = Quaternion.LookRotation(Vector3.RotateTowards(
               targetDir, rotationSpeed*Time.deltaTime, 0));
            if (equals(targetDir.normalized, transform.forward.normalized))
                rotating = false;

I believe you may need to mess around with this Mathf function. Unity - Scripting API: Mathf.Approximately

You’ve been misinformed. The == operator is an equality operator and does not have any checks for approximation. This is why Mathf.Approximately exists.

Personally, I believe there’s something in your code for rotation or movement that you can change in order to fix this issue. However, what you can do is create your own form of Approximately, like I do on occasion:

public bool Approximately(float a, float b, float epsilon)
	return (Mathf.Abs(a - b) < epsilon) || (Mathf.Approximately(Mathf.Abs(a - b), epsilon));

//or JS:

function Approximately(a : float, b : float, epsilon : float) : float
	return (Mathf.Abs(a - b) < epsilon) || (Mathf.Approximately(Mathf.Abs(a - b), epsilon));

epsilon is the maximum distance between two floats that you’ll accept as approximately.

Approximately(0.05f, 0.1f, 0.05f) //will return true
Approximately(0.06f, 0.1f, 0.04f) //will return true
Approximately(0.05f, 0.1f, 0.06f) //will return false