Lightweight FBX Importer
Search Results for

    Basic Usage

    The Lightweight FBX Importer provides three methods for loading models. Each method supports both synchronous and asynchronous variations, tailored to different performance requirements:

    • Synchronous Loading: This approach is faster but may pause the main thread, which might cause issues on VR/AR platforms.
    • Asynchronous Loading: While potentially slower, this method minimizes disruptions to the main thread, ensuring smoother operation, especially in performance-sensitive environments.

    Import Models with the Built-In File Picker

    To begin, ensure you have imported the "FBXImporterFileBrowser" folder from the Asset Store package.

    • Synchronous importing
    • Asynchronous importing

    Assign the following action to the event that triggers the file picker, allowing you to select the model you wish to load:

    // Set up the extension filter for FBX and OBJ files.
    var extensionFilter = new[]
    {
        new ExtensionFilter("FBX", "FBX"),
        new ExtensionFilter("OBJ", "OBJ")
    };
    
    // Open the file picker asynchronously with the specified filter.
    // The callback LoadModelFromFileInternal will be executed when the user selects a file.
    StandaloneFileBrowser.OpenFilePanelAsync(
        "Select an FBX or OBJ file", // Title of the dialog.
        "",                          // Default directory (empty means use default).
        extensionFilter,             // File types allowed.
        false,                       // Disable multi-selection.
        LoadModelFromFileInternal    // Method to handle the selected file.
    );
    

    Then, create the callback function that will be executed when the user selects a file:

    private void LoadModelFromFileInternal(IList<ItemWithStream> itemWithStream)
    {
        // Check if any files were selected and if the first one contains data.
        if (itemWithStream.Count == 0 || !itemWithStream[0].HasData)
        {
            // If no valid file, throw an exception.
            throw new Exception("File not valid");
        }
    
        // Create a standard material converter for use during import.
        var materialConverter = new StandardMaterialConverter();
    
        // Use the default load options provided by the importer.
        var loadOpts = Importer.DefaultLoadOpts;
    
        // Import the model from the stream of the first selected file.
        // The imported model will be added as a root GameObject in the scene.
        var rootGameObject = Importer.ImportFromStream(
            itemWithStream[0].OpenStream(),  // Open a stream from the selected file.
            loadOpts,                        // Importer options.
            default,                         // Default bakeOpts.
            materialConverter,               // Material converter to apply.
            OnError,                         // Method to handle errors in case import fails.
            itemWithStream[0].Name           // Model filename.
        );
     }
    

    Finally, create the OnError method that will be invoked if a loading error occurs:

     private void OnError(Exception exception)
     {
        // Rethrow the exception to propagate it upwards.
        // You could replace this with custom error handling or logging if needed.
        throw exception;
     }
    

    Assign the following action to the event that triggers the file picker, allowing you to select the model you wish to load:

    // Set up the extension filter for FBX and OBJ files.
    var extensionFilter = new[]
    {
        new ExtensionFilter("FBX", "FBX"),
        new ExtensionFilter("OBJ", "OBJ")
    };
    
    // Open the file picker asynchronously with the specified filter.
    // The callback LoadModelFromFileInternal will be executed when the user selects a file.
    StandaloneFileBrowser.OpenFilePanelAsync(
        "Select an FBX or OBJ file", // Title of the dialog.
        "",                          // Default directory (empty means use default).
        extensionFilter,             // File types allowed.
        false,                       // Disable multi-selection.
        LoadModelFromFileInternal    // Method to handle the selected file.
    );
    

    Then, create the callback function that will be executed when the user selects a file:

    private void LoadModelFromFileInternal(IList<ItemWithStream> itemWithStream)
    {
        // Start coroutine to perform asynchronous loading.
        // The CatchExceptions extension method is located in FBXImporter.Extensions.CoroutineExtensions and allows you to handle exceptions that occur within coroutines.
        StartCoroutine(LoadModelFromFileCoroutine(itemWithStream).CatchExceptions(OnError));
    }
    

    Next, create the coroutine method to load the model:

    private IEnumerator LoadModelFromFileCoroutine(IList<ItemWithStream> itemWithStream)
    {
        // Check if any files were selected and if the first one contains data.
        if (itemWithStream.Count == 0 || !itemWithStream[0].HasData)
        {
            // If no valid file, throw an exception.
            throw new Exception("File not valid");
        }
    
        // Initialize material converter and loading options.
        var materialConverter = new StandardMaterialConverter();
        var loadOpts = Importer.DefaultLoadOpts;
    
        // Prepare result container for import process.
        var importResult = new Importer.ImportResult();
    
        // Start asynchronous import process.
        var enumerator = Importer.ImportFromStreamAsync(
            importResult,                   // The container to hold the import result.
            itemWithStream[0].OpenStream(), // Open a stream from the selected file.
            loadOpts,                       // Importer options.
            default,                        // Default bakeOpts.
            materialConverter,              // Material converter to apply.
            itemWithStream[0].Name          // Model filename.
        );
    
        // Loop through asynchronous loading steps
        while (enumerator.MoveNext())
        {
            // importResult.LoadingPercentage contains the loading percentage, which you can use to update a loading bar, for example.
    
            // Yield control to allow Unity to continue rendering/updating.
            yield return enumerator.Current;
        }
    
        // Retrieve root GameObject of the loaded model.
        var rootGameObject = importResult.GameObject;
    }
    

    Finally, create the OnError method:

     private void OnError(Exception exception)
     {
        // Rethrow the exception to propagate it upwards.
        // You could replace this with custom error handling or logging if needed.
        throw exception;
     }
    

    Import Models from the File System

    • Synchronous importing
    • Asynchronous importing

    To initiate model loading, assign the following action to the event responsible for loading the model:

    // Instantiate the material converter to use during import.
    var materialConverter = new StandardMaterialConverter();
    
    // Use the default import options provided by the importer.
    var loadOpts = Importer.DefaultLoadOpts;
    
    // Import the model file into the scene, handling any errors with OnError.
    var rootGameObject = Importer.ImportFromFile(
        "c:/users/test/desktop/mymodel.fbx",    // Provide your filename here.
        loadOpts,                               // Importer options.
        default,                                // default bakeOpts.
        materialConverter,                      // Material converter to apply.
        OnError                                 // Method to handle errors in case import fails.
    );
    

    Finally, create the OnError method that will be invoked if a loading error occurs:

     private void OnError(Exception exception)
     {
        // Rethrow the exception to propagate it upwards.
        // You could replace this with custom error handling or logging if needed.
        throw exception;
     }
    

    To initiate model loading, assign the following action to the event responsible for loading the model:

    // Start coroutine to perform asynchronous loading.
    // The CatchExceptions extension method is located in FBXImporter.Extensions.CoroutineExtensions and allows you to handle exceptions that occur within coroutines.
    StartCoroutine(LoadModelFromFileCoroutine().CatchExceptions(OnError));
    

    Next, create the coroutine method to load the model:

     private IEnumerator LoadModelFromFileCoroutine()
     {
        // Initialize the material converter to be used during the import.
        var materialConverter = new StandardMaterialConverter();
    
        // Use default import options provided by the Importer.
        var loadOpts = Importer.DefaultLoadOpts;
    
        // Prepare result container for import process.
        var importResult = new Importer.ImportResult();
    
        // Start the asynchronous import process, providing necessary parameters.
        var enumerator = Importer.ImportFromFileAsync(
            importResult,                           // The container to hold the import result.
            "c:/users/test/desktop/mymodel.fbx",    // Provide your filename here.
            loadOpts,                               // Importer options.
            default,                                // default bakeOpts.
            materialConverter,                      // Material converter to apply.
        );
    
        // Iterate through the enumerator to process the asynchronous steps.
        while (enumerator.MoveNext())
        {
            // importResult.LoadingPercentage contains the loading percentage, which you can use to update a loading bar, for example.
    
            // Yield to allow the next asynchronous step to proceed.
            yield return enumerator.Current;
        }
    
        // Retrieve the root GameObject resulting from the import.
        var rootGameObject = importResult.GameObject;
     }
    

    Finally, create the OnError method:

     private void OnError(Exception exception)
     {
        // Rethrow the exception to propagate it upwards.
        // You could replace this with custom error handling or logging if needed.
        throw exception;
     }
    

    Import Models from Custom Streams

    • Synchronous importing
    • Asynchronous importing

    To initiate model loading, assign the following action to the event responsible for loading the model:

    // Initialize the material converter to be used during the import.
    var materialConverter = new StandardMaterialConverter();
    
    // Use default importer load options.
    var loadOpts = Importer.DefaultLoadOpts;
    
    // Register the callback for handling external file requests.
    using var callback = loadOpts.set_open_file_cb(OnOpenFile, null);
    
    var rootGameObject = Importer.ImportFromStream(
        stream,                 // Pass the Stream containing your model data here.
        loadOpts,               // Importer options.
        default,                // Default bakeOpts.     
        materialConverter,      // Material converter to apply.
        OnError,                // Method to handle errors in case import fails.
        ObjFilename             // Model filename.
    );
    

    Then, create the method for resolving external files:

    private bool OnOpenFile(out Stream stream, string path, ufbx.ufbx_open_file_info info, object userdata)
    {
        // Use the path, info, and userdata parameters to resolve the custom file.
        // If the file is found, set the `Stream` output parameter to a Stream containing the external file data, and return `true`.
        // stream = new MemoryStream(Encoding.UTF8.GetBytes(MtlData));
        // return true;
        // Otherwise, set the `Stream` output parameter to `null`, and return `false`
        stream = null;
        return false;
    }
    

    Finally, create the OnError method:

    private void OnError(Exception exception)
    {
        // Rethrow the exception to propagate it upwards.
        // You could replace this with custom error handling or logging if needed.
        throw exception;
    }
    

    To initiate model loading, assign the following action to the event responsible for loading the model:

    // Start coroutine to perform asynchronous loading.
    // The CatchExceptions extension method is located in FBXImporter.Extensions.CoroutineExtensions and allows you to handle exceptions that occur within coroutines.
    StartCoroutine(LoadModelFromStreamCoroutine().CatchExceptions(OnError));
    

    Next, create the coroutine method to load the model:

    private IEnumerator LoadModelFromStreamCoroutine()
    {
        // Initialize the material converter to be used during the import.
        var materialConverter = new StandardMaterialConverter();
    
        // Use default importer load options.
        var loadOpts = Importer.DefaultLoadOpts;
    
        // Register the callback for handling external file requests.
        using var callback = loadOpts.set_open_file_cb(OnOpenFile, null);
    
        // Prepare result container for import process.
        var importResult = new Importer.ImportResult();
    
        // Begin asynchronous import of the model from the memory stream.
        var enumerator = Importer.ImportFromStreamAsync(
            importResult,                      // The container to hold the import result.
            stream,                            // Pass the Stream containing your model data here.
            loadOpts,                          // Importer options.
            default,                           // Default bakeOpts.
            materialConverter,                 // Material converter to apply.
            ObjFilename                        // Model filename.
        );
    
        // Continuously process the import steps.
        while (enumerator.MoveNext())
        {
         // importResult.LoadingPercentage contains the loading percentage, which you can use to update a loading bar, for example.
    
         // Yield control to allow other operations and avoid blocking the main thread.
         yield return enumerator.Current;
        }
    
        // Retrieve the root GameObject generated by the importer.
        var rootGameObject = importResult.GameObject;
    }
    

    Next, create the method that will be used to resolve external files the stream model might reference to:

    private bool OnOpenFile(out Stream stream, string path, ufbx.ufbx_open_file_info info, object userdata)
    {
        // Use the path, info, and userdata parameters to resolve the custom file.
        // If the file is found, set the `Stream` output parameter to a Stream containing the external file data, and return `true`.
        // stream = new MemoryStream(Encoding.UTF8.GetBytes(MtlData));
        // return true;
        // Otherwise, set the `Stream` output parameter to `null`, and return `false`
        stream = null;
        return false;
    }
    

    Finally, create the OnError method that will be invoked if a loading error occurs:

    private void OnError(Exception exception)
    {
        // Rethrow the exception to propagate it upwards.
        // You could replace this with custom error handling or logging if needed.
        throw exception;
    }
    
    In this article
    Back to top Generated by DocFX