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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Introduction to Modding Unity Games With Addressables
35 mins
- Getting Started
- Understanding Addressables
- Advantages of Addressables
- Looking Under Addressables’ Hood
- Exploring the Project
- Understanding the Addressables’ Settings
- Setting up the Mod
- Renaming and Building Addressable Assets
- Loading Mods Using Addressables
- Creating the Reference Lookup Manager
- Setting up the Reference Lookup Manager
- Instantiating Assets Into the Scene
- Removing Assets From Memory
- Modifying Player Scripts
- Handling Bullet Spawning
- Handling Debris Spawning
- Creating the Mod Manager
- Loading Mods From the Mod Directory
- Loading New Catalogs Into Addressables
- Loading Mods With a Button
- Changing the Currently Loaded Mod
- Finding Assets Within the Mod
- Creating the Default Mod
- Testing and Profiling the Game
- Using the Addressables Event Viewer
- Where to Go From Here?
Understanding the Addressables’ Settings
This project comes with Addressables already installed and configured for you, so you can jump ahead to look at the setup.
To view the settings of the Addressables system, select the AddressableAssetSettings file in Assets/AddressableAssetsData/, then look at the Inspector.
There are two important settings:
- Profile In Use: The profile of the Addressables system changes the location of the Build Path and Load Path. This dictates where Unity will export the catalog file and asset bundles. View the actual profile settings by selecting Manage Profiles.
- Build Remote Catalog: The catalog file tells you where the assets are, so you need to know its location to access the mod. Therefore, you need to tell Addressables to build the catalog along with the assets.
So what are Build Path and Load Path?
-
LocalBuildPath:
[UnityEngine.Application.dataPath]/Exported
-
LocalLoadPath:
{UnityEngine.Application.dataPath}/Resources/Mods
What does that mean? LocalBuildPath
is where Unity will export the mod. Look at the folders in the Project window and you’ll see an empty Exported folder. The mod will build to this folder. UnityEngine.Application.dataPath
points to the Assets folder of the Unity project.
It’s important to note that the square brackets denote the current project’s dataPath
, while the curly brackets denote the dataPath
of the project that’s loading the mod.
In the same way, LocalLoadPath is where you expect the mods to be. Open Game Starter and look at the folders and you’ll observe an Assets/Resources/Mods folder. Your scripts will search for the mods here. It’s a convention to locate the LocalLoadPath in UnityEngine.Application.persistentDataPath
but for ease of testing, you’re going to store it in a local directory that’s easily accessible.
Setting up the Mod
Back in the Content Starter project, select all the assets in RW/Prefabs and select Addressable in the Inspector.
By making these assets Addressable, Unity will pack the prefab together with all the dependencies. That’s all it takes, just a simple check!
Now open Window ▸ Asset Management ▸ Addressables ▸ Groups to view the different Addressables groups. Note the assets are under Default Local Group (Default).
Addressables support multiple groups. Each group can be in a different location and the catalog will still be able to retrieve it. For modding purposes, you only need Default Local Group (Default).
Renaming and Building Addressable Assets
The red outlined section is the actual address of each Asset. Select the four assets in that group and right-click to bring up a menu. Within the menu, select Simplify Addressable Names.
These are the addresses that you’ll use to refer to each prefab. Any new mods will have to use the same address so your game knows which Asset to spawn at which location.
Now, select Build ▸ New Build ▸ Default Build Script. That’s all it takes to create a mod for your game! Users can unleash their creativity upon the prefabs, and as long as they stick to the address naming convention, they can replace your game’s assets with anything they want.
These are the generated files within Assets/Exported:
The generated files include:
- A catalog file
- A hash file
- Two asset bundles
To rename the created mod, you can give both the catalog file and the hash file a different name. Ensure that they each share the same name since Addressables links them by file name — though you can change this under Addressables Settings. Now, change both of the file names to randy_savage.
To use this mod, open Assets/Exported in your operating system’s file explorer. To open the folder in your operating system, right-click on it and select Show in Explorer.
Now, move these mod files to Assets/Resources/Mods in the Game Starter project.
Now that the assets are in the LocalLoadPath, Addressables will be able to find the mods.
Loading Mods Using Addressables
Switch back to the Game Starter project. Open RW/Scenes/Fire Range and note that the scene is empty except for the building. Before you can test the game, you need to select the Mod Manager in the Hierarchy and select Load Mod in the Inspector.
Now, press Play and enjoy some simple FPS target practice.
Once you finish, select Unload Mod within the Inspector. Look at the Hierarchy and you’ll notice a Player Instance Holder. This is an empty GameObject that tells your game where to spawn the Player asset.
The same method is used for all the Target assets. The Load Mod and Unload Mod buttons within the Mod Manager GameObject allow you to visualize where the GameObjects will spawn when the game runs. This helps with level design during the development process. This is one possible pipeline you can use when working with mods.
Select the Player Instance Holder and view the Instance Holder component in the Inspector.
Name Reference tells you the address of the asset to spawn at this location and rotation, while the Placeholder is the visualization GameObject.
Creating the Reference Lookup Manager
This script is responsible for loading an asset by name, depending on the mod that’s currently loaded. Addresables stores the location of an asset in an IResourceLocation
. Therefore, mapping the address of an asset to an IResourceLocation
lets you find an asset by its address.
ReferenceLookupManager simply provides a central location where the rest of the scripts in the game can get assets, without having to worry about which mod is currently loaded.
Setting up the Reference Lookup Manager
Open RW/Scripts/ReferenceLookupManager.cs and add the following, above the class declaration:
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
This lets you access the classes that Addressables use.
Next, you need to add the following variables inside the class declaration:
// 1
public Dictionary<string, IResourceLocation> instances =
new Dictionary<string, IResourceLocation>();
// 2
private List<AsyncOperationHandle> loadedGameObjects =
new List<AsyncOperationHandle>();
Here’s what each of these do:
- Maps the address name to the
IResourceLocation
, letting you load that asset in the future. - Keeps track of all the GameObjects instantiated from this mod. You can use the handle to release the asset from memory when you delete it.
Note that ModManager
will fill the instances
variable depending on which mod the user has loaded. The requiredAssets
list tells the game which assets it needs to function. Here, the list already contains the following addresses: Player, Target, Bullet and Debris.
When a new mod loads, the game will find the requiredAssets
addresses within the mod, then add them to the instances
dictionary. Once instances
populates, other scripts within the game can request the assets by name. This ensures that gameplay scripts don’t have to worry about which mod is currently loaded.