Lesson 27 - Navigating the Unity API

Tutorial Series: Introduction to Unity with C# Series

Previous Article  |  Next Article


Transcript

Okay, finally, here we are, ready to go back to coding up our little game prototype, which is what we're really here for, right? Well, a common place for someone to be at this point, having learned all of these C# concepts about classes and fields and methods and so on. It's common for people to think at this point, "Great. I know the basics of all these things "but how do I use that knowledge to then "open up Unity as a blank slate and turn my ideas into a game? "How do I know what to write when I find myself "staring at an empty MonoBehaviour script?" for example. Well, knowing the general C# details is one thing but you also have to become familiar with the particular classes, fields, and methods that have already been written by the Unity developers that give you access to the Unity engine itself. Basically, you have to use what you learned about C# in order to understand, at least on the surface, the purpose of code written by somebody else, which would be the Unity engine API. Unity as an API, or framework, means that since it has a pre-built set of classes, properties, and methods, you can't just write whatever structure of classes, properties, and methods you so choose. You have to learn how to make everything "play nice" within the framework, and most of that is simply learning through documentation and such how to use existing code within the framework. That's where pretty much everyone has to start, with a better understanding of the Unity API.

In this video, I'll be showing you what it means to sort of wade through the API and how to generally go about researching those classes, fields, and methods that are available to you in order to use to create pretty much any behavior you want in your game. In order to look closer at the API, let's refer back to some of the code we've already written and see how we can dive into the Unity code base from it. To better understand what makes up a game object, in code at least, let's right click on GameObject here, where there's the cube reference field that we wrote before. Right-click on game object and we'll see two options we'll be interested in right now and that's 'Peek Definition' and 'Go to Definition.' First, I'll select go to definition. You see it opens up a window that actually takes you to the GameObject class definition. Now, you don't get to see all of the code that makes up this class definition. The fact, because the Unity code is proprietary, you won't get to see any of how Unity's code actually works but you will still get a wealth of information that can better help you understand what's going on underneath the hood. You have some comments, as well as what fields and methods the game object here holds. For instance, you'll see here the first three members of this class are actually methods. We know that because right after the name GameObject, in this case, you have the rounded parentheses. Again, we can't see much but we can see the name, the accessibility, as well as the input parameters.

Now, actually, these first three methods are special kinds of methods called constructors but we're not quite ready to talk about those just yet, and under those methods are a bunch of fields. Actually, not really fields but rather variables that are just like fields in most ways but are slightly different and are called properties. We haven't talked about properties just yet but basically they're exactly like fields but with an important distinction that actually isn't that important right now to understand just yet. Just know that when I say properties, basically take it to mean fields, as we've come to understand fields, until we talk about properties a bit later. Now, we know that these are properties rather than fields because of the variable, after the variable name, we have the get and set key words. Some of these just say get, others say get and set. Well, that will all become explained later. We see that a GameObject has a bunch of basic components of different types but recalling inheritance, click on the Transform property and actually right-click on Transform, as a type, and go to its definition. You'll see that Transform inherits from the Component class, which makes sense as we know Transforms are a type of Component. This as well is a Component.

I'm going to press the back button now so we can go back to where we were. After that Transform property in the GameObject class, we have a whole bunch of more methods available to you. Yeah, a lot of this won't seem all that useful right away but it at least gives a glimpse into what the GameObject class is made up of. Eventually, you'll become familiar with many of these properties and methods but, don't worry, you don't have to actually memorize anything, at least not that much. Alright, moving on. We also see that GameObject directly inherits from class Object. From what we learned about inheritance, we know that means that this GameObject class actually has a bunch more code that you don't see here. More than just all of this stuff but also the stuff that it's inheriting from the Object class. What do you think we can do to see that code? That's right, we can right-click it and check it Out in the same way, with go to definition. Here we go. Here's a bunch more code that all game objects have access to because all game objects are also at their base Objects. We see that this Object class doesn't itself inherit from anything else. so it's nice to know that this is as complex of inheritance as it gets for GameObjects. Once again, understanding inheritance Structures just by looking them up in this way can eventually be very useful when coding in Unity so just try to keep that in mind.

