 We'll move objects around in some more interesting ways soon enough, but first we need to talk about how you in code can find references to various game objects and their components. And first what we're going to do is we're going to take our cube and our sphere and remove the script component from both of them. And we're going to create a new standalone game object. So I'm just going to call what we call it just game manager and just called manager. It'll just be a generic object we attach our script to it's not going to serve any other purpose just to hold our script, which I think is more appropriate for scripts which are just general logic, and not concerning particular individual objects. That is my stylistic preference anyway so now we have this manager with the my script and go back and I added in this code in the start method, where first off we're using this method find object of type. And that is actually a method of the static method of the object class. Again be clear this is unity engine dot object, which has a static method find object of type. Visual Studio is hinting to us by the fact that this is a slightly different shade of teal here. It's hinting to us we don't actually need that because it knows what we're talking about because we're inside the my script class which inherits from model behavior, which inherits from behavior which inherits from component, which ultimately inherits from unity engine dot object. So we don't have to qualify this static method with its class name it knows what we're talking about. And anyway this method what it does is it finds all objects of a particular type. And we specify the type you pass in system dot type values and to get such values we use the type of operator and here we're specifying the game object type. So we want to find an object of the game object type and this method always returns an object regardless of what we're looking for. So no matter what we're going to fetch here, in this case a game object as far as the compiler knows we're getting back an object. But because we know at runtime this what's going to be stored in O here is going to be a game object we can then just immediately cast it to type game object. And of course we can just sort of skip that step we don't need to make these separate lines I was just trying to be explicit for clarity. So we just need that one line and that's all good. So now we have a game object retrieved by this method and we're going to log it out by printing out its name because every game object has a name. Actually the object type is where the name property comes from but then game object inherits that and that is the name that is what we see here. So this game object has the name sphere and this has the name manager. This is Q. The question though is what game object here are we going to get because in our scene we have will be a five of them and the answer is well you just get one of them and you're not in control of which one you get. Frankly I'm not sure why this method even exists. It doesn't seem very useful to me slightly more useful there is find objects of type that's plural objects and this returns an array of object instead of just a single object. And again in this case we know we're going to get back an array of game objects specifically not just object so we can do the cast here and that's more useful because now we can use them like game objects and we'll loop through them and print out all their names. So now if we run the code here let's see what we get first off find object of type manager. So for whatever reason it's this last one I guess this is one that's loaded first and then find objects of type printed out manager sphere cube directional light main camera all of them and just printed them all out. So those are two ways we can get at references to objects but one thing we're probably going to want to do different here is there's another event method called awake which I don't know why Visual Studio adds the private modifier there you don't I don't think it matters at all but it would only matter if for whatever reason we wanted to call this awake method from some other class of our own code but I don't think we would ever want to do that anyway I'll just get rid of it. There we go. Anyway so the awake event is like start it's called when an object is created for the first time before any updates called but it's guaranteed that at least within an individual frame all the calls to awake will be done before any call to start. What's useful about that is we can do scaffolding business where we hook objects together like get references to things and initialize fields to store references we do that typically in our awake methods and then our start methods we can assume all that stuff is already done so it generally would be more appropriate to do all this business in a wake rather than start. Another method we have for getting references to objects is the find method which is in a static method of the game object type so be clear our myscript class doesn't inherit from game object it's a component not a game object they both inherit from object but not game object so we have to write explicitly game object find and it's expecting a string what did we have in our scene we had manager sphere cube directional light main camera so just one of these names as a string is what we want let's just say a directional light just to demonstrate that you have to get the name exactly right with the right capitalization and all that so that that looks good to me and this returns a game object we'll just call it light there we go and just to prove that works we'll print out find we'll print out the name of the object there we go let's see this in action I'll restart the game where does it say at the end yeah under find directional light that got logged okay so that works as we expected and if you're wondering if we specify a name that doesn't exist like we make a typo like that lowercase d now it's not going to find it so if I restart we got a null reference exception because what happened here is that light got assigned null and then we tried to access its name property and if you try and access the property or methods of things that don't exist that are null now you get a null reference exception another thing to keep in mind is that we might actually have multiple objects with the same name i'm going to duplicate our sphere here and rename it so it also has a name sphere and then i'm going to move it so that when we print out its properties we can see that distinction okay so now go back here and we're going to search for sphere and just so i don't confuse you i'll rename this to sphere though doesn't of course doesn't really matter what the variable name is sphere there we go and we're going to print out um it's transform and so what we should expect is well we know we're getting back something named sphere that part is not going to be the surprise the question is which sphere do we get and the answer is well when unity when you call find and it searches through all of your game objects it's just whichever one it encounters which happens to have a name that matches that's the one you get so it's also basically just uh indeterminate from our perspective which one we're going to get we'll get one of the two so let's see which one we get i'm going to play this one here and oh wait i didn't print out the transform oh excuse me local position there we go we want to print out just a position not the whole transform there we go zero two point one three point eight which one is that is that this one two one three yeah it's about that one so it's it's this sphere that we happen to get not the other one if you're looking for stuff my name you probably want to make sure stuff has unique names rather than just relying on happenstance in addition to having names our objects can also have tags that's what this is about up here and by default there are six tags we can apply these just come stock i don't know if you can even remove these existing tags but you can also create your own custom tags as i will do here i will call it my tag if i can type whatever my tag lowercase tag there so that's a new tag that's been created and now when i go back to an object and i want to apply a tag i can choose my tag the thing to keep in mind is that this tag system is not like other tag systems where you can apply multiple tags to one thing a single game object can only have one tag quite inconveniently too it's it'd be nice if you had a proper tag system where you could have multiple tags per object but that's not the case so having applied my tag to sphere if i come here and select uh respawn well now it only has that one tag not my tag anymore so you only have one tag applied to any object so let's put it back to my tag i'm also gonna make this cube give it my tag and now if in our code if we want to find let's see i'm going to duplicate this code real quick let's see i want to find with tag and it's called my tag lowercase t um i'll just give it the same name doesn't matter just for clarity we'll just print out the name this time let's see which one we get um it could either be the sphere or the cube i don't know which one that we get it's indeterminate it turns out okay we get the sphere but keep in mind the cube also has the same tag but just for whatever reason when it looks through all the objects with that tag it found the sphere first now if i want i can also find all objects with a particular tag if i simply here all those copy and what is it it's uh find objects with tag i believe that's correct no what's going on um it's called find game objects with tag it's very confusing why'd they change that name um and that will return an array of game objects and so we'll have another loop here oh and also i should make sure this is fine with tag because that's what it's the result of we're printing out to console and it's to come back here play the game and let's see so find with tag sphere but then find game objects plural with tag finds both sphere and cube because they both have the tag called my tag so that's what we expected um strangely why does it have i noticed in the code completion it said game object with tag singular but i didn't see that in the documentation so what the hell is this thing um oh it doesn't want an array go back to tag is that proper now oh well we don't want to reduplicate that declaration what the what the hell is this is this any different from find with tag because i don't strangely in the documentation it's not mentioned um i guess they decided at some point they needed to make this symmetrical though honestly now it's it's more confusing because it's really easy to look at this and i accidentally see this and vice versa i think i assume that's just um you know let me let me actually see this in action i assume it's just going to do the same thing as find with tag oh i forgot to uh print that out just once of course so my tag excuse me okay that that's what i meant to do come back here play and so find with tag it's a sphere find game object with tag also gets a sphere rather than cube i assume they're exactly equivalent it's weird then it's not mentioned in the documentation anyway so those are probably the most essential methods for getting references to game objects but understand finding by type is very expensive not something you want to do every frame finding my name a bit better but still quite expensive and not something you want to do every frame so those things you probably should only do on startup when your your initial game objects are loading up then it's appropriate and like your awake methods otherwise particularly like in an update function you wouldn't want to call that stuff find us up by tag it can be fine though that that's relatively optimized because of how i believe it keeps a a hash table to pre-existing arrays that it can just hand a reference to when you use these methods so finding by tag much more efficient so i hope that gives you an idea of how we can hook our game objects together in code though of course what we're missing here is that probably what you want to do is in awake you want to preserve references to these objects that we're finding so let's say we just want to find a reference to the cube in the sphere and we want to preserve that in our class so we can create some private fields which are game objects here we'll call this one cube we'll another one for the sphere and what we'll do is upon awake we'll just store in sphere what we get back from game object find sphere and it will also do the same for cube but assign that to cube and we'll get rid of all this other stuff and that should be all we need because assume just for whatever reason in the script we're going to make repeated reference in other methods to the cube and sphere that we find on awake so this is how we can hook them up programmatically but sometimes what you might want to allow is for objects to get hooked up in the editor like you define some component type that needs to reference certain other objects rather than making those connections in the code i'm going to actually get rid of these lines here and we're going to make these public and what happens when we give our script component public fields is if we then go into the editor and here look at the manager which has the myscript component it now has here cube and sphere it has places where we can plug in hooks for some cube object and a sphere object and here i'm just going to specify cube and here i'm going to specify the sphere but actually nothing stopped me in this case from assigning sphere to the cube field and the cube to the sphere field because they are valid game objects that's the only restriction here has to be a game object so now when the scene is loaded and the manager game object is created its myscript component is going to be initialized with the the sphere for its cube field and the cube game object for its sphere field that's just going to automatically be hooked up for us by unity we don't have to do so programmatically and in fact what we can do is we can give our component public fields of other types like say just some float field here which we'll call uh fred and now if i go back to the manager and look at its script component and wait for the recompile now you see hey there's a fred component and what i can plug in here is just any float value so this is how our scripts can be configured much like the built-in component types where in the editor is where you specify the initial values for certain public fields and again that might be very handy for certain purposes where like say you want to create some component type which your environment designers are going to use and you don't want them to have to go into the code to hook up certain values you want to just be specified in the editors so that's what this opens up you can create custom components and have their instances configured directly in the editor in fact be clear any game objects can have as many instances of any script component as you want so i'm going to give the manager a second script component oops he didn't like the drag there there we go okay and so this one the cube i'll make actually cube um and then the sphere here well i'll make a main camera for whatever reason doesn't matter in this case because our script is nothing but anyway and then now the fred value in this component can be whatever i want can be totally different so be clear associated with this one game object are two script components of the same type but they are separate instances of this one class called my script and each one has its own cube field sphere field and fred field which are configured independently here in the editor