G: Keyword: Static¶
Concepts in Action¶
In a game, you often have objects that you need to access frequently and from many different parts of your code. A common example is the player’s character. Many different systems might need to know about the player’s character — for example, an enemy AI system might need to know where the player is to chase them, or a UI system might need to know the player’s health to display it.
If the player’s character is instantiated by a specific GameManager instance, then each time you need to access the player, you’d need a reference to the exact instance of the GameManager that created the player. This can lead to tangled code and can make it more difficult to manage your game’s structure.
However, if you declare the player’s character as a static variable within the GameManager, any part of your code can directly access it. You wouldn’t need to know about the specific GameManager instance, just the GameManager class. This simplifies your code and makes it much easier to manage access to important game objects.
So far, we’ve talked about static in the context of variables, but static is not limited to just variables. It can also be applied to functions and even whole classes.
A static function can be called directly from the class, without needing an instance of the class. This can be useful when you have a function that doesn’t interact with any instance variables and doesn’t need to know about specific instances. For example, a Math class might have a static function for square root, because you don’t need a specific Math object to calculate a square root—you just need the number you’re taking the square root of.
Similarly, a static class is a class that contains only static members and cannot be instantiated. In other words, you can’t create an object from a static class; you just use its static functions or variables directly. This is useful for utility classes, like the MathHelper class above, where you don’t need instances, just a collection of related functions.
Understanding how to use static with variables, functions, and classes gives you more tools to structure your code effectively. It allows you to create utilities and global access points, simplifying your code and making your game easier to manage.
Introduction¶
In every game development journey, there comes a moment when you need to reference a particular game object, a function, or a variable from multiple different places. Maybe you have a player character whose health needs to be updated by various enemies, traps, and healing items. Or perhaps there’s a game manager that controls the flow of your game, and several different systems need to communicate with it.
In moments like these, the static keyword in C# becomes a game-changer. static allows you to create variables, functions, and even classes that do not need to be attached to a specific instance of a class. They exist independently, and can be accessed directly from the class they are defined in.
In this article, we’re going to delve into the static keyword, exploring how it works, why it’s useful, and how it can help you in building your games. By the end, you’ll understand why static is a powerful tool in your C# toolbox, one that can make your game development journey smoother and more efficient.
Prior C# knowledge required¶
Before jumping into the world of static, it’s important to have a firm grasp on a few fundamental C# concepts.
Variables: Understand what variables are and how they’re used to store and manipulate data in your code. Know the difference between different data types like int, float, string, and bool.
Functions: Be familiar with how to define and call functions. Know how they can take parameters and return values.
Classes: Understand what classes are and how they’re used to structure code in an object-oriented programming language like C#. Be aware of how to create an instance of a class and access its members.
Access Modifiers: Know the difference between public, private, and protected access modifiers and how they control the visibility of your classes, variables, and functions.
Having a firm understanding of these concepts will make your journey into the world of static much smoother. Don’t worry if you’re not a master at all of these yet - as with all things in programming, practice makes perfect!
You can refresh these concepts by reading the previous articles: - Types - Classes - functions
Definition¶
n C#, the static keyword is used to denote a member of a class that is not tied to any specific instance of that class. This means that static members are shared across all instances of the class.
Let’s look at the first image. Here, we see a representation of a class with a static variable, alongside some instance variables of a single instance of the class. The static variable lives in its own memory block, separate from any individual instance of the class. This is because the static variable is not part of any specific instance - it’s part of the class itself.
Now, let’s move on to the second image. Here, we see the static variable and instance variables from two different instances of the class. Notice how each instance has its own set of instance variables in their own memory blocks, but they both share the same static variable. This illustrates how static members are shared across all instances of a class.
Besides static variables, a class can have static functions as well. A static function belongs to the class itself, not any specific instance of that class. This means that you can call a static function without creating an instance of the class.
Consider a class called MathUtils that has a static function to calculate the square of a number. You don’t have to imagine very hard, because the Unity engine has such a MathUtils class, called Mathf! You can call this function as MathUtils.Square(5) without creating an instance of MathUtils, saving memory.
In summary, static members - whether they are variables or functions - are part of the class itself, not any particular instance. They live in their own memory space and are shared across all instances of the class. This makes them incredibly useful for certain tasks, but they should be used with care, as overuse can lead to code that is hard to manage and understand.
Differences to JavaScript¶
-
In JavaScript, static functions are defined on the class itself, not on instances of the class. This is similar to C#, but there’s a key difference: JavaScript doesn’t have static variables (properties). Instead, JavaScript developers usually use properties on the constructor function itself as a workaround.
-
JavaScript doesn’t have the concept of static classes. In C#, a static class is one that cannot be instantiated and can only contain static members. JavaScript doesn’t have an equivalent concept.
Similarities to JavaScript¶
-
The static keyword in both languages is used to create members (functions in the case of JavaScript) that belong to the class itself, not any particular instance of the class.
-
In both languages, static members are shared across all instances of a class. This means that they maintain their state across all instances, which can be useful in certain scenarios.
-
Static functions in both languages can be called without creating an instance of the class. This makes them useful for utility functions that don’t rely on any instance-specific data.
Examples¶
public class Player
{
// Player properties and functions go here
}
public class GameManager
{
public static Player player;
public GameManager()
{
player = new Player();
}
}
/**
*In the example above, GameManager creates a new Player instance when it's constructed.
*Because player is declared as static, it's shared among all instances of GameManager,
*and it can be accessed directly via other instances, such as an enemy, like this:
*/
public class Enemy
{
private Player player;
public Enemy()
{
player = GameManager.player;
}
}
//now, let's create a MathUtils class with a static function:
public class MathUtils
{
public static int Add(int a, int b)
{
return a + b;
}
}
/**
*In this case, the Add function can be called directly on the MathUtils class,
*without needing to create an instance of MathUtils:
*/
public class Enemy
{
public void KillEnemy()
{
GameManager.score = MathUtils.Add(GameManager.score, 2);
}
}
Key Takeaways¶
-
Static Members: In C#, the static keyword is used to declare members (variables, methods, properties) that belong to the class itself, not to any specific instance of the class. This means that static members are shared among all instances of the class.
-
Accessing Static Members: Static members can be accessed directly from the class, without the need to create an instance of the class. This makes static members useful for storing global state that needs to be shared across multiple instances, or for utility functions that don’t rely on instance state.
-
Static Use Cases: Static members can be useful in game development for accessing important objects (like the player or the game manager) from anywhere in the code, or for utility functions that don’t rely on instance state.
-
Static vs Instance Members: Remember that static members behave differently from instance members. While instance members have a separate copy for each instance of a class, static members have a single copy that’s shared by all instances.
-
Careful with Static: While static can be very useful, it’s also easy to overuse, which can lead to code that’s difficult to manage and debug. Use static when it makes sense, but don’t rely on it too heavily. Always consider the trade-offs and choose the most appropriate tool for the task at hand.
Further Reading¶
- Tutorials Teacher: static keyword
- Microsoft: static classes and static members
- When to use static classes in C#