A quick side note. You may recall in the previous video on polymorphism that we said all classes inherit from the most basic C# class called object. That is actually a different object class from this one. I know that may seem terribly confusing and you may wonder how that is even possible since you can easily confuse the lower-case o object with the upper-case Object. Well, we didn't talk about namespaces, but we see here that this Object class is part of a containment structure called namespace UnityEngine, right? The C# basic class that we looked at in the previous video with a lower-case o comes from the namespace System, and this is perfectly okay in the same way that a wizard, a knight can both hold their own weapon with the same name for the field. One of them is really something like wizard.weapon, you can think of it that way, and the other is really knight.weapon, basically. By the same token, the object that is from the C# .NET Library that we just saw on the previous video is actually of System.object, whereas this object in the UnityEngine namespace is actually UnityEngine.Object. Now we didn't use the full name references so how do we tell them apart? Well, you can use the full name, as I just mentioned. System.object or UnityEngine.Object. Or, as in the previous video, use the lower-case o object alias, which, as it implies, is sort of a fake name that refers back to the actual class name, System.object. You may have noticed that other types are alias too, like int, string, etc. The actual class name for int, for example, is int32. Think of it as a nickname when your real name sounds kind of ugly, right? That's what aliases are all about.

Now going back to this SphereController CubeReference, let's see with IntelliSense all this code we've seen on those classes reflected with IntelliSense in real time. If I type in after CubeReference, which I can't do it there, excuse me. I'll just start typing it again so I can use IntelliSense. It opens up IntelliSense and, as I scroll through all these options, you may recognize these properties and methods that we just saw in the class definition. As you probably noticed, these wrenches, those refer to properties. Those pink boxes, those are methods. This is basically everything that a game object has access to that you can get to with the dot accessor. You do get a wealth of information through Intellisense. If you click on a particular method, it'll give you a little blurb as to what that method is all about. It at least gives you a hint, if you've never seen it before. See, this one says, "Adds a component class Of "type, componentType, to the game object" right? It makes sense, in that case. With our prototype game project, we primarily worked with the transform component and that component is accessible by a property available to all MonoBehaviours. Let's right-click on this transform property in the CubeController right here to see where it comes from. Where does this transform property come from? After all, it may seem kind of magical. There's no original type declaration. There's no Transform upper-case T and then lower-case t transform in our class that we wrote here, CubeController, so where does it come from? It must be inheriting from somewhere, so think about that. Remember all of our scripts attached to GameObjects must inherit from monobehaviour, all right? When we right click on the transform property, it shows that it's a property from the class.

What class is it? Component. Maybe you expected it to directly be inherited from monobehaviour, as SphereController inherits from MonoBehaviour. Can you venture a guess as to why we have access to this property? Well, basically that's because the script we're writing is, as you see here, a MonoBehaviour that is attached to a GameObject. Things attached to GameObjects are called, what again? That's right, a component. That's why this class has access to that property. This transform came from the Component class, and we can prove that the script is Component, not only because we know it is in the inspector by navigating the inheritance hierarchy, so if I right-click monobehaviour, we see that it inherits from Behaviour, right? If I click on behavior to go further down this inheritance structure, we see Behaviour inherits from Component. Once again, if you go to Component, look at all these properties. Among them is transform. You have others available too. See, there's one called animation so I know that I can type in animation because a monobehaviour is a component, my SphereController is a MonoBehaviour so I have also an animation property. There it is. I can do with that whatever that gives us access to. That's again why the script we're working on has a property for transform.

How do we know what this transform property relates to, though? After all, it could be referencing any transform. Well, let's see here the note we get from Intellisense when we hover over it. The transform attach to this game object. Null if there's none attached. We know that the transform attached to this game object is the one we saw on the inspector. For the cube, in this case, we're looking at the cube controller. For the cube controller script, that transform again refers to the transform of the GameObject that this CubeController script is attached to. Now, this may seem confusing. Didn't we just see that GameObjects have transforms? But so do Components. Why? Why would that be? Well, it's basically just flexibility coming from multiple classes, having a has-a containment reference to their own transform objects. Basically, the moral of the story is to have a bunch of different ways... Unity gives you a bunch of different ways of accessing common properties like transforms and whatnot. We don't have to stop there. We can try to understand what makes transforms better. What can we do? We can find the Transform class or we can just type it in anywhere. That's the class. Don't confuse the property from the class. That little symbol means it's a class. The upper-case T, and you also see it color coded like that. Classes get color coded. It's kind of, I don't know. What is that, teal? Light blue kind of color?

