Basic Usage

There are three main methods to load models and their dependencies in TriLib:

  • Local File-System Loading
  • URL Loading
  • Custom Source Loading

The user can adapt other loading mechanisms as the core loading methods accept Streams as data input and Scriptable Objects called Mappers, used to load textures, and external data from custom data Streams.

Local File-System Loading

Loading models from the local file-system is simplified by using the StandaloneFileBrowser classes that come with TriLib.

Let’s create an empty Unity project in this example and import the TriLib Unity package. Make sure you include the StandaloneFileBrowser folder when extracting.

Create a new Script. You can call it “TestLoader.cs” then assign this script to the “Main Camera” on your scene.

Use the following code in your “TestLoader.cs” and hit the play button to test 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();

            // Creates the AssetLoaderFilePicker instance.
            // AssetLoaderFilePicker is a class that allows users to select models from the local file system.
            var assetLoaderFilePicker = AssetLoaderFilePicker.CreateInstance();

            // 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);
    }
}
URL Loading

You can use the AssetDownloader class to load models from URLs (network). The usage is relatively simple and similar to the local file-system loading.

Let’s create an empty Unity project in this example and import the TriLib Unity package. Make sure you include the StandaloneFileBrowser folder when extracting.

Create a new Script. You can call it “TestLoader.cs” then assign this script to the “Main Camera” on your scene.

Use the following code in your “TestLoader.cs” and hit the play button to test 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 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");

            // Begins the model downloading.
            AssetDownloader.LoadModelFromUri(webRequest, OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions);
        }
    }

    // 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);
    }
}
Custom Source Loading


Besides the methods above, you can load models from any data source that can be read from a Stream.
The base methods LoadModelFromFileAsync and LoadModelFromStreamAsync allow you to pass a Path or a custom Stream in order to load your model, respectively.

Using Path:

var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions();
AssetLoader.LoadModelFromFile("PATH_TO_MY_MODEL.FBX", OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions);

Using Stream:

When using Stream loading, you may want to load external model dependencies and textures from custom data sources as well. To do that, you should create classes that inherit TextureMapper and ExternalDataMapper to specify how data will be loaded.

var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions();
assetLoaderOptions.ExternalDataMapper = ScriptableObject.CreateInstance<ExternalDataMapperSample>();
assetLoaderOptions.TextureMapper = ScriptableObject.CreateInstance<TextureMapperSample>();
var modelPath = "PATH_TO_MY_MODEL.FBX";
AssetLoader.LoadModelFromStream(File.OpenRead(modelPath), modelPath, null, OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions);

Here are the Mappers used on the code above. One creates Steams from external resource files and the other creates TextureLoadingContexts from files:

public class ExternalDataMapperSample : ExternalDataMapper
{
	public override Stream Map(AssetLoaderContext assetLoaderContext, string originalFilename, out string finalPath)
	{
		finalPath = $"{assetLoaderContext.BasePath}/{FileUtils.GetFilename(originalFilename)}";
		if (File.Exists(finalPath))
		{
			Debug.Log($"Found external file at: {finalPath}");
			return File.OpenRead(finalPath);
		}
		throw new Exception($"File {originalFilename} not found.");
	}
}
public class TextureMapperSample : TextureMapper
{
	public override TextureLoadingContext Map(AssetLoaderContext assetLoaderContext, ITexture texture)
	{
		var finalPath = $"{assetLoaderContext.BasePath}/{FileUtils.GetFilename(texture.Filename)}";
		if (File.Exists(finalPath))
		{
			var textureLoadingContext = new TextureLoadingContext
			{
				Context = assetLoaderContext,
				Stream = File.OpenRead(finalPath),
				Texture = texture
			};
			Debug.Log($"Found texture at: {finalPath}");
			return textureLoadingContext;
		}
		throw new Exception($"Texture {texture.Filename} not found.");
	}
}

Read more about Mappers