I copied a video tutorial on how to make a ai that patrols, chases the player, than attacks. I am making a simulation where creatures go around and am using the script to make them eat plants. I currently have it where
Plant = FindGameObject(“plant”).transform;
But this was for when there is only one player. Since i will need several tags i need to set the plant to be the closest object with the plant tag instead. How do i do this
Not sure which method you’re referring to in your code since ‘FindGameObject’ isn’t a method. Do you mean ‘GameObject.Find’? But that doesn’t find by tag, that finds by name.
There is also GameObject.FindWithTag:
But that only returns the first one it finds. If you want to find any of them with a tag, then you’re going to have to first get all the GameObjects with the tag via FindGameObjectsWithTag:
Then you loop over it and you check the distance from some position and take the nearest.
var arr = GameObject.FindGameObjectsWithTag("plant");
var pos = transform.position; //assuming this code is running on the gameobject you want to find closet to
float dist = float.PositiveInfinity;
GameObject nearest = null;
foreach(var go in arr)
{
var d = (go.transform.position - pos).sqrMagnitude; //use sqr magnitude as its faster
if (d < dist)
{
nearest = go;
dist = d;
}
}
//nearest if not null is the nearest gameobject. If null no gameobject was found
Of course this all is a very naive approach to the task you’re attempting to accomplish. Using tags and FindGameObjectsWithTag is slow and creates a lot of garbage. Usually you would cache a collection of all available targets and then just access that collection. Instead of querying all of them every time you want to test.
A simple way of doing this is just have a Plant class attached to all Plants and on start add it to the collection, and on destroy remove it.
public class PlantComponent : MonoBehaviour
{
public static readonly HashSet<PlantComponent> AllPlants = new HashSet<PlantComponent>();
void Start()
{
AllPlants.Add(this);
}
void OnDestroy()
{
AllPlants.Remove(this);
}
}
Heck you could even streamline the above loop with some linq (though yes linq does create a little garbage… just negligible).
var pos = transform.position;
var nearest = PlantComponent.AllPlants.OrderBy(go => (go.transform.position - pos).sqrMagnitude).FirstOrDefault();
Though really, the foreach loop from before is faster than this. The orderby will create a delegate and other garbage, and it’ll do a full sort which scales non-linearly the more plants there are… where as the for loop is a simple O(N) query. But I figured I’d just show you another example just to demonstrate there’s always more than 1 way to skin a cat.
Am having trouble understanding because am still kind of new but i think i kind of understand but is this code JavaScript because i use c# and i don’t know too much about java
Then maybe we can give you more specific help relative to your specific code as it appears you’re still rather new to C# in general and are having a hard time just understanding scope, data types, or even the syntax of C#.