You can right-click on the class, and this time I'm going to 'Peek definition' and what happens is it just opens up a nice little inline summary, which is the same thing but it's just in-line with this document. It doesn't open up a new document tab. Well, it's a little bit hard to look at on this monitor so I'm going to go back to 'go to definition.' Here we see what transforms are made up of. Here we see the familiar position property that we've been quite familiar with. It's a Vector3 and so we can just ask ourselves, what are Vector3s made up of? Well, let's go to definition and there's a Vector3 Now, you see here, it's actually not a class. It's a struct. I'll talk a little bit more about structs later. It really is a simple distinction between classes and structs. Actually, you'll be mostly just writing classes and not structs. Referring back to the video where I mentioned the difference between value types and reference types. Basically, this is the difference. Classes are reference types and structs are value types. Structs are just like classes but they're value types and there's some good reason for using structs versus classes but you don't have to worry about that. Certainly not anytime soon.

Once again, Vector3, we see some familiar properties. The x, y, and z properties, for example, that we've worked with already that are floats. We're calling that, we can expand these definitions and get some more information through the comments provided to us. Sometimes it's more helpful than other times but at least you can dig a little bit if you want to. Looking at the Unity API in this way, kind of going on a little Easter egg hunt and opening it up and finding out how it's all comprised is useful in a lot of ways. It gives you a way to look at various possibilities while you're coding on the fly but it also lets you zoom out and see all these class relationships. All of these is-a and has-a containment structures, hopefully giving you a better wireframe understanding in your mind of how all of these classes relate. Going back to what we saw by navigating the Unity API, we saw that ... What did we see? We learned that a script class is a Component because MonoBehaviours are also Components. A Component has a property called transform, which refers to the transform Component attached to the same GameObject as this Component, which, in this case, is the script that you're writing in, SphereController, CubeController, and so on. Transform, in turn, has a Vector property. A Vector3 property called position, which has X, Y, and Z properties which are all floats. That's why in your script component that you're writing in right here, the script Component is SphereController.

You can write in anywhere there and have access to all these properties because your script is a Component, and by virtue of being a MonoBehaviour, it's a Component so you inherit a ton of functionality, just from being a MonoBehaviour alone. This gives you lots of different ways of manipulating game objects in your game. That's the primary purpose of MonoBehaviours. That's really handy. Unity is giving you all of these properties and methods already furnished and hooked up in your scripts directly from just being a MonoBehaviour. Even more broadly, you get even more stuff available to you through the general UnityEngine namespace. We talked a bit about namespaces. Using our limited understanding of that, we can basically understand it as importing the entire library of code that makes up the Unity engine. Let's look at the entire Unity namespace, UnityEngine namespace / library that's what it's giving us that we've already worked with. What do we get? We got of course Random. Where does that come from? Let's see. It comes from UnityEngine. That just gives us randomization methods and properties and such. Like Range(), that's what we used to get a random value between a range of floats. We got the GameObject class, of course.

You might notice that these are static methods. The Instantiate() method that comes from GameObject is static because we're referencing the Instantiate() method directly through the GameObject class. We don't need an instance. Same with Destroy() and Random.Range(). We have a Vector2 Distance, which is basically the same as Vector3. It's just all we need is X and Y properties with that. We didn't need the ... I think we use that for calculating the distance, yeah. We only look at X and Y so that's why we use that. We have the GetKey() method from the Input class, which handles ... This is a class that comes from UnityEngine that basically manages inputs, whether from the keyboard or from a game controller, that you can then access in your code and create behavior, as you saw earlier on, when we were coding up this project originally. Directly digging into the API through things like IntelliSense and looking at class definitions, it can be very helpful. Sometimes, there's really no substitute for actual documentation, and Unity is pretty well-documented in this regard. You can access the scripting documentation either online, through a browser, for example, or even directly within Visual Studio, which opens up the documentation stored locally on your computer. I think it's in an HTML file or something like that.

The online scripting documentation is pretty much exactly the same so yeah, accessing the scripting documentation is very helpful. Also helpful is researching for answers online. There's plenty of forums and blog posts and people talking about Unity and how to solve problems and it's very useful. Bear in mind that 99% of finding the right answers on the web is knowing how to ask the right question. I think it's natural for newcomers to not worry too much about getting all of the lingo when learning how to program your properties, fields, methods, static, public, private, all that stuff, but it really helps when you need to ask a specific question and be able to narrow down the field of possible answers. Keep that in mind when learning all of these funny-sounding terms. It is useful, eventually understanding what they all mean. Even with all this information at your disposal, I don't expect you to now be able to go, "A-ha! I know exactly how I can create this gameplay mechanic." That insight comes ultimately with time and familiarity with the API and just picking up tips and knowledge through the documentation and online and your own just playing around. Half the fun is just playing around and seeing what you can come up with. Simply knowing all these bits of documentation, it's not going to get you from A to Z but you'll at least know where to turn to better flesh out your understanding and solve some problems on your own, and ask questions that you know how to ask and you get some answers that hopefully will answer those questions. There'll be many instances in which we'll be turning to that documentation for clarification in coming videos. Right now, I just wanted to show you how to access the API in a variety of different ways. Understand it and be able to use that information to move forward in programming a game. Alright, so I'll see you in the next videos.


Related Articles in this Tutorial:

Lesson 1 - Who This Course is For

Lesson 2 - What to Expect from this Course

Lesson 3 - Installation and Getting Started

Lesson 4 - Starting the First Project

Lesson 5 - Prototype Workflow

Lesson 6 - Basic Code Review

Lesson 7 - Game Loop Primer

Lesson 8 - Prototyping Continued

Lesson 9 - C# Fundamentals and Hello World

Lesson 10 - Variables and Operations

Lesson 11 - Variables and Operations Continued

Lesson 12 - Floats, Bools and Casting

Lesson 13 - If Statement Conditionals

Lesson 14 - If Statements Continued

Lesson 15 - Complex Evaluations and States

Lesson 16 - Code Syntax vs. Style

Lesson 17 - Variable Scope

Lesson 18 - Object-Oriented Programming Intro

Lesson 19 - OOP, Access Modifiers, Instantiation

Lesson 20 - Object Containment and Method Returns

Lesson 21 - "Has-A" Object Containment

Lesson 22 - "Is-A" Inheritance Containment

Lesson 23 - Static Fields and Methods

Lesson 24 - Method Inputs and Returns

Lesson 25 - Reference vs. Value Types

Lesson 26 - Introduction to Polymorphism

Lesson 27 - Navigating the Unity API

Lesson 28 - Applying What You've Learned and Refactoring

Lesson 29 - Constructors, Local Variables in the Update Method

Lesson 30 - Collecting Collectibles, Items and Powerups

Lesson 31 - Spawning and Managing Prefab Powerups

Lesson 32 - Implementing Powerup State Logic

Lesson 33 - Displaying Text, OnGUI, Method Overloading

Lesson 34 - Referencing Instantiated GameObjects, Parenting

Lesson 35 - Understanding the Lerp Method

Lesson 36 - Creating Pseudo Animations in Code

Lesson 37 - Understanding Generic Classes and Methods

Lesson 38 - Animations Using SpriteSheets and Animator

Lesson 39 - Working with Arrays and Loops

Lesson 40 - Debugging Unity Projects with Visual Studio

Lesson 41 - Camera Movement and LateUpdate

Lesson 42 - Playing Audio Clips

Lesson 43 - Routing Audio, Mixers and Effects

Lesson 44 - Adding Scoring Mechanics and Enhancements

Lesson 45 - Scene Loading and Game Over Manager

Lesson 46 - Understanding Properties

Lesson 47 - Controller Mapping and Input Manager

Lesson 48 - Understanding Enums

Lesson 49 - Dealing with Null References

Lesson 50 - Handling Variable Framerates with time.DeltaTime

Lesson 51 - Preparing the Project for Final Build

Lesson 52 - Final Build and Project Settings

Lesson 53 - Introduction to the Unity Physics Engine

Lesson 54 - Understanding FixedUpdate vs. Update

Lesson 55 - Movement Using Physics

Lesson 56 - Attack Script and Collision Events with OnCollisionEnter2D

Lesson 57 - Projectiles and Stomping Attack

Lesson 58 - Parallax Background and Scrolling Camera

Lesson 59 - Infinitely Tiling Background Sprites

Lesson 60 - OOP Enemy Classes

Lesson 61 - OOP Enemy Classes Continued

Lesson 62 - Trigger Colliders and Causing Damage

Lesson 63 - Multi-Dimensional Arrays and Procedural Platforms

Lesson 64 - Finishing Touches

Lesson 65 - Series Wrap


Comments

Please login or register to add a comment