- Home /
How can I make my gameObject find the nearest object with a specific tag and rotate to look at it?
Hi everyone
I'm rather new to Javascript and I've been experimenting with it for the past 3 days and read a lot of tutorials and forum posts - thanks in advance for those.
What I can't figure out is how to have an object look at the nearest other object with a certain tag. I know I need an array for it and I've found some code for similar functions, but they either don't seem to work or do something I don't need to.
Could anyone maybe assist me in how to write this?
What I need is to have the object that code is attached to find the closest object with a specific tag (say "waypoint") and then look at it.
Any help is much appreciated, thank you.
Answer by duck · May 05, 2010 at 09:26 AM
Something along these lines should be what you're after:
(Edit : now tested & working!)
// the tag to search for (set this value in the inspector) var searchTag = "Respawn";
// the frequency with which to re-scane for new nearest target in seconds // (set in inspector) var scanFrequency = 1.0;
// the current target private var target : Transform;
function Start() { // set up repeating scan for new targets: InvokeRepeating("ScanForTarget", 0, scanFrequency ); }
function Update() { // we rotate to look at the target every frame (if there is one) if (target != null) { transform.LookAt(target); } }
function ScanForTarget() { // this should be called less often, because it could be an expensive // process if there are lots of objects to check against target = GetNearestTaggedObject();
}
function GetNearestTaggedObject() : Transform { // and finally the actual process for finding the nearest object:
var nearestDistanceSqr = Mathf.Infinity;
var taggedGameObjects = GameObject.FindGameObjectsWithTag(searchTag);
var nearestObj : Transform = null;
// loop through each tagged object, remembering nearest one found
for (var obj : GameObject in taggedGameObjects) {
var objectPos = obj.transform.position;
var distanceSqr = (objectPos - transform.position).sqrMagnitude;
if (distanceSqr < nearestDistanceSqr) {
nearestObj = obj.transform;
nearestDistanceSqr = distanceSqr;
}
}
return nearestObj;
}
Thank you. Unfortunately, this doesn't seem to work when I copy it into an empty Javascript. The script then gives me a load of errors (mainly semicolons missing and unity.Engine errors).
An idea why that might be? Thank you very much for your help so far.
Code is now tested and fixed! (had a few accidental pieces of c# syntax in there before!)
Awesome! this works for me... i've been atempting the same, you're a genius!!! :D
Answer by user-2441 (google) · May 06, 2010 at 10:42 PM
I was guided to the answer I was looking for, thank you very much! Here is the working code:
function Update () { var waypoints: GameObject[] = GameObject.FindGameObjectsWithTag("waypoint"); var closest: GameObject; var closestDist = Mathf.Infinity;
for (waypoint in waypoints) {
var dist = (transform.position - waypoint.transform.position).sqrMagnitude;
if (dist < closestDist) {
closestDist = dist;
closest = waypoint;
}
}
transform.LookAt(closest.transform);
}
How would i make a statement like if(waypoint > lastwaypoint)... ??? I must know if every waypoint has passed...
Thanks
tweaked it a bit ... and attached it with a collider to the water prefab.working great.thanks.now i can easily respawn my car from the last waypoint
for anyone else wondering what < is, it means "less than". I tried your code and it threw an error with < Replacing it with < worked. Thumbs up for your solution
Answer by BocoProgrammer · Sep 12, 2010 at 07:56 PM
hey man I noticed that Closest distance never resets and if it does it messes up my targeting here is what I have man see what you think it doesnt use LOOK AT because my code you can slow down the turret so if you wanted a huge battleship cannon you can do that with my code.
var closestDist = Mathf.Infinity;
var attackRange = 30.0; var shootAngleDistance = 10.0;
var closest: GameObject;
function Update () {
var waypoints: GameObject[] = GameObject.FindGameObjectsWithTag("waypoint");
for(waypoint in waypoints) { var dist = (transform.position - waypoint.transform.position ).sqrMagnitude;
if(dist <= closestDist)
{
closestDist = dist;
closest = waypoint;
}else
{
closestDist += 100;
}
//Debuging ClosestDist
if(Input.GetKeyDown("t"))
{
print("ClosestDist: " + closestDist);
}
var targetPoint = closest.transform.position;
var targetRotation = Quaternion.LookRotation ( targetPoint - transform.position , Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0);
// If we are almost rotated towards target - fire one clip of ammo
var forward = transform.TransformDirection(Vector3.forward);
var targetDir = closest.transform.position - transform.position;
if (Vector3.Angle(forward, targetDir) < shootAngleDistance && closest.gameObject.tag == "waypoint")
SendMessage("Fire");
}
}
This sort of works but has a few issues. 1. It does not seem to do clean up for destroyed objects. $$anonymous$$issingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
When new objects are spawned, the rotation gets confused and the rotation stops offest or between the "waypoints"
Any ideas on how to fix these issues?
Answer by luozitian · May 03, 2012 at 07:07 AM
just add one target transform and ignoring the Y axis and so this script can attached any object and can specify the transform
function GetNearestTaggedObject(searchTag : String,otherTrans: Transform) : Transform { // and finally the actual process for finding the nearest object:
var nearestDistanceSqr : float = Mathf.Infinity;
var taggedGameObjects : GameObject[] = GameObject.FindGameObjectsWithTag(searchTag);
var nearestObj : Transform = null;
// loop through each tagged object, remembering nearest one found
for (var obj : GameObject in taggedGameObjects) {
var objectPos = obj.transform.position;
var distanceSqr = (objectPos - Vector3(otherTrans.position.x,objectPos.y,otherTrans.position.z)).sqrMagnitude;
if (distanceSqr < nearestDistanceSqr) {
nearestObj = obj.transform;
nearestDistanceSqr = distanceSqr;
}
}
return nearestObj;
}
Answer by Bryan-Legend · Nov 08, 2013 at 11:00 PM
Here's a method that I created to do this in C#. It also uses a helper method from my utility class.
void SelectClosest()
{
const int maxSelectionDistance = 2;
Selected = null;
var closestDistance = Single.MaxValue;
foreach (var selectable in GameObject.FindGameObjectsWithTag("Selectable"))
{
var distance = gameObject.DistanceSquaredTo(selectable);
if (distance < closestDistance && distance < maxSelectionDistance * maxSelectionDistance)
{
closestDistance = distance;
Selected = selectable;
}
}
}
public static float DistanceSquaredTo(this GameObject source, GameObject target)
{
return Vector3.SqrMagnitude(source.transform.position - target.transform.position);
}
Yes, I'm sure. Var can be used for local variables since C# 3.0 (2007). The compiler can infer the type from the statement.
Your answer
![](https://koobas.hobune.stream/wayback/20220612212613im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Locking onto enemies with the third person controller 2 Answers
Problem with the direction of the raycast when rotating 1 Answer
I wanna use Gameobject.Find(string name, bool active) 3 Answers
Moving a GameObject (camera) forward and backward along a series of points (C#). 1 Answer
velocity direction 1 Answer