Now, before we wrap up everything that we've learned so far about Object-Oriented Programming to a nice bow and go into the Unity API, I want to touch on a few things to round out your understanding a bit better before we do that. The first thing I want to look at is how our classes have fields and methods that so far have been accessible only through our object instances. Right? We've had to always create an instance of our class in order to access, modify, read and write those fields or use those methods. There's actually a way to make a field or method so that it can be accessed without having to refer to an object. You don't even have to have an object instance. That is achieved by prefixing a field or method with the keyword "static". Let's show that with this example.
Going back to our Human class, let's just make this field static. Before the variable type, after the access modifier, I will put in "static", alright? When we mark this field as being static, we're saying that it doesn't belong exclusively to the object instance, but rather to the entire class itself. Let me illustrate this in action to give you an idea of what I mean by this. Going back to our AnimalFactory here, we will just get rid of the Debug here so we can focus on what we need to. Now let's try to access that Bipedal field of our person instance and what do you see? It's not there any longer. IntelliSense it doesn't even show it up even though it's a public field right? Still public so other classes should be able to see it. Well that's because it doesn't any longer belong to the instance, it belongs the class in general. Either Humans in general, not instances but in general, either Bipedal by nature or not. That's why we chose this as a static field. You access that static field by referring to the class itself. The type and then the dot accessor, and there you go. There's our public static field for Bipedal and you can assign it whatever you want, and that's how you make sense of statics.
So the obvious question is, when should you use a static field in general? Well you probably aren't going to use them that much when you write code specifically in Unity, in our Unity projects but you will come across statics in Unity's API pretty often. The rule of thumb is you use a static to designate where some value is shared across all instances. You can think of it that way. In the moment that you change that value, it changes it for all instances of that class. Again, that's the way you can think of it. Perhaps you're creating a simulation game, or a "god game" as they call it, and you want to do something like this. We can still use our Human class code here. As before, we had fields that did not belong to the class in general. That is, it wasn't shared across all instances. Let's give this human class again a Gender, right? Not everybody is of the same gender. Sorry string, and Age. Not everybody is the same age, so that's not going to be static. If we're creating a god game, right, and we want to manipulate some value that is shared across all Humans, if we imagine that condition, we may want to create something like this. public static bool FreeWill. I chose free will as a static here because it's an example where, regardless of its value, since it's a bool here it's either true or false, but regardless of if it's true or false, what's immediately clear is its value should be shared across all instances of Human. Either these Humans all have FreeWill or none of them have FreeWill.
When we switch that value, it switches it for all of them. They may all have these different Genders and Ages for each instance but fundamentally they share, as a part of their class definition, whether or not they have FreeWill. I don't want to get into a philosophical debate, this is just one example, but I thought it was maybe an instructive one. You can also prefix a method with a static keyword and you would need to do that when that method does some process that, say, changes a static field, a static field that it's referencing from the same class definition. For example, you can do something like this, have a method that references this static field FreeWill. Let's make static method, public static returns void,ChangeFreeWill(), and this will be a very simple line of code, FreeWill = !FreeWill although I would not necessarily read it that way. You can read it as FreeWill equals the opposite of FreeWill, alright? Whatever FreeWill is, if it's true it becomes false, if it's false it becomes true, as we went over with our bools and looking at the exclamation operator. Now admittently, this is a very contrived example. Let's assume there's a lot more stuff going on here in the method for ChangeFreeWill() just to justify its existence right?
Just to make a point, let's think about why it would necessary to have ChangeFreeWill() to be a static method. Would it make sense to access a static field shared by all instances that belonged to that class by going through any one instance of the class? Would it make sense to do something like this? Human Steven, just to use one example. We have our Steven object now. Would it make sense to access the FreeWill static bool that belongs to the entire class through Steven and we change that value by accessing the ChangeFreeWill() method, which we see within IntelliSense, it doesn't even let us do it. And it doesn't work obviously, because we set ChangeFreeWill() as a static method so it's not surprising, but just conceptually and intuitively it doesn't make sense to go through any one person: me, you, anyone to change a field that we all fundamentally share. That's why in method, in a class of that static field that we all share, a method that references that static field, shouldn't be able to be invoked from any individual. That's a conceptual way of understanding why we have to go through the class itself, so the method that references that static field has to be static itself. If you keep that in your head, this example, hopefully it will help make sense as you move along.
Since going through the instance, it doesn't make sense to modify that static field let's just do this properly and do it through the class itself. Human, hit the dot accessor and there's our method. In case you haven't noticed by now, the fields in Visual Studio have this little blue box to the left of it, and methods have the pink box, just so it helps you visually understand what you're looking at as you're using the dot accessor. We'll just access the ChangeFreeWill() method and just to show you how that works, although it's not terribly important right now, let's just output the value for FreeWill. Which we actually haven't set, so let's just set it first. Depending on your philosophical take on this matter, doesn't matter what we set it at but let's just say, false alright? Then we output that to Unity, we no longer need this code right now so I'm just going to comment it out. True. It just flips that FreeWill bool static value. Just so we keep that reference to what didn't work, I'll quickly write out again what we had before, and comment that out because it's just going to cause an error, and there we go.
I don't want you to worry too much about the details surrounding statics but I just want to clarify one point. In the example we looked at, we made the ChangeFreeWill() method static because it accesses a static field. Conceptually, this makes sense and maintains a certain consistency. However, it isn't strictly necessary. You could make the ChangeFreeWill() method non-static which would let you access the static field through the Steven instance in our example. It just doesn't make a lot of sense to do so. Of course, there are always edge cases in code where that actually might be useful but generally it's not useful. Technically it's okay for a non-static member to reference a static member or an instance member to reference a static member. On the other hand, what is strictly forbidden when it comes to working with statics is for a static member to reference an instance, or put another way a non-static member in its own class, for example. In other words, an instance member can reference a static member because the static member is always knowable to the instance because the instance knows the reference never changes, it will always be statically referencing the class. Whereas a static member can't access an instance member because the instance member is "unknowable" to the static member. This becomes a lot clearer when you ask, "How would this static method know whose "Age we're talking about here? "What instance does it belong to?" The static method has no way of knowing this so this reference is strictly not allowed.
Much of the time you make something static so you have a global reference point for all other classes that could find it useful to reference it frequently. For example, every one of our classes that have been making use of the static method Log() found in the Debug class, right? We've been using that all the time. One of the reasons why it's static is because we're just outputting information to the console. There's no real reason to make an instance every time we do so. That's just a lot of extra code and memory resources for what should be a very simple process that is useful to many classes across the board. That definition fits the Debug.Log() perfectly and that's why it's a static method. This might seem like, at this point, a lot to keep swimming in your head but really it will become second nature with time, as you get used to using these different tools available to you as you move along in coding. Right now, however, I want you to get the understanding of this entire object model, containment, access structure, and so on, mainly so that we can delve deeper into the Unity API. I'm not expecting you to have absolute mastery at this point, it's just dipping your toes into these concepts, just so that we can look at the Unity API, which is kind of opening up a giant toolbox, and knowing all this stuff I've been showing you about C#'s OOP nature, which hopefully makes a difference between understanding roughly what those tools are and how to use them and having no clue how to use them even to begin with.
Perhaps you've heard that saying, "To a hammer, everything looks like a nail"? Well in much the same way you can say, "To a person who doesn't understand tools "and toolbox everything looks like a hammer." If you get my drift. I think you're more or less prepared. I know you're more or less prepared at this point, to not look at everything as just being a hammer in code at this point. We'll go deeper into our actual Unity code and game logic by continuing our prototype and looking at the Unity API in the next few videos. I know that you're probably eager to go back to actual game development. I promise we'll be doing just that very soon. Thanks a lot.
Lesson 23 - Static Fields and Methods