Object-Oriented Programming (OOP) in Unity Game Development

Introduction

Swapnil More
5 min readJan 13, 2024

Hey everyone! Whether you’re a total beginner or a budding game creator, get ready to dive into the awesome world of Unity game development. Today, we’re unlocking the secrets of something called “OOP,” which might sound like a secret code, but it’s actually a super cool way to write code that makes our games even more amazing.

Think of OOP as your trusty sidekick: It’s like having a magic toolbox that keeps our code organized, easy to understand, and super powerful. No more getting lost in a tangled mess of code! OOP helps us build games that are not only fun to play but also easy to change and improve as we go.

So, are you ready to level up your game dev skills? We’re about to uncover the hidden powers of OOP and transform our game ideas into epic masterpieces!

Importance of OOP in Unity

Unity’s architecture heavily relies on OOP principles, offering a structured and modular approach to game development. OOP promotes code organization, reusability, and maintainability, allowing developers to create complex systems with ease. Let’s explore some of the fundamental OOP concepts used in Unity and understand their significance.

1. Class and Object

Unity leverages classes and objects to model entities within the game. For instance, the GameObject class represents an object in the game world. Every game object is an instance of this class, possessing properties and functionalities.

// Example in Unity
GameObject player = new GameObject("Player");

1.1 Base Class

A base class serves as a foundation for other classes. In Unity, this could be a generic class like Animal that provides common functionality.

public class Animal
{
public void MakeSound()
{
Debug.Log("Generic animal sound");
}
}

1.2 Derived Class

A derived class inherits properties and methods from a base class. For example, Dog is a derived class of Animal, inheriting the MakeSound method and adding its own, like Bark.

public class Dog : Animal
{
public void Bark()
{
Debug.Log("Woof! Woof!");
}
}

// Usage
Dog myDog = new Dog();
myDog.MakeSound(); // Inherited from Animal
myDog.Bark(); // Specific to Dog

1.3 Abstract Class

An abstract class is a blueprint that cannot be instantiated. It often contains abstract methods without implementation, like an abstract Shape class in Unity.

public abstract class Shape
{
public abstract void Draw();
}

1.4 Sealed Class

A sealed class cannot be inherited. It’s like saying, “This class is complete, and no one can extend it further.

public sealed class FinalClass
{
// Class definition
}

2. Encapsulation

Encapsulation is crucial in Unity to control access to data and methods. Unity components often encapsulate their functionalities, exposing only essential interfaces. Consider the Transform component, encapsulating position, rotation, and scale information.

// Example in Unity
public class Player : MonoBehaviour
{
private int health;
public void TakeDamage(int amount)
{
// Encapsulated health modification logic
health -= amount;
}
}

2.1 Private Access Modifier

The private modifier restricts access to the declared members within the same class. It's like keeping certain variables (e.g., health) private to prevent external interference.

public class Player
{
private int health;

public void TakeDamage(int amount)
{
health -= amount;
}
}

2.2 Public Access Modifier

The public modifier allows access from any other class. In Unity, public variables like Model and Speed can be accessed directly.

public class Car
{
public string Model;
public int Speed;

public void Accelerate()
{
Speed += 10;
}
}

3. Inheritance

Inheritance facilitates code reuse and hierarchy in Unity. Components like MonoBehaviour serve as base classes, allowing developers to create custom behaviors by inheriting from them. A common example is extending the MonoBehaviour class to create custom scripts.

// Example in Unity
public class CustomScript : MonoBehaviour
{
// Custom functionality added here
}

3.1 Single Inheritance

A class can inherit from only one base class. For example, B inherits from A, creating a simple hierarchy.

public class A
{
// Class definition
}

public class B : A
{
// Inherits from A
}

3.2 Multiple Inheritance (through interfaces)

While C# doesn’t support multiple class inheritance, it allows multiple inheritance through interfaces. Unity components often inherit from multiple interfaces to acquire various functionalities.

public interface IDamageable
{
void TakeDamage(int amount);
}

public class Player : MonoBehaviour, IDamageable
{
public void TakeDamage(int amount)
{
// Player-specific damage logic
}
}

4. Polymorphism

Polymorphism enhances flexibility and extensibility in Unity. The Update method, found in scripts derived from MonoBehaviour, exemplifies polymorphism. Each script can implement its unique Update behavior.

// Example in Unity
public class Enemy : MonoBehaviour
{
void Update()
{
// Enemy-specific update logic
}
}

4.1 Compile-Time Polymorphism (Method Overloading)

It allows a class to have multiple methods with the same name but different parameters. Unity’s Vector3 class has multiple Lerp methods with different parameter types.

public class MathOperations
{
public int Add(int a, int b)
{
return a + b;
}

public float Add(float a, float b)
{
return a + b;
}
}

4.2 Run-Time Polymorphism (Method Overriding)

It allows a subclass to provide a specific implementation of a method defined in its superclass. Unity’s MonoBehaviour methods like Update are overridden in scripts for custom behavior.

public class Animal
{
public virtual void MakeSound()
{
Debug.Log("Generic animal sound");
}
}

public class Dog : Animal
{
public override void MakeSound()
{
Debug.Log("Woof! Woof!");
}
}

5. Interface

Interfaces define contracts in Unity, ensuring that classes implementing them adhere to a specific set of methods. The IDamageable interface might be implemented by various game entities that can take damage.

// Example in Unity
public interface IDamageable
{
void TakeDamage(int amount);
}
public class Player : MonoBehaviour, IDamageable
{
public void TakeDamage(int amount)
{
// Player-specific damage logic
}
}

5.1 Basic Interface

An interface defines a contract for classes to implement. For example, IDamageable ensures that any class implementing it must have a TakeDamage method.

public interface IDamageable
{
void TakeDamage(int amount);
}

5.2 Multiple Interface

Unity often uses multiple interfaces to enforce a class adhering to various contracts, such as IDamageable and IDisplayable.

public interface IDisplayable
{
void Display();
}

public class Character : IDamageable, IDisplayable
{
public void TakeDamage(int amount)
{
// Damage logic
}

public void Display()
{
// Display logic
}
}

5.3 Explicit Interface Implementation

It’s a way to implement an interface explicitly, resolving naming conflicts and making it clear which interface a method belongs to.

public interface IShape
{
void Draw();
}

public class Square : IShape
{
void IShape.Draw()
{
Debug.Log("Drawing a square");
}
}

Conclusion

In conclusion, the utilization of OOP concepts in Unity is paramount for creating scalable, maintainable, and extensible game systems. Understanding classes, encapsulation, inheritance, polymorphism, and interfaces empowers developers to craft well-organized and efficient code. As you embark on your Unity journey, remember that embracing OOP principles will pave the way for building captivating and dynamic game experiences. Happy coding!

--

--

Swapnil More

With 7 years of experience in the mechanical engineering arena, I bring a wealth of knowledge and a passion for innovation to the table.