GHUD can connect Unity assets to database rows. This allows row-specific prefabs, sprites, materials, audio clips, meshes, and animator controllers to be accessed through the same kind of APIs used for spreadsheet data.
This page will teach you how to use those accessors, how to use the system to make them available,
as well as the instructions for asset loading.
Assets are loaded when their generated accessor is called. Once loaded, they are cached for later calls.
The details of this cache are covered in Resources and Memory Management, the bottom section of this page.
You can use GHUD to reference assets related to the rows within your data tabs.
This can be done with the same kind of method calls you'd use to access sheets data.
[Tab].[AssetType]([RowEnum])
Remember to add null checks as pictured on line 293, as unlike data references, assets will be null until added.
The default accessor methods are as follows:
Prefab (returns GameObject)
Sprite (returns Sprite)
Material (returns Material)
AudioClip (returns AudioClip)
Mesh (returns Mesh)
RuntimeAnimatorController (returns RuntimeAnimatorController)
Custom accessor methods are possible for additional asset loading for any asset type.
See Optional Reference Strategies below.
Before generating an asset loader, the tab must already exist in GHUD.
If you recently added the tab to your Google Sheet, run Get All Data first.
Then complete the four steps below.
1. Choose the loader options
Open Tools > GHUD > Window.
Look to the ~ Asset Loading ~ section.
In ~ Asset Loading ~,
Select the tab you want to reference assets for from LoaderTab dropdown.
Check each supported asset type checkbox you want to generate , and click Generate Asset Loader Script for [TabName] with:...
This will generate a partial class of the matching tab, and folders for asset housing.
2. Locate the generated files and folders
GHUD creates
Assets/GHUDatabase/UserScripts/Partials/[TabName]_Assets.cs
(This partial file only needs to be generated once per file, and so are open to edits.)
And the selected asset-type folders under
Assets/GHUDatabase/Resources/GHUD/TabAssets/[TabName]/
Place assets in those folders you want to reference through the new partial script.
3. Place assets in the TabAssets folders.
Place each asset in its matching folder.
By default, its name must exactly match the corresponding row enum value.
EAbilities.Club → Club.wav → Abilities.AudioClip(EAbilities.Club)
EAbilities.Club → Club.prefab → Abilities.Prefab(EAbilities.Club)
Rows without matching assets present in the TabAssets folders will return Null.
Note in the GHUD Unity Asset Store package, there are extra prefabs and materials in the TabAssets to account for URP and HDRP render pipelines. Your project will not need to make these distinctions; the files are available for each to ensure the examples work regardless of which render pipeline your project uses.
4. Set Asset References
The assets references are stored as Resources directory lookup strings.
The reason for this is to reduce loading times on tab asset loading,
which can be substantial when thousands of assets are connected.
For more information about how GHUD manages assets loaded into memory, see Resources and Memory Management.
With the correctly named assets placed in the TabAssets folders, click Set Asset References in the GHUD window,
Or from the Unity Editor menu bar select
Tools → GHUD → Reference Assets → 0 Set Asset References
This editor method checks every tab that has an asset loader and stores the references to the relevant assets in the respective DataTab prefab. The DataTab prefabs use the asset references to load them when [Tab].[AssetType]([rowEnum]) is called.
If text is entered in one of the serialized reference elements, and a valid asset is found in the folders, the text will be overwritten.
In the case that a serialized reference exists, but the asset does not exist,
Set Asset References will not erase the existing reference.
To clear existing references to assets that no longer exist in the TabAssets folders, run Clear Missing References.
5. Regenerating Tab Asset Partial Files.
If [TabName]_Assets.cs already exists,
GHUD asks for confirmation before overwriting it.
Confirming the overwrite replaces any custom changes in that asset loader,
so be sure you don't need them first.
Adding project-specific accessors can be useful; the [TabName]_Assets.cs classes are ideal places to create those extensions.
These files are found in Assets/GHUDatabase/UserScripts/Partials/
Here are some strategies to add to or improve asset references.
1. Editable Asset Name Column
By default, assets must be named such that they match the enum name of the related row.
This can be changed to allow for another naming scheme.
A recommended strategy to accomplish this would be to have a dedicated column for the reference name.
Let's implement this strategy with the Abilities tab from the GHUD Template:
Then after updating GHUD from the Get All Data button,
open Assets/GHUDatabase/UserScripts/Partials/Abilities_Assets.cs
From there, find the Load method for the specific asset type; in this case, it's LoadAudioClips
Press Ctrl + M + O to collapse all methods to make it easier to scan, or search for "Load" + the asset type name.
To have the method use the name column instead of the enum name reference,
simply add the name column's array reference as an extra parameter in the LoadAssetsOfType<T> method call.
The array is directly accessible here because [TabName]_Assets.cs and [TabName].cs both define the same partial class. Therefore, instead of calling the public Abilities.SfxName(...) accessor, we can directly pass the generated _sfxName array.
Save the script, then update the asset reference now from GHUD. Set Asset References should work,
but if the path is stuck looking at an old asset, you can use Clear Missing References instead.
If there is an error, you likely just need to use Get All Data again.
And that's all you need to do to have your asset name references editable from your Google Sheets.
This is particularly useful when you need to reference multiple assets of the same type within the same tab.
2. Adding Asset Arrays
Sometimes a tab needs to reference an unsupported asset type or more than one asset of the same type.
For example, the Abilities tab may need one AudioClip for the ability’s sound effect and a second AudioClip for the sound played when the ability impacts its target.
In this example, SfxName is already being used to populate the normal AudioClip array, while the new ImpactSFX column will populate a second AudioClip array.
The values in ImpactSFX match the hypothetical names of the Unity AudioClip assets we want to reference.
After adding the column, use Get All Data so GHUD generates the new column data in Abilities.cs.
The generated tab class will now contain the array: [SerializeField] string[] _impactSFXs;
The generated _impactSFXs array can be accessed directly from Abilities_Assets.cs
because both files define the same partial class.
Add a pair of arrays to Abilities_Assets.cs for the new asset; one for the stored asset reference, and one for the loaded asset.
[SerializeField] string[] _impactSFXs;
AudioClip[] _loadedImpactSFXs;
Next, add an accessor for the impact array so it can be referenced by its EAbility row, just like the original AudioClip array.
One limitation here is we can't use the exact same name as the column, as there is already a generated accessor for the exact column name. In this example, we can't call the accessor "ImpactSFX", so we call it "ImpactAudioClip".
public static AudioClip ImpactAudioClip(EAbility abilityID)
{
return Instance.GetAssetOfType(ref Instance._loadedImpactSFXs, Instance._impactSFXs, (int)abilityID);
}
Because this new array participates in GHUD’s runtime asset cache, it also needs to be included in ClearCache().
Add it to the existing cleanup logic so its cached entries are untracked before the array reference is cleared.
UntrackCachedAssetArray(_loadedImpactSFXs);
_loadedImpactSFXs = null;
Next, add a loading method for the impact AudioClip array.
This uses the same AudioClip folder, but passes the string array _impactSFX as the reference-name array.
This will have GHUD match each row using the ImpactSFX Column.
private void LoadImpactSFXs(bool overrideValues = false, bool logResults = true)
{
LoadAssetsOfType<AudioClip>(ref _impactSFXs, _audioClipPath, overrideValues, logResults, _impactSFX);
}
Finally, call the new loading method from LoadAllAssets() so it runs whenever GHUD loads asset references.
LoadImpactSFXs(overrideValues, logResults);
Save the script,
then use Set Asset References so GHUD populates the new ImpactSFX array from the names in the ImpactSFX column.
If there is an error, try running Get All Data to ensure you have the latest sheets data.
The new impact sound can then be accessed with:
Abilities.ImpactAudioClip([EAbility]);
Or whatever you named the accessor method.
3. Adding Unsupported Asset Types
If you need to add an unsupported asset type, such as AnimationClip or PhysicsMaterial, that is possible too.
Simply follow the instructions for #2: Adding Asset Arrays above,
except you set the private loader array, and the public accessor to the desired type.
Remember the accessor method name isn't allowed to match any column name exactly, as that's a separate generated accessor.
[SerializeField] string[] _animationClips;
AnimationClip[] _loadedAnimationClips;
public static AnimationClip AnimClip(EAbility abilityID)
{
return Instance.GetAssetOfType(
ref Instance._loadedAnimationClips,
Instance._animationClips,
(int)abilityID);
}
For the folder path for assets of custom types, you should set a path variable near the top of the class.
[SerializeField] string _[Your Folder]Path = "Assets/GHUDatabase/Resources/GHUD/TabAssets/Abilities/[Your Folder]/";
The custom path variable is what you should use in the private array loader method which gets called from LoadAllAssets.
Note the example below, the optional name parameter is not used, so the loader will look for AnimationClips with a name matching the enum. You can of course use the name parameter if desired, but because there isn't another asset array of the same type pointing to the same folder like there was for the #2 example, the name array it isn't required.
LoadAnimationClips(overrideValues, logResults);
private void LoadAnimationClips(bool overrideValues = false, bool logResults = true)
{
LoadAssetsOfType<AnimationClip>(ref _animationClips, _customPath, overrideValues, logResults);
}
Remember to add your private loaded asset array
to the ClearCache()!
UntrackCachedAssetArray(_loadedAnimationClips);
_loadedAnimationClips = null;
GHUD loads an asset the first time its generated accessor requests it, then caches the reference for later calls. Generated loaders report each load and reuse to one project-wide AssetMemoryManager.
The manager uses least-recently-used ordering. A newly loaded asset is added to the back of the eviction queue.
Using a cached asset again moves it to the back, so the oldest entries are removed first.
The default hard limits are 256 tracked assets and 512 MB of estimated tracked memory. Eviction begins only after either hard limit is exceeded. The default Flush-To Percent is 60%, so a flush continues until both the tracked count and estimated memory are at or below 60% of their limits. The manager always preserves at least one tracked entry, including when one asset alone exceeds the memory limit.
While most useres won't need to bother with this, you can configure these project-wide settings on:
Assets/GHUDatabase/Resources/GHUD/DataTabs/AssetMemoryManager.prefab
• Max Tracked Assets:
Maximum number of cached entries before a flush is requested.
While less technically useful than the Max Tracked Asset Memory MB,
it serves as a backup for when the memory data is not accessible for certain asset types.
Increasing this reduces flush frequency, but increases RAM usage.
• Max Tracked Asset Memory MB:
Maximum estimated memory before a flush is requested.
While the system can't get an exact read on RAM usage from the files, it estimated them based on the file size,
which is recorded on asset loading from the editor. Increasing this reduces flush frequency, but increases RAM usage.
• Flush To Percent:
Target percentage for both limits after a flush begins.
A higher % allows more consistency of cashed assets, but increases the frequency at which assets are flushed.
• Wait For Scene Change To Flush Assets:
Delays an over-limit flush until the next scene loads. When disabled, the flush happens immediately upon demand.
The reason this may be desired is that asset flushing can cause lag; this forces that lag to happen during a scene transition.
It is checked by default, so if you are finding RAM usage too high with prolonged time on the same scene, uncheck this field.
Eviction clears GHUD's cached reference. An asset referenced by a scene or another system can remain loaded.
So no matter how these fields are set, the system will function, but at varied performance.
Loading cached assets is faster, but the more assets are cached, the more RAM is required.
After cached entries are evicted, GHUD requests Resources.UnloadUnusedAssets(), which unloads only assets Unity considers unused. If an evicted asset is requested through GHUD again, it is loaded and cached again.