March 03 2020
Picture yourself at the university’s library, holding a heavy 1000-page Calculus book on your hands for about two hours. Tell me, how would that feel on your arms? Here’s the thing: that’s exactly what Unity is doing by default to your operating system with all your text files. Here’s the more lightweight solution: Unity Addressables TextAsset loading.
In this blog post, you’ll learn how to:
Maybe you’ve been in this situation.
Or maybe you haven’t yet, but you will.
Handling large text files is a bit problematic in Unity. What happens under the hood is just too implicit…
Many developers are unaware of the memory implications of using big text files in Unity.
In any case, there are different ways to handle text files in Unity, and some are plain worse than others.
Let’s see them.
Games love text files.
From small configuration files to huge XML databases that hold game items that you generated with an external tool.
Some developers even use JSON files to support game localization.
No matter the reason, many game developers prefer to work with text files for certain subsystems of their games. What they do next is to import these text files into Unity and then get them loaded into memory… somehow.
In Unity, there are several ways you can load text files into memory. Sorted from least desirable to most desirable:
While reading text files from StreamingAssets on demand is fine, sometimes it’s just nice if we can let Unity help us a bit through references and its TextAsset API. And as you might argue, it’s better to avoid hardcoded paths such as StreamingAssets/MyEpicWeapons.xml
What we want is to leverage the memory efficiency of StreamingAssets with the power of Unity references.
Surprise! We can easily do this with Unity Addressables + TextAsset processing.
Here’s the process:
Easy.
Since I’ve done already quite many tutorials on this, I won’t go in detail on the steps but on the last one. For more information, read my Unity Addressables Tutorial and/or download this unity project here.
Let’s create a script that loads the file, prints its length to the console and then unloads it.
Read the code for PrintAddressablesTextLength.cs below:
public class PrintAddressablesTextLength : MonoBehaviour
{
[SerializeField] private AssetReference _addressableTextAsset = null;
void Start()
{
_addressableTextAsset.LoadAssetAsync<TextAsset>().Completed += handle =>
{
Debug.Log($"Length: {handle.Result.text.Length}");
Addressables.Release(handle);
};
}
}
It can hardly be simpler.
As soon as you add this script to any game object, you’ll be able to assign an indirect reference pointing to any TextAsset file in your Assets directory. On Start, you’ll see how it automatically prints the length of the text file for you.
The main benefit of this approach is that you pay the memory and loading times on demand, while the traditional route of assigning direct references makes you pay by default.
To go a step further, you can create an addressable group for text files that use LZMA compression. This algorithm is very suitable for text as I show in my Unity Addressables Compression Benchmark.
Doesn’t it feel better now that you left the calculus book on the bookshelf to hold it only when you really need it?