π Game Resources
What are GameResources
- GameSuite's resource management system
- Everything is weak referenced and loaded through Guids
Advantages of using GameResources
- It takes all the complications out of loading, unloading and managing assets and memory
- Uniform way of accessing asset from Resources folders or Addressables
- Sync and Async loading support
- Works the same as any Library
- Supports AB Testing: swap, enable or disable any resource
Instantiating GameObjects
GameResources are basically a Library, so it can be used in the same way, showing a dropdown in the inspector, with the addition to drag and drop the object.
[Resource]
public Guid graphic;
Safe to rename
As every Unity asset is referred to by its internal Guid, which makes it safe to rename or move the assets around in the project, as long as they are either in a Resources folder or marked as Addressable.
There are a few different methods available, depending on what kind of asset needs to be loaded.
Instantiating a GameObject:
using GameSuite;
namespace Game
{
public class GraphicSpawner : SerializedMonoBehaviour
{
[SerializeField, Resource]
private Guid graphic;
protected void Start()
{
// This spawns the graphic under the current transform.
GameObject instance = GameResources.Instantiate(graphic, transform);
}
}
}
It is also possible to Instantiate asynchronously:
using GameSuite;
namespace Game
{
public class GraphicSpawner : SerializedMonoBehaviour
{
[SerializeField, Resource]
private Guid graphic;
protected void Start()
{
// This is a fire and forget async instantiate:
GameResources.InstantiateAsync(graphic, transform);
// Or in case the object needs further processing:
GameResources.InstantiateAsync(graphic, transform, GraphicSpawned);
}
private void GraphicSpawned(GameObject instance)
{
// Do something with the spawned instance here.
}
}
}
Instantiating sync and async supports different parameters:
// Spawns the graphic on the root.
GameResources.Instantiate(graphic);
// Spawns the graphic under the transform.
GameResources.Instantiate(graphic, transform);
// Spawns the graphic under the transform with translation.
GameResources.Instantiate(graphic, transform, position, rotation);
// The same parameters exist for the async methods.
GameResources.Instantiate(graphic, transform, position, rotation, callback);
Destroying objects
To unload any instantiated GameObject, just Destroy(gameObject)
it through normal means, GameSuite will take care of the rest internally.
Every instantiated object gets a hidden component attached which GameSuite subscribes to and handles the object destruction when it gets deleted automatically.
Use GameResources everywhere
It is highly advised to use GameResources.Instantiate
instead of the Unity's GameObject.Instantiate
in all scenarios.
It keeps internal references to items and when an object is destroyed and it flushes it from Addressables automatically when no further references exist.
Get instances
To get all instances of an instantiated object: GameResources.TryGetInstances(Guid guid, out List<GameObject> instances)
.
Loading other types of objects
By default the [Resource]
attribute will only allow GameObjects to be set as its the most common use case.
If it requires other types of resources, it can be done by passing a type:
[Resource]
public Guid Prefab;
[Resource(typeof(Material))]
public Guid Material;
[Resource(typeof(VideoClip))]
public Guid VideoClip;
[Resource(typeof(Animator))]
public Guid Animator;
Get any resource
In most cases you want to get only certain types of assets as you are going to do something specific with them, but in case of a scenario where you want any object from the entire resource library, use this:
[Resource(null, null)]
public Guid AnyResource;
Now that we have the resource the game needs, in order to load an asset of a certain type, use LoadAsset<T>
:
Texture texture = GameResources.LoadAsset<Texture>(graphic);
// To unload it from memory:
GameResources.UnloadAsset(graphic);
There is also an asynchronous version available, just like with GameObjects:
using GameSuite;
namespace Game
{
public class GraphicSpawner : SerializedMonoBehaviour
{
[SerializeField, Resource]
private Guid graphic;
protected void Start()
{
// Load the texture async:
GameResources.LoadAssetAsync(graphic, TextureLoaded);
}
protected void OnDestroy()
{
// Force unload the graphic from memory.
GameResources.UnloadAsset(graphic);
}
private void TextureLoaded(Texture texture)
{
// Do something with the spawned texture here.
}
}
}
Filter
The resource attribute allow to filter by type like, but also by folder.
[Resource("UI/Buttons")]
public Guid Button;
It also allows for filtering on both the type of resource and a sub folder:
[Resource(typeof(Animator), "Animations/Characters/Bosses")]
public Guid BossAnimator;
Addressable folder
Note the folder is related to the highest level folder which is marked as addressable. In case of using Unity's Resources folders, it is related to the sub-folders underneath the Resources folder the asset is under.
Resources
- Any assets in any folder named Resources is automatically included in the build and can be loaded.
Addressables
- Any asset tagged as addressable in the inspector, or any of the parent folders, is included in the build as part of an asset bundle
- Asset bundles can be baked into the build, uploaded to a CDN or both, allowing a fallback
Inspector dropdown
To only show a limited subfolder to select items in the resource dropdown, pass in a string as parameter to the Resource attribute:
[Resource("UI/Buttons"]
public Guid buttonGraphic;
By default the dropdown shows all assets that can be accessed through Unity Resources and Addressables. To excluded project folders from the dropdown, add them to the Exclude Folders list on the ResourceLibrary asset in the project:
Debug Menu
There are multiple ways to interact and spawn GameResources using the Debug Menu, such as being able to spawn any GameObject:
Debug Menu > Project Explorer > Resource Loader
Scenes are also able to load and unload from the same menu.
Hierarchy explorer
Just like the Unity editor, the hierarchy and all its GameObjects, Components and even variables are viewable through the debug menu. Objects and components can be enabled, disabled and destroyed. This will help a lot when debugging issues on device.
Async latency simulator
Loading assets async can result in unwanted race conditions, especially on lower end devices. To test if the code supports slow loading times, use the debug menu tool:
Debug Menu > Game State > Addressables > Async Latency
Set the latency to a high number to verify that everything works as intended even with extreme async loading times.