Normalized Vector reversing direction unexpectedly

I’m writing a script to have an enemy run from anything tagged as a player.

This is the function where it checks to see if any players are within its sight radius, and if so calculates the sum of the vectors to each of them, flips the x and z components so as to get the exact opposite direction and then normalizes the vector which is then returned and used to by a different function to move it in that direction.

90% of the time this works as desired, but the other 10% of the time, it will suddenly change directions and start moving back towards the player and once on the other side of them, begin fleeing normally again.

Through the use of log messages, I’ve been able to figure out that it happens around the time that either the “x” or “z” values start approaching +/- 1. It appears that they change direction when they reach this threshold, and I’m pretty certain that this happens as a result of the normalization process.

I’m pretty new to unity and vectors aren’t really my strong suit so I’m not sure what to do with this information to fix it.

public static Vector3 observeForFlee(Vector3 center, float radius, string refTag) {

		Vector3 detectTotal = Vector3.zero;	//zero out summation vector
		bool detected = false; //flag variable to allow different behavior when nothing detected

		Collider[] seenObjects = Physics.OverlapSphere(center, radius); //observe all game objects within radius

		//cycle through all seenObjects
		for (int i = 0; i < seenObjects.Length; i++) {
			if(seenObjects*.gameObject.transform.tag == refTag){ //if tagged with specified name*

_ Vector3 detectCurrent = seenObjects*.gameObject.transform.position; //calculate direct vector*_
* detectCurrent.y = 0f; //zero out the y component - unneeded for my scenario*
* detectTotal = detectTotal + detectCurrent; //add vector to any other vectors of detected objects*
* detected = true; //put flag up*
* }*
* }*
* if (detected) {*
* //behavior is to go in best opposite direction so I flip the x and z components and the normalize*
_ Vector3 fleeVector = new Vector3(detectTotal.x * -1, 0, detectTotal.z * -1).normalized;_
* return fleeVector;*
* }*
* else {*
* //sentinel value checked outside of function*
* return Vector3.zero;*
* }*
* }*

Well, what bugs me a little here is that you get all players location, based from world center, not enemy center. You don’t have a reference point to where the enemy stands, except for when you gather which players are in the sphere. Your coordinate systems won’t add up. I think it should be fixed if you change detectCurrent though:

Vector3 detectCurrent = seenObjects*.gameObject.transform.position - center;*

And if you want an explanation why, read on. Otherwise, the above change should suffice.
Without the correction with - center, it would only work correctly if the enemy was standing at (0, 0, 0). Imagine if the enemy was standing at (100, 0, 100) and a player was standing next by it at (101, 0, 100) (1 unit to the right of the enemy).
// Renaming expressions to make it clearer to follow:

// Vector3 detectCurrentBroken = seenObjects*.gameObject.transform.position;*
// Vector3 detectCurrentBroken = player.position;
Vector3 detectCurrentBroken = (101, 0, 100);

// Vector3 detectCurrent = seenObjects*.gameObject.transform.position - center;*
// Vector3 detectCurrent = player.position - center;
// Vector3 detectCurrent = player.position - enemy.position;
Vector3 detectCurrent = (101, 0, 100) - (100, 0, 100);
Vector3 detectCurrent = (1, 0, 0);
Normalizing (101, 0, 100) would give you a “right + forward” direction, but the player was standing to the right of the enemy, not in front of the enemy.
Normalizing (1, 0, 0) would give you a “right” direction, which makes sense since the player was standing on the right side of the enemy.