- Home /
Find child of a Game Object using tag
Hello,
So I have a Game Object in my scene with 4 child. I want to put the 4 child in a GameObject[]. I have this code :
var other : GameObject;
var gos2 : GameObject[];
gos2 = other.FindGameObjectsWithTag("Cover Node");
Instead of listing the 4 child of other(Game Object) it list all the game objects with the tag Cover Node. Do you have any solution?
Have A Nice Day
NbO
Answer by Piflik · Jul 16, 2012 at 08:12 PM
Try something like this. It is an edited part of a script that I (successfully) use in my game (I look for only one item and don't store it in an array).
for(var child : Transform in transform){
if(child.gameObject.tag == "Cover Node"){
gos2.Add(child);
}
}
(As it is now, the script has to be attached to the parent of the objects. If you want to have this script on an unrelated object, you'd have to write 'for(var child : Transform in other.transform)', where other is the same variable you use in the script you posted)
It's telling that Add it's not a part of Unity GameObject[]
Oh....right...'Add()' doesn't work with the builtin arrays...let's try again ;)
var tempcounter : int = 0;
for(var child : Transform in transform){
if(child.gameObject.tag == "Cover Node"){
gos2[tempcounter] = child;
tempcounter++;
}
}
Cannot convert 'UnityEngine.Transform' to 'UnityEngine.GameObject'. It seems that child is a Transform am I right?
IndexOutOfRangeException: Array index is out of range. (wrapper stelemref) object:stelemref (object,intptr,object) PrototypeCoverSystemAI.FindBestCoverNode () (at Assets/PrototypeCoverSystemAI.js:37) PrototypeCoverSystemAI.Update () (at Assets/PrototypeCoverSystemAI.js:11) ;)
Answer by delstrega · Jul 16, 2012 at 04:14 PM
This should return all child GameObjects of a given object (even deactivated ones):
function GetChildGameObjects(theParent : GameObject) : GameObject[]{
var tempTransforms : Transform[];
tempTransforms = theParent.GetComponentsInChildren(Transform, true);
var children: GameObject[] = new GameObject[tempTransforms.length-1];
for(var i=0; i < tempTransforms.length-1; i++){
children[i] = tempTransforms[i+1].gameObject;
}
return children;
}
Use it like this:
gos2 = GetChildGameObjects(other);
EDIT: Just remembered that GetComponentsInChildren returns the parent too, so I adjusted the code accordingly to only return the children, excluding the parent.
Thank you for the fast feedback let me try it and accept your answer as correct one.
Get This : Assets/PrototypeCoverSystemAI.js(12,13): BCE0017: The best overload for the method 'PrototypeCoverSystemAI.test(UnityEngine.GameObject)' is not compatible with the argument list '()'.
It is not related to the code he gave you. The error tells you provided the wrong parameter to the method PrototypeCoverSystemAI.test().
it's worth noting that you don't want to be doing this sort of searching very often. It's the sort of thing you might do at startup, but don't do it every frame!
If, as suggested by your question, you're looking for nodes for AI to run to, you might want to cache the node somehow or arrange them so they can be easily found.
For instance: add triggers to your cover objects and at the point the AI decides it needs to find cover, you could do an overlap sphere or cast to deter$$anonymous$$e where the nearest bit of cover is. You'd do this once, cache the result and then manage the business of dashing over to the cover. You could put AI stuff on an AINodes layer and limit your overlap or cast to that layer, speeding it up.
I'm pretty sure the above will be quicker, although a desktop machine might not grumble at it too much. It's still a good idea to follow this approach.
Answer by siddharth3322 · Aug 27, 2014 at 03:35 AM
Here is C# code for similar.
private List<GameObject> spawnPoints = new List<GameObject>();
void Start(){
PrepareSpawnPointList();
}
private void PrepareSpawnPointList(){
foreach(Transform child in transform){
if(child.CompareTag(GameConstants.TAG_SPAWN_POINT))
spawnPoints.Add(child.gameObject);
}
}
You directly use this code for your purpose.
Answer by Dune2 · Sep 30, 2016 at 02:18 PM
If you're using C#, and you want to find within nested children, then you may find either of the following extensions helpful.
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
public static class TransformExtensions
{
/// <summary>
/// Find all children of the Transform by tag (includes self)
/// </summary>
/// <param name="transform"></param>
/// <param name="tags"></param>
/// <returns></returns>
public static List<Transform> FindChildrenByTag(this Transform transform, params string[] tags)
{
List<Transform> list = new List<Transform>();
foreach (var tran in transform.Cast<Transform>().ToList())
list.AddRange(tran.FindChildrenByTag(tags)); // recursively check children
if (tags.Any(tag => tag == transform.tag))
list.Add(transform); // we matched, add this transform
return list;
}
/// <summary>
/// Find all children of the GameObject by tag (includes self)
/// </summary>
/// <param name="gameObject"></param>
/// <param name="tags"></param>
/// <returns></returns>
public static List<GameObject> FindChildrenByTag(this GameObject gameObject, params string[] tags)
{
return FindChildrenByTag(gameObject.transform, tags)
//.Cast<GameObject>() // Can't use Cast here :(
.Select(tran => tran.gameObject)
.Where(gameOb => gameOb != null)
.ToList();
}
}
You would in the OP's case use it like.
var other : GameObject;
var gos2 : GameObject[];
gos2 = other.FindChildrenByTag("Cover Node").ToArray();