Basic Usage
TriLib provides three primary ways to load a model together with its dependencies:
- From the local file system
- From a URL
- From a custom data source
You can also implement another loading workflow. The underlying APIs consume Streams, while ScriptableObject-based Mappers resolve textures and other external content from custom streams.
Local File-System Loading
Using a File Picker
The StandaloneFileBrowser classes included with TriLib make it straightforward to select and load models stored locally.
For this example, begin with an empty Unity project and import the TriLib Unity package. Include the StandaloneFileBrowser folder when choosing which package contents to extract.
Create a script named TestLoader.cs, then attach it to the Main Camera in the scene.
Paste the following code into TestLoader.cs and enter Play mode:
using TriLibCore;
using TriLibCore.General;
using UnityEngine;
public class TestLoader : MonoBehaviour
{
// Lets the user load a new model by clicking a GUI button.
private void OnGUI()
{
// Displays a button to begin the model loading process.
if (GUILayout.Button("Load Model from File"))
{
// Creates an AssetLoaderOptions instance.
// AssetLoaderOptions is a class used to configure many aspects of the loading process.
// We won't change the default settings this time, so we can use the instance as it is.
var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions();
// Creates the AssetLoaderFilePicker instance.
// AssetLoaderFilePicker is a class that allows users to select models from the local file system.
var assetLoaderFilePicker = AssetLoaderFilePicker.Create();
// Shows the model selection file-picker.
assetLoaderFilePicker.LoadModelFromFilePickerAsync("Select a File", OnLoad, OnMaterialsLoad, OnProgress, OnBeginLoad, OnError, null, assetLoaderOptions);
}
}
// This event is called when the model is about to be loaded.
// You can use this event to do some loading preparation, like showing a loading screen in platforms without threading support.
// This event receives a Boolean indicating if any file has been selected on the file-picker dialog.
private void OnBeginLoad(bool anyModelSelected)
{
}
// This event is called when the model loading progress changes.
// You can use this event to update a loading progress-bar, for instance.
// The "progress" value comes as a normalized float (goes from 0 to 1).
// Platforms like UWP and WebGL don't call this method at this moment, since they don't use threads.
private void OnProgress(AssetLoaderContext assetLoaderContext, float progress)
{
}
// This event is called when there is any critical error loading your model.
// You can use this to show a message to the user.
private void OnError(IContextualizedError contextualizedError)
{
}
// This event is called when all model GameObjects and Meshes have been loaded.
// There may still Materials and Textures processing at this stage.
private void OnLoad(AssetLoaderContext assetLoaderContext)
{
// The root loaded GameObject is assigned to the "assetLoaderContext.RootGameObject" field.
// If you want to make sure the GameObject will be visible only when all Materials and Textures have been loaded, you can disable it at this step.
var myLoadedGameObject = assetLoaderContext.RootGameObject;
myLoadedGameObject.SetActive(false);
}
// This event is called after OnLoad when all Materials and Textures have been loaded.
// This event is also called after a critical loading error, so you can clean up any resource you want to.
private void OnMaterialsLoad(AssetLoaderContext assetLoaderContext)
{
// The root loaded GameObject is assigned to the "assetLoaderContext.RootGameObject" field.
// You can make the GameObject visible again at this step if you prefer to.
var myLoadedGameObject = assetLoaderContext.RootGameObject;
myLoadedGameObject.SetActive(true);
}
}
</pre>
Using the Model Filename
Models can also be loaded by supplying their filename directly to an AssetLoader method.
Start with an empty Unity project, import the TriLib Unity package, and create a script named TestLoader.cs. Attach the script to the scene's Main Camera.
Add the code below to TestLoader.cs, then enter Play mode to try it:
using TriLibCore;
using TriLibCore.General;
using UnityEngine;
public class TestLoader : MonoBehaviour
{
// Lets the user load a new model by clicking a GUI button.
private void OnGUI()
{
// Displays a button to begin the model loading process.
if (GUILayout.Button("Load Model from File"))
{
// Creates an AssetLoaderOptions instance.
// AssetLoaderOptions is a class used to configure many aspects of the loading process.
// We won't change the default settings this time, so we can use the instance as it is.
var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions();
// Loads the model from the "PATH_TO_MY_FILE.FBX" path
AssetLoader.LoadModelFromFile("PATH_TO_MY_FILE.FBX", OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions);
}
}
// This event is called when the model is about to be loaded.
// You can use this event to do some loading preparation, like showing a loading screen in platforms without threading support.
// This event receives a Boolean indicating if any file has been selected on the file-picker dialog.
private void OnBeginLoad(bool anyModelSelected)
{
}
// This event is called when the model loading progress changes.
// You can use this event to update a loading progress-bar, for instance.
// The "progress" value comes as a normalized float (goes from 0 to 1).
// Platforms like UWP and WebGL don't call this method at this moment, since they don't use threads.
private void OnProgress(AssetLoaderContext assetLoaderContext, float progress)
{
}
// This event is called when there is any critical error loading your model.
// You can use this to show a message to the user.
private void OnError(IContextualizedError contextualizedError)
{
}
// This event is called when all model GameObjects and Meshes have been loaded.
// There may still Materials and Textures processing at this stage.
private void OnLoad(AssetLoaderContext assetLoaderContext)
{
// The root loaded GameObject is assigned to the "assetLoaderContext.RootGameObject" field.
// If you want to make sure the GameObject will be visible only when all Materials and Textures have been loaded, you can disable it at this step.
var myLoadedGameObject = assetLoaderContext.RootGameObject;
myLoadedGameObject.SetActive(false);
}
// This event is called after OnLoad when all Materials and Textures have been loaded.
// This event is also called after a critical loading error, so you can clean up any resource you want to.
private void OnMaterialsLoad(AssetLoaderContext assetLoaderContext)
{
// The root loaded GameObject is assigned to the "assetLoaderContext.RootGameObject" field.
// You can make the GameObject visible again at this step if you prefer to.
var myLoadedGameObject = assetLoaderContext.RootGameObject;
myLoadedGameObject.SetActive(true);
}
}
URL Loading
Use the AssetDownloader class to retrieve models over the network. Its API closely resembles the local file-loading workflow.
Create an empty Unity project and import the TriLib Unity package. Be sure to extract the StandaloneFileBrowser folder as part of the import.
Add a script called TestLoader.cs and attach it to the Main Camera in your scene.
Important: When the remote model is not inside a ZIP archive, pass its file extension as the final argument to AssetDownloader.LoadModelFromUri (for example, "fbx").
Place the following code in TestLoader.cs and enter Play mode:
using TriLibCore;
using TriLibCore.General;
using UnityEngine;
public class TestLoader : MonoBehaviour
{
// Lets the user load a new model by clicking a GUI button.
private void OnGUI()
{
// Displays a button to begin the model loading process.
if (GUILayout.Button("Load Model from URL"))
{
// Creates an AssetLoaderOptions instance.
// AssetLoaderOptions is a class used to configure many aspects of the loading process.
// We won't change the default settings this time, so we can use the instance as it is.
var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions();
// Creates the web-request.
// The web-request contains information on how to download the model.
// Let's download a model from the TriLib website.
var webRequest = AssetDownloader.CreateWebRequest("https://ricardoreis.net/trilib/demos/avatars/003/003_visemes.zip");
// Important: If you're downloading models from files that are not Zipped, you must pass the model extension as the last parameter from this call (Eg: "fbx")
// Begins the model downloading.
AssetDownloader.LoadModelFromUri(webRequest, OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions, null, null);
}
}
// This event is called when the model loading progress changes.
// You can use this event to update a loading progress-bar, for instance.
// The "progress" value comes as a normalized float (goes from 0 to 1).
// Platforms like UWP and WebGL don't call this method at this moment, since they don't use threads.
private void OnProgress(AssetLoaderContext assetLoaderContext, float progress)
{
}
// This event is called when there is any critical error loading your model.
// You can use this to show a message to the user.
private void OnError(IContextualizedError contextualizedError)
{
}
// This event is called when all model GameObjects and Meshes have been loaded.
// There may still Materials and Textures processing at this stage.
private void OnLoad(AssetLoaderContext assetLoaderContext)
{
// The root loaded GameObject is assigned to the "assetLoaderContext.RootGameObject" field.
// If you want to make sure the GameObject will be visible only when all Materials and Textures have been loaded, you can disable it at this step.
var myLoadedGameObject = assetLoaderContext.RootGameObject;
myLoadedGameObject.SetActive(false);
}
// This event is called after OnLoad when all Materials and Textures have been loaded.
// This event is also called after a critical loading error, so you can clean up any resource you want to.
private void OnMaterialsLoad(AssetLoaderContext assetLoaderContext)
{
// The root loaded GameObject is assigned to the "assetLoaderContext.RootGameObject" field.
// You can make the GameObject visible again at this step if you prefer to.
var myLoadedGameObject = assetLoaderContext.RootGameObject;
myLoadedGameObject.SetActive(true);
}
}
Importing Avatars
Loading an avatar through TriLib requires some additional configuration.
Configure AssetLoaderOptions
Configure AssetLoaderOptions before starting the load:
- Set
AssetLoaderOptions.AnimationTypetoAnimationType.Humanoid. - Assign a
HumanoidAvatarMappertoAssetLoaderOptions.HumanoidAvatarMapper.
The HumanoidAvatarMapper associates the source model's bones with Unity Animator/Mecanim bones and muscles.
TriLib supplies a MixamoAndBipedByName mapper for rigs created with Mixamo, Biped, or DAZ Studio conventions.
Using a Custom HumanoidAvatarMapper
To support another skeleton naming scheme, create a ByNameHumanoidAvatarMapper asset. In the Project window, right-click and choose:
Create -> TriLib -> Mappers -> Humanoid -> ByNameHumanoidAvatarMapper
Select the new asset and configure its name-based bone matches in the Inspector.
A convenient way to use the mapper is to expose a public field on the component that loads the avatar, then assign the mapper asset to that field in the Inspector.
Putting It All Together
TriLib offers several model-loading entry points, described earlier on this page. The following snippet only demonstrates the avatar-specific options. Add it where you prepare AssetLoaderOptions, then load the model with whichever method fits your application:
var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions(false, true);
assetLoaderOptions.AnimationType = AnimationType.Humanoid;
// A HumanoidAvatarMapper may instead come from a public field assigned in the Inspector.
assetLoaderOptions.HumanoidAvatarMapper = Resources.Load<HumanoidAvatarMapper>("Mappers/Avatar/MixamoAndBipedByNameHumanoidAvatarMapper");
Assigning an AnimatorController
After the avatar loads, you can give it an AnimatorController. This is commonly done from OnMaterialsLoad:
var animator = assetLoaderContext.RootGameObject.GetComponent<Animator>();
// MyAnimatorController can be a public field assigned through the Inspector.
animator.runtimeAnimatorController = MyAnimatorController;