Introduction to Modding Unity Games With Addressables

Use Unity Addressables to make it easy to let users create mods, enhancing the user experience and expressing their creativity through your game. By Ajay Venkat.

4.9 (13) · 3 Reviews

Download materials
Save for later
Share

Sometimes, the best content within a game isn’t made by the developers, but by the game’s amazing community. This is possible thanks to mods. A mod is a piece of user-generated content that changes the way a game looks, behaves or sounds, allowing players to express their creativity through your game.

Traditionally, structuring games to support mods has been difficult. Fortunately, Unity is working on a system to address this called the Addressable Asset System, also known as Addressables.

In this tutorial, you’ll learn how to make a simple moddable FPS game that changes its functionality and graphics depending on the mod a user selects. Throughout this process, you’ll get hands-on experience with:

  • Loading and unloading content through Addressables.
  • Setting up a game for modding.
  • Creating a mod that changes models, textures, sounds and functionality.
Note: This tutorial assumes that you’re familiar with Unity development and C#. If you’re new to Unity development, check out our Getting Started in Unity tutorial. If you’re new to Addressables and the process of how to set up and configure them, read Introduction to Addressables.

You’ll need a copy of Unity 2020.1 or newer on your machine to follow along with this tutorial.

Getting Started

Once you’ve installed Unity, download the sample project by clicking the Download Materials button at the top or bottom of this tutorial. Note that there are two starter (and final) projects:

  • Game Starter: You’ll create the moddable game in this project.
  • Content Starter: Here, you’ll create the mods for that game.

Once downloaded, extract the files and open the Game Starter project in Unity. When the project loads, open the RW folder using the Project window and take a look at the folder structure:

List of folders in RW

Here’s what each folder contains:

  • Animations: Basic animations for the weapons.
  • Materials: Simple materials for the prefabs.
  • Models: Base models for the default content.
  • Prefabs: Particle effects for the Player, Target, Bullet and Impact.
  • Scenes: An empty scene.
  • Scripts: All the scripts in the game.
  • SFX: Sound effects for the weapon and impact.
  • Sprites: Crosshair sprites.

And here are the things you’ll allow modders to change in your game:

  • Target model
  • Bullet model
  • Bullet sound effects
  • Gun model
  • Movement speed
  • Bullet speed

So, how do you achieve this with the Addressables system? Before you start coding, take a moment to understand what Addressables do.

Understanding Addressables

So far, letting users mod their games has been difficult for developers. You usually have to tackle these issues:

  • Loading dependencies from user-generated content.
  • Unloading original game content and replacing it with the correct user-generated content.
  • Loading and unloading assets asynchronously.
  • Allowing players to easily generate content for your game.

Addressables use the existing AssetBundles system to provide an easy way to load assets asynchronously using an address. This lets developers abstract the process of retrieving the assets.

You can use AssetBundles directly, but they don’t address any of these problems. :]
Addressables provide an entire content management pipeline, while AssetBundles are simply a way to package content.

Advantages of Addressables

The first thing you should know is that the Addressables system does not support modding out of the box. Rather, they’re a concept that allows you to build a layer of abstraction between the game development and the knowledge of where assets are.

Normally, if you wanted to spawn a bullet, you would write something similar to this:


public GameObject bulletPrefab;

public void Shoot() 
{
    GameObject.Instantiate(bulletPrefab);
}

The caveat of this method is that you have to assign a prefab that exists within the project to bulletPrefab. There are two limitations to this:

  • The project size will become very big.
  • Unity will load every prefab stored in a reference into memory, even if the scene doesn’t use it.

The Addressables system allows you to do something like this, instead:


public string bulletAddress;

public void Shoot() 
{
    Addressables.Instantiate(bulletAddress, instantiationParameters);
}

Now, as long as you know the bulletAddress, the Addressables system will handle retrieving the prefab from its location, then load it into memory asynchronously.

The benefit is that Unity can locate the asset from anywhere. In this case, the asset can either be in memory as part of the original game or in an external mod file.

For testing purposes, Addressables will cache assets. That means that load times are minimal when you emulate a production environment during playtesting, thus reducing development time.

Looking Under Addressables’ Hood

Before you use this system, you need to know how it works. When you build a mod using Addressables, Unity will generate three types of files:

  • Catalog File: This file acts as a dictionary, mapping the address of an asset to its actual location, whether it be on a server or local.
  • Hash File: Determines if a new catalog is available.
  • Asset Bundles: The actual assets bundled using Unity’s Asset Bundles. Addressables separate the Asset Bundles based on the groups you assign to different assets.

Each mod will contain its own version of these three files with different content. To load content from different mods, you have to download its respective catalog file. Once you have the catalog file, you know exactly where all the assets are and you can load them into memory when you need them.

For a player to create a mod, all they need is a base Unity project containing the prefabs in the original game. With this, players can modify the prefabs to their liking without modifying the address of the prefab.

Exploring the Project

Open the Content Starter project, open the RW folder in the Project window and note the folder structure. The folders contain the same type of content from the Game Starter project, with quite a few modifications.

Open RW/Prefabs and note the prefabs. The modder has changed the bullet into a fish and the target into Randy Savage.

Image of the prefabs

It would be wrong to have a tutorial about modding without paying tribute to the legendary Randy Savage mod in Skyrim. And while you’re at it, why not throw some fish at him? You’ll also appreciate the sound effects. :]

Randy Savage mod in Skyrim

Umm, just be warned, this might be the weirdest tutorial you’ve followed. :]

Next, open the Bullet prefab and note the properties of the Bullet component.

Properties of the Bullet component

Note that Addressables support the ability to save the serializable attributes of a component. The limitation, however, is that you can’t change the functionality within a script. So, for the fish to act as a bullet, you’ll need to reduce the Speed to 25 to be more in line with what you’d expect from a fish flying through the sky. For even more realism, you’ll change the impact sound to a water splash effect.

The more variables you make accessible in the scripts, the more power you give modders beyond just changing how objects look. If you want, you can make further modifications to the prefabs before you move on.

For example, you can give these prefabs different models, shapes, sound effects and component values. Addressables will manage all the prefabs’ dependencies, so you can change anything you like.