Finding too many closest nodes

I’m using this script here to find the closest node:

using UnityEngine;
using System.Collections;

public class FindNearestNode : MonoBehaviour {
	
	public GameObject closest;
	public string nodeTag = "NodeU";
	
    public GameObject FindClosestNode() {
        GameObject[] gos;
        gos = GameObject.FindGameObjectsWithTag(nodeTag);
        float distance = Mathf.Infinity;
        Vector3 position = transform.position;
        foreach (GameObject go in gos) {
            Vector3 diff = go.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance) {
                closest = go;
                distance = curDistance;
            }
        }
        return closest;
    }
}

But for some reason, the closest node keeps changing. The node isn’t moving, and neither is the character, so the closest node is the same, but it keeps changing. Instead of one node being found, it’s finding several of them, some of them that aren’t even close to the player. Why does this happen? I have another script that uses this script, which may be the problem. In the scene, too many nodes are tagged FinalNode, when only one should. Here’s the other script:

	public float speed;
	public float rotateDamp;
	
	public ArrayList nodes = new ArrayList();
	public ArrayList path = new ArrayList();
	
	public Transform closestNode;
	public Transform finalNode;
	
	public bool makePath = true;
	
	public Transform currentNode;
	private int currentNodeNumber;
	
	private float distance;
	
	private Transform AI;
	private Transform target;
	
	void Awake () {
	
		AI = transform;
	}

	void Start () {
	
		target = GameObject.FindWithTag("Player").transform;
		currentNode = path[0] as Transform;
	}
	
	void Update () {
		
		var rotate = Quaternion.LookRotation(currentNode.position - AI.position); 
        AI.rotation = Quaternion.Slerp(AI.rotation, rotate, Time.deltaTime * rotateDamp);
		AI.Translate(Vector3.forward * speed * Time.deltaTime);
	
		distance = Vector3.Distance(target.position, AI.position);
		Debug.Log(nodes.Count);
		
		Collider[] colls = Physics.OverlapSphere(AI.position, distance);
		var nodeUObjects = GameObject.FindGameObjectsWithTag("NodeU");
		var nodeUVObjects = GameObject.FindGameObjectsWithTag("NodeUV");
		
    	foreach (Collider col in colls){
			if(col.tag == "Node"){
				nodes.Add(col);
				col.tag = "NodeU";
			}
		}

    	foreach (GameObject obj in nodeUObjects) {
			float distanceU = Vector3.Distance(AI.position, obj.transform.position);
      		if(distanceU > distance) {
      			obj.tag = "Node";
				nodes.Remove(obj);
      		}
    	}
		
		foreach (GameObject obj in nodeUVObjects) {
			float distanceU = Vector3.Distance(AI.position, obj.transform.position);
      		if(distanceU > distance) {
      			obj.tag = "Node";
				nodes.Remove(obj);
      		}
    	}
		
		if(!makePath) return;
		
		FindNearestNode targetInfo = target.GetComponent<FindNearestNode>();
		targetInfo.FindClosestNode();
		finalNode = targetInfo.closest.transform;
		finalNode.tag = "FinalNode";
		
		FindNearestNode finder = AI.GetComponent<FindNearestNode>();
		finder.FindClosestNode();
		closestNode = finder.closest.transform;
		closestNode.tag = "NodeUV";
			
		FindNearestNode nodeInfo = closestNode.GetComponent<FindNearestNode>();
		nodeInfo.FindClosestNode();
		Transform nextNode = nodeInfo.closest.transform;
		nextNode.tag = "NodeUV";
		
		while(nextNode != finalNode){
			FindNearestNode nextNodeInfo = nextNode.GetComponent<FindNearestNode>();
			nextNodeInfo.FindClosestNode();
			nextNode = nextNodeInfo.closest.transform;
			nextNode.tag = "NodeUV";
			path.Add(nextNode);
		}
		
	}
	
	void OnTriggerEnter (Collider collider) {
	
		if(collider.gameObject.CompareTag("NodeUV")){
			currentNodeNumber ++;
			currentNode = path[currentNodeNumber] as Transform;
		}
		
		if(collider.gameObject.CompareTag("FinalNode")){
			makePath = false;
			speed = 0;
		}
	}
}

Your second code fragment is too much code to look at. However, some thoughts on the first section of code:

  1. I would calculate curDistance with Vector3.Distance(go.transform.position, position) although the results should be identical

  2. You are using a variable called “closest” which is defined as a Global. I think this is mistake. I think your FindClosestNode function should be saving the current closest node as a local and then returning that local at the end of the function.

The function FindClosestNode seems ok. I suspect that your problem is caused by the frequent tag changes. For instance: each Update you find the NodeU object nearest to the player and change it to FinalNode, thus each time a new NodeU object will be returned, until there’s no more NodeU’s except those found in OverlapSphere.

I honestly can’t understand what you’re trying to do, but the logic seems too complicated to work - and the whole thing is way too heavy to be done each Update, even more if several enemies run this same script!