How to search a List for GameObjects with tag and copy them into a new List

I’m trying to search a list for GameObjects with Children that are tagged “X”, then copy the Parents that have Children tagged “X” into a new list.

So far I haven’t found any examples of this :confused:

So, there is no ‘FindChildWithTag’ method unfortunately (and I have no clue why not).

You could loop over the list of GameObjects, and then get all children, and loop over them calling CompareTag on each one.

OR…

You could get all objects with said tag, loop over them, and then follow each up its parent chain up, and test if said list contains any of them (though I would suggest converting to a HashSet for faster contains testing).

Though honestly, I wouldn’t use a tag.

What is this tag for specifically? Could you instead use a component? Then just GetComponentInChildren to see if it exists?

1 Like

Loop through the gameobjects in your list. Then create a second loop within that loop to check the children and check each one to see if it has the proper tag. If you find one, add the gameobject(from the first loop) to the list and break out of the second loop since you found one child with the tag.

This would solve your question, but @lordofduct does mention other possible options depending on what your use case is.

1 Like

why not just tag the parents and add them?

This is what I have currently (it’s wrong)

            Debug.Log("Searching for Digital Projects");

            foreach (GameObject gameObject in searchingAndReplacingList.FindGameObjectsWithTag("Digital"))
            {
                newList = transform.parent.gameObject.Add;
            }
            Debug.Log("All GameObject Parents of Children tagged Digital have been added to newList");

            searchingAndReplacingList.Clear();
            Debug.Log("searchingAndReplacingList has been cleared");

            searchingAndReplacingList = newList.ToList();
            Debug.Log("newList has been copied into searchingAndReplacingList");

            newList.Clear();
            Debug.Log("newList has been cleared");

I am trying to emulate a multi-tag system, so I have multiple empties with tags as Children of the Parent, I need to check whether a Parent has two or more of the correct tags to know if I need to do something to it or not.

I think that’s kind of what I’ve done but it’s not working too well because I’ve done something wrong.

I need check whether the Parent has two or more correct tags, this is not achievable with one tag.

I think this is getting closer but still not right

        if (digitalProject)
        {
            /*/
             *  Search searchingAndReplacingList for GameObjects with Children tagged "Digital" and put Parents in newList
             *  Clear searchingAndReplacingList
             *  Copy newList to searchingAndReplacingList
            /*/
            Debug.Log("Searching for Digital Projects");

            foreach (GameObject gameObject in searchingAndReplacingList)
            {
                if (gameObject.tag == "Digital")
                {
                    newList.Add(transform.parent.GameObject);
                }
            }
            Debug.Log("All GameObject Parents of Children tagged Digital have been added to newList");

            searchingAndReplacingList.Clear();
            Debug.Log("searchingAndReplacingList has been cleared");

            searchingAndReplacingList = newList.ToList();
            Debug.Log("newList has been copied into searchingAndReplacingList");

            newList.Clear();
            Debug.Log("newList has been cleared");
        }
1 Like
public List<GameObject> parents;
public List<GameObject> filteredParents;

public void FilterList()
{
   for(int x = 0; x < parents.Count;x++)
   {
        foreach(Transform child in parents[x].transform)
        {
            if(child.gameObject.CompareTag("Digital")
            {
                 filteredParents.Add(parents[x];
                 break;
            }
        }
   }
}

I just typed that real quick, might be typos.

Also though, you could make a script on the parents with a string array and just put all the “tags” you need into there and then check that script to see if the array contains a “tag” that you need. Which would probably be the better way to go. Just a thought.

1 Like

Ohhh, you want a multitag system.

I created something like that a while back. Let me dig that up.

MultiTag:

TagData - a ScriptableObject allowing runtime access to known tags:

MultiTagInspector:

And a few find methods in GameObjectUtil:

It of course uses a few other things like UniqueToGameObjectMultitonPool for optimization purposes (it’s a fast lookup pool for special scripts):

Anyways, this is obvsly going to be a lot of code… you don’t really need to look at it directly, or emulate it exactly. I have lots of bells and whistles built into my system.

The point is, what I do is not create GameObjects as children. But rather instead stick a script on a GameObject called ‘MultiTag’, and tag it as ‘MultiTag’ (this signals that the GameObject is multitagged when searching).

The script then has an array in which what tags it has associated with it. It’s just a simple array.

Then the inspector for it just draws a pretty display for that array for adding and removing tags.

Everything else is just helper methods that tests if the GameObject is tagged directly OR if it’s tagged MultiTag it gets the script and checks its array.

1 Like

There are also other MultiTag systems in the AssetStore and other places.

Mine is part of my framework, which makes it hard to implement in your project without taking the entire framework… or you having to be good enough at code to rip it out.

So I’d suggest looking around for other MultiTag systems similar to mine.

In the end, I think you should go with this script based approach rather than child GameObjects.

1 Like

Thank you I had been blundering about for some time with this.

Many thanks I haven’t seen these before, I did try a different multi-tag system and it didn’t work so I attempted to create my own solution :confused: