Unity C# - How to get child gameobjects (+ Extension Methods)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello again in this tutorial i'd like to show you how to get the children of any game object you have in your scene if you'd like to jump straight to the code it's in the description below for you uh please leave a like if that helps you out okay so as a quick demonstration here you can see we have a small hierarchy of game objects in unity it doesn't matter what they're named but here we have parent we have three children and then we have a bunch of sub-children under those children this parent game object here at the top of the hierarchy is the one we're going to be using in this video to retrieve all of its child game objects right here so looking at this card the code that we'll be writing will allow us to get these children here in multiple different ways the first will be to get the immediate children of a game object and here you can see that we'll store this data in a list so here's our parent and the immediate children are child a child b and child c and then here we have it here retrieved in a list the second will be similar to our first approach but this time we'll be getting all the children recursively and not just the first layer immediately underneath our specified game object the third approach we'll use is to create an extension method this essentially allows us to extend the functionality of the game object class and provide us with a very tidy way of getting access to the children of any game object that we're working with similar to how you can call gameobject.getcomponent for example this we will create a method that will allow us to do gameobject.getchildren on any game object you have in your script and lastly the fourth method will allow us to create a hierarchy using dictionaries as you can see here you probably won't use this as often as the other three but i've included it in this video so we can cover the subject thoroughly now as a side note you won't actually see the data like this inside unity but it's a good way to visualize the data okay so back to unity so we usually start with a completely empty unity scene so you can follow along from the beginning but this time i'm going to start with my game object hierarchy here already created so you don't need to watch me do that step now i haven't done anything special except create these empty game objects and give them names and then parent them underneath each other so let's create our first script i'm going to right click create c-sharp script and i'm going to call it get children with my usual scr prefix to get this code to execute on runtime we will need to attach it to a game object so i'm going to attach it to our parent game object here so we can use this script on this game object here and then retrieve these children this will give us easy access to the entire hierarchy here if we put it here okay now let's go ahead and open up this script okay let's do some quick cleanup now we're only going to keep this start method here as it will be a good place to prototype some code as it only runs once on startup so we can get rid of that okay so from the four approaches you saw earlier let's begin with the first one which will be to get the immediate children underneath our parent game object so we want to get child a b and c in a list so we'll start off by creating that list we'll say a list of transform and we'll call it children and then we'll say get children which will be the name of the method that we'll create in a second so straight underneath we will create this get children method that we're creating so we'll say list transform get children so you can see here that this get children method will return a list transform which will go straight into our variable here called children now the first argument we're going to want is the parent so we'll go transform parent and this will tell this function which parent game object to get all the children from so in here we're going to need to pass through a parent now because this script here is attached to a parent already we can just say in here transform lowercase t so it refers to the transform of the game object this script is attached to if it was an uppercase t then it would refer to the actual type transform we don't want the type we just want this one here okay so now we have our parent we want to get the children from inside here we're going to want to create a new list which is where as we're iterating through all the children in our parent we want to take those children one by one and put it into a new list so in here we will also create a list of transforms and we can call this one children as well because it's a different scope to up there and then we'll say this children variable here is a new list of transforms and then we'll instantiate that okay so here's where the magic happens we'll say for each child transform in the parent i want to say children dot ad child so here we're saying for each child transform that we have found underneath this parent add it into the new temporary list here we have created and then after we've looped through and populated our list here inside the function we will return this list here okay so going back to our start method here when we run this it will execute this function here just below and this will go through the parent that we've provided it will make a temporary list it will add all the children it's found one by one into this list and then it will return it and then we will assign that list to this children list right here now let's test that quickly so we will then say temporarily we'll say four each transform child in children and then we'll do debug.log child name so you'll notice here that we have two for each loops but that's okay because you can think of it as this for each loop is going through and getting all the information we need whereas this for each loop is going through so we can use this information to do something with it so we're just going to be doing a debug.log so we can see what that information is so if we save that and then we'll go back to our scene here and that compile quickly now if i go to my console and i click play it should give us a list there we go child a child b child c and you'll notice it's only been run once if you notice that number is ticking away one two three four five etc then that might be because you have placed your go back here that might be because you have placed this code inside the update function so if you put in the start function it will just run once so it'll be good for testing okay so this printed out three names child a b and c so that means that this code here and this function here was correct this did indeed get the children of the transform that we gave it perfect so let's just add a comment here and we'll say this one was get children nice and simple i'll just comment this out for now okay so this variable here contains the immediate children underneath the specified transform that we have given it okay so now we want to get the children recursively we don't just want child a b and c we want all the children and all the sub children and if your hierarchy goes even deeper we want all of that as well so we can keep this method here but we're going to extend the functionality a bit so it can work recursively before we do that though let's run through this method once more just to be sure we understand what's going on so here we're creating a temporary list and then here we are looping through all the children that we find underneath that parent and then one by one we are sticking those children into our temporary list which will then be returned at the end of the method here now to make this method recursive it needs to be able to call itself so let's make our changes quickly and then we'll run through them so i'm going to say ball recursive which will allow us to use this function both with and without recursion and then here we're going to say if recursive will say children dot add range and then get get children child and true so now you can see that this method will be calling itself here we have get children and we have get children here so we'll be calling itself so this method is now recursive so now what's going on if we run this function with recursive equals true what will happen is it will loop through all the children underneath our parent it will add that to the list and then it will go one level deeper and get all the children for this child and then because this is now recursive if it finds children underneath this child it will then run itself again and again and it will keep running until it gets to the bottom of the hierarchy so if we go back to our hierarchy here we'll run this for the parent it will go child a and then it will go deeper sub child so it can't go deeper than sub child a1 because subchar doesn't have any children underneath so it will go down a2 no children for that okay a3 no children for that okay now we've finished the children for child a it'll go back up it'll then iterate to child b it'll go down sub child b1 and then it'll go back up and then it'll go down to child c c1 c2 and so on and so on so if you have this huge hierarchy it will go all the way through it all the way up down up down up down now this image here is a good way to visualize what's going on within the process so we'll come in we'll say for each child does it have children yes and then we'll go down the hierarchy and you can see it will keep going down the hierarchy until it reaches the bottom and then it will say okay it doesn't have any more children so go back up the hierarchy and then we'll go back up to the next child and so on and so forth now in our recursive function we won't need to check whether it has children or not because if it doesn't have children it will carry on for us and also when we get to the bottom of the hierarchy it will exit this function for us but do be careful when you create recursive functions to make sure that you do have an escape so it doesn't get stuck okay so going back to the code now you'll notice that this method returns a list of children which is fine when we're calling it up the top here but what happens when we're trying to pass that list of children back into itself when it is called here well this is where the add range function comes in which allows us to combine two lists together and essentially every time this function gets run it will pass the list of children it's found to be merged in with the list of children above it and it will keep getting merged together until that final list is passed back to here now this can be a little bit tricky to understand but here's one final image that we'll look at now this is a very plain example of what your code would look like if you didn't use recursion here on the left you can see that on the left the loops can quickly get out of control and you have no way of knowing the depth whereas on the right here this example function will call itself recursively and in essence it will be creating these loops for you but in the background now the function that we've created looks very similar to this we've got a little bit of extra code in there to work with the children and put them into a list but in short it's pretty much doing the same as this okay so now we've updated this method here with a new argument we have to update the call here so we go ahead and we'll save false because here we just wanted to get the immediate children so if we copy this underneath and we'll change the comment to say recur simply and we'll change this to true so this list here will have the immediate children whereas this list here will have the recursive children so because we have two variables here of the same name that will error so i'm going to comment that out but i'm going to keep it here for reference so we can come back to it later if we need to okay now that that's ready we'll uncomment this again so when we run it we can check we can use the debug.log to check that that has all the children that we've asked for so if we go back to unity go to our console we'll click play we should see a list of every child and here we go child a a123 b b1 c c12 and you can see that it does depth first so instead of it going parent child a child b child c and then a1 a2 a3 it goes parent child a child a1 a2 a3 and then b and then everything underneath and then c and then everything underneath okay so that's approach one and two here completed now approach number three was the extension method we're gonna skip that for now we'll leave that to the end and we're gonna go straight for approach number four which is to get this entire hierarchy here as a giant dictionary so let me just comment that out for debugging we don't need this method for now so we'll create a new one and this one will be returning a dictionary so we'll say dictionary transform keys and with dynamic values we'll say get children hierarchy transform parent okay so i'm going to copy and paste this because it's very similar in here but we won't need the recursive because this function will be recursive anyway because it's getting the entire hierarchy and instead of working with lists we're going to be working with dictionaries so we will update that line and then the only thing missing here is a call to itself so we'll say get children hierarchy here and child okay save that okay so you can see here that this method is very similar to this method above it however we won't be saying if it's recursive because to get the entire hierarchy it has to be recursive anyway so we don't need that if statement in here now this method here is going to be returning a hierarchy so a list won't be good enough for these purposes because a list will be flat whereas we need to maintain that hierarchy structure so we're going to be returning a dictionary the key is going to be the parent transform and then underneath that the value is going to be all the children so we're going to be tying together the parent and its children now this can be quite useful so if you want to save the state of a hierarchy and then you want to delete these objects but still remember where they were or what their names are now i'm using the keyword here dynamic because we don't know the depth of this hierarchy so if i was to say dictionary transform dictionary transform dictionary transform it could go on forever whereas if i say dynamic it will allow me to pair together a transform with a dictionary without having to specify the dictionary type underneath now to show you the problem you'd run into if you didn't use this dictionary keyword you would say dictionary and then it would be transform is the parent and you want it to be tied to a dictionary of children so you would say dictionary and then that dictionary would be the child would be paired together with the sub-children and then that dictionary you can see how it would snowball and it will be quite uncontrollable so by using dynamic we're pretty much we don't have to specify all of this and c-sharp will handle that for us which is pretty nice okay so as before what happens is we create a new dictionary on the fly we loop through all the children underneath the first parent and then we'll recursively call this function again it will pretty much do exactly what we did above with this one and then by doing children.add instead of add range to combine two lists we'll do children.add which will add this dictionary into the dictionary above it okay so we'll go back up to our start method and we'll create a space to call this new function we've just created so we'll comment out the old one just so they don't clash we'll create a new one and this one is get children hierarchy and this one is a dictionary of transform dynamic keys and we'll call this one children again and it will be get children hierarchy and we'll pass the transform of this script through as our parent now to read this data is a bit more tricky than just looping through and printing it out we are going to be printing it out but we're going to have to create a new function which will pretty much be read children hierarchy now i was going to skip this step but then i thought if you know if we've gone over how to create the dictionary it'll be very useful to go over how to then read that dictionary so let me just separate these two sections here so this first one is getting the data and i'm just going to use you know some fancy symbols to separate this and then here i will copy paste that and we'll just say accessing the data okay so this first bit here allows you to access the list and then underneath we will create a section to access the dictionary and i'm going to call the function read child hierarchy and of course we can pass through the dictionary that we're going to want to read so we'll pass that there scroll down a bit so let's create our new method to read this so we'll say void because it's not going to return anything read child hierarchy and then we're going to be passing through the hierarchy so it will be a dictionary transform now i have to use object here i will explain why later hierarchy lowercase h okay so the data coming in here will be a ready-made dictionary so we don't need to create a new one on the fly so then we'll loop through that dictionary we'll say for each key value pair transform object child in hierarchy okay so at the top layer we're saying for each child in the hierarchy and you can see that child will be a dictionary underneath so we'll say debug.log and then we say child.key so they will be logging the child name that we found and then we can say if child dot value is not equal to null so if this child has children itself we will then pass it through recursively to keep going and read everything else and then because the child itself is a dictionary as well we can say child dot value now just to force this value coming through to be the same type of value coming in that we need we're going to cast that to a dictionary transform object so this nested dictionary that comes through the key will be the transform of that child and the value will be the nested dictionary underneath now because we're using the object keyword here child.value is an object but when we run this function here we need the incoming argument to be of type dictionary so if we put this in brackets before the child dot value we're essentially forcing child dot value to be this type even though we already know it is that type but to the function it thinks it's just a generic object so by forcing it to be this these two will line up and then it will be able to run recursively and have no issues so let's go ahead and save this we've got our function here to read the hierarchy we've got a line of code here which will run the initial method to get the data and then underneath here we'll run the read function to go through that piece of data that we've found now obviously here i'm just doing a debug.log but however this is the part of the script where you'd want to actually use these child objects for your purposes okay so we've saved this we'll go back to unity again open up the console we've got an error here and it seems that i've used the word dynamics instead of just dynamic let's go back into it and have a look so just looking at the code uh here so i said dynamics that should be dynamic onward okay save that go back to the console we have another error here so let's go to that error line 64. oh yeah i've put key with a lowercase k so that's uppercase save that go back here okay cool no errors we'll click play and there we have it there's our hierarchy again child a sub children b sub children c sub children awesome okay so go back to the script and we can see now that our get hierarchy and read hierarchy functions or methods they both work which is cool and just if we go back to the original image just to show you this here number four this is a good way to visualize what this dictionary data will look like and you can see that in the dictionary we have just created the first key will be a child transform and underneath that will be all the child transforms in a dictionary and then under that will be another dictionary containing any further children that it finds so pretty much if it's empty that means it's the bottom of the hierarchy okay perfect so we've done approach number one we've got approach number two done approach number four so we've got the dictionary of the hierarchy now you can see how this looks like the exact hierarchy we had in the scene so now you could if you wanted to you could delete this hierarchy and you still have this in your script so you can recreate it or you could save this and then load this in later so the last thing we'll be doing now is the extension method which will give us a nice get children method here which we'll go through now so now looking at this you can see the biggest problem is that every time we run this function we have to pass through a transform which is okay but wouldn't it be so much nicer if we could say okay this current game object get children and then we just run that and it returns the children that we need so that's where extension methods come in now we can't access game object class or the transform class for example to add this functionality because that's part of unity's code however they have given us the ability to create extension methods which means we can create this method which will then essentially extend the functionality we have available to us through the game object class so if we go back to unity we're going to want to create a new script it doesn't matter what it's named but i'm going to call it extension methods and we'll open that up okay so we won't need any of these two methods here but we will need to call this a static class this means that this extension methods class can't be instantiated but anything we put inside here will be used by unity to extend any classes that we create functions for so i do prefer working with game objects rather than transforms because transforms are attached to game objects so game objects are kind of the parent object so i think it's nice to be working with those so we're going to create two extension methods for the game object class so the methods we're going to put in here we have already created so if we go back to our previous script get children and we will copy and paste the get hierarchy and get children methods here and we will paste them right here so we'll need to make a few changes to these methods just to make them compatible with the game object class so here we'll say public static so we can access that anywhere we won't need this parent argument anymore because it's going to be attached to a game object so we'll say this game object and then game object we'll keep the recursive ball so we can turn that on off and then here we don't have parent anymore we have the game object that we're working with but we do need the transforms to loop through so we'll say gameobject.transform but because this is looping through transforms we will just need to say here child dot game object so it passes a game object back through here and not a transform and then similarly down here we need to say public static for this second method and then we won't need the transform again but we will need to specify the game object object and then it's the same as above we'll be looping through the game object transform and then we'll be passing through the child game object so you can see i'm using the keyword this here and here now this is required to extend the class along with this type here i'm telling unity which class to extend so by saying this game object i want to extend the game object class and by passing the game object through here this will allow us to get access to the game object that we are running this method on so for example in another script when we do game objects dot get children we are no longer specifying what parent we want to get the children from and that's because we're already specifying here the game object that we want to get the children from so when we're passing it through here we're using it like a parent and it will automatically give us access to the children that we need so i'll get rid of this we'll save this we'll go back to our previous script to do some testing so similar to before we want to get the children but instead of having to specify a transform we already have the game object that we want to get the children from so we'll create a new section and we'll say this is where we use our children extension methods and that first one will be a list of transforms capital t children and then we can say we'll use the game object this script is currently attached to so we'll say game object dot get children now it still supports the recursion so we'll say we'll say true we'll comment this out so don't clash and we don't need this at the moment for debugging but we now can try and run this so if we uncomment this bit here which will log our list we'll save that we'll go back to unity cool we'll go to the console and we'll click play again we should get a list of every child yep there we go so we'll go back to our script again so we know that works let's change that to false so we just get the immediate children go back to unity we'll run that now we should just get child a b and c perfect okay that works go back to our script now let's try the extension method for the get hierarchy so i will copy that here but this time we just say gameobject dot get children hierarchy we don't need to specify a transform because we want to get the child hierarchy of this game object and then for debugging we will comment that out we don't need that right now we'll use this now i'm keeping this read hierarchy method here you can put this wherever you want you can put it in the extension methods as well if you want to i'm just going to leave it here for now so that looks all good we'll run that go back to unity go to the console click play that should show us everything yeah we've got everything again good so that works jump back to the script again okay cool so we can now access the children flat the children recursively the entire hierarchy we can extend the game object class to have the function so we don't need to have this floating around we can actually build it into our unity game which is is pretty nice i mean i would use this it gives me access to the children of any game object that i have in my script anywhere this hierarchy i wouldn't use as much but if i for any reason need to save the state of a hierarchy and then destroy this this allows me to keep that hierarchy intact in script which would be nice now to be thorough there's one last thing we have to cover here and that is a method that unity provides for us to get the children so i'll create a new section here for that unity array and transform array so it's not a list it's an array children equals gameobject dot get components in children and then the component will want to get his transform so what this allows you to do this is already part of unity it says for any game object i want to get a list or an array of all the components in the children underneath so if i say transform it pretty much gives me a flat list of all the children including sub-children underneath but however there is a problem here this method will also return the transform of the parent which i don't think is very useful because i've already got the parent here so to then have a list of children with the parent in that list would mean that this is not named correctly it should be get components in children and you know and self but hey that's just how it is so i'm just going to leave a little warning here warning also includes parent now this is an array but we can go through this the same way we go through lists so just comment this back into play we'll say this code works for lists and arrays we'll save that and we'll run this just to show you that working as well and click play perfect so you can see now we have all the children and sub-children in a list but unfortunately we also have parent which is not very useful considering we just want to get the children but i thought i'd show you that anyway just in case you want to use it and we'll comment that out and comment that out and we'll just leave this one switched on now if we scroll down to the reading function just quickly you will notice that we've used object here as the value whereas in the function above we've used dynamic now i would recommend avoid using the keyword object and use the keyword dynamic but it will error when you do so i'll show you go back to unity now we have an error here which will require you changing some settings in the player settings so if we go edit project settings we go to player and we scroll down here and you see it has api compatibility level now you'll need to switch this to net framework and then if we go back to unity here that error should disappear there you go so this setting here is quite advanced and if you're changing that then you probably already know how and when to use the dynamic and the object keywords so i'm just going to change that back to object for now and i think we have pretty much covered everything so this is pretty much the final code here uh it will be a link in the description so you can get access to it as well and you can see going back to this slide that we have now done all four approaches we've got our list of children our list of recursive children we've got the hierarchy saved in a dictionary with nested dictionaries and then we've also extended the game object class to give us this extension method which is quite nice and if the video was helpful to you at all please like and subscribe and if this code doesn't work for you for any reason please let me know and i'll try and help you out if i can i'm just going to go through the doc strings now very quickly so feel free to end the video here and uh yeah cool thank you for watching okay so doc strings dot strings i'm just going to we've got five dot strings to add now i'm going to use what i call informal dot string so i won't be using the input and output types and specifying everything i'm just going to put a quick sentence to say what it does so when i come back to this code i'll roughly remember what it does so this first method here get a list of children from a given parent either the direct descendants or all recursively so this function will go through all the children in the parent and it'll either get the immediate level only or it'll go through recursively cool next one get children hierarchy so this function will get a dictionary hierarchy of all children under a given parent close that off so for the parent specified we'll get all the children in the dictionary of dictionaries of dictionaries so nested dictionaries and then our helper function underneath which is to read that dictionary so we'll say read a dictionary hierarchy of children cool so that's that one and then we'll switch over to our extension method script here and it's very similar to the previous one but i'm going to type in full anyway get a list of children from a given game object either the direct descendants or all recursively and finally last one get a dictionary hierarchy of all children under a given game object now it doesn't really matter how you lay out your dot strings just try and be consistent throughout all your code and when you come back to it in the future it will it's just a nice to see a quick summary okay thank you very much for watching and i will see you next time bye bye you
Info
Channel: Danndx
Views: 13,517
Rating: undefined out of 5
Keywords: unity, unity game dev, get child gameobjects, unity extension methods, unity c#, unity c# extension methods, unity c# get children, unity get children, unity get child hierarchy, unity save hierarchy, unity get children hierarchy, unity gameobjects, unity beginners tutorial, unity c# tutorial, unity basic tutorial, unity beginners lessons, unity lessons, unity get parent objects, unity get child objects
Id: KhvokgokrQE
Channel Id: undefined
Length: 38min 5sec (2285 seconds)
Published: Fri Jun 03 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.