- Home /
Other
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;
}
}
}
Answer by kolban · Apr 09, 2012 at 01:01 AM
Your second code fragment is too much code to look at. However, some thoughts on the first section of code:
I would calculate curDistance with Vector3.Distance(go.transform.position, position) although the results should be identical
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.
Normally it was a local, but it throws up an unassigned use of local variable error.
Answer by aldonaletto · Apr 09, 2012 at 03:15 AM
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!
Yeah I realized that, and I found the script too impractical for what I was trying to do. I'm starting over with a new strategy to figure out my original plan, and you can be sure to see some questions regarding that ;) Thanks anyways
Follow this Question
Related Questions
Count the contents of the list from FindGameObjectsWithTag 1 Answer
Find the first game object created with a given name 1 Answer
How do I find the closest target with a tag? c# 2 Answers
Count objects with a certain tag and display number on GUI 1 Answer
My AI code is only making a sprite look Left or Right? Help please. 1 Answer