Up to last week, when I had to write a custom 3D format plugin for Unity I used the classic AssetPostprocessor. Having a look at the Unity API, I stumbled upon the ScriptedImporter API.
Now that real-time 3D (digital twin, training, AR, VR, desktop apps, ...) are used by classic industries and corporate companies, it's important to have a very efficient 3D pipeline.
This pipeline must be kept as short as possible to avoid several time and budget consuming 3D file formats manual conversions and interoperability tasks.
Writing a generic way to quickly support a new file format is, in that context, very important.
Please note that the ScriptedImporter API is indicated as experimental by Unity and may be removed or modified in the future. Let's be pretty confident that it is there to stay.
While writing such importer was working with the AssetPostprocessor class, some tasks, like creating a prefab from the loaded data, link the Prefab to the actual custom format asset, asset update on file format custom import inspector changes, were not very straightforward.
Once again Unity blows my mind creating a simple, very lean and relevant API.
Here is the current version of the ScriptedImporter I use, which is pretty simple compared to how things were done before this API:
[ScriptedImporter(1, "ifc")]
public class IFCScriptedImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
IFC3DModelUnityImporter ifcimporter = new IFC3DModelUnityImporter();
GameObject importeddataroot = ifcimporter.ConvertToUnity(ctx.assetPath);
if (importeddataroot != null)
{
ctx.AddObjectToAsset(Path.GetFileName(ctx.assetPath), importeddataroot);
ctx.SetMainObject(importeddataroot);
}
}
}
So I decided to write a more generic "framework" to write custom 3D file format plugin for Unity, especially in the case that the 3D file format API is a C++ API.
This article describes the main architecture of this work and the key tricks and APIs I generally use to make this (PInvoke, Native code callbacks, ...).
Testing the framework, I used the famous AEC IFC file format read by the IFCOpenshell C++ SDK.