Loading Raw 3D Models in Runtime

By Myonmyon

This was a strange thing to tackle…

TL;DR: Attempt to import FBX is going to be a pure fantasy. OBJ, okay, but lacking advanced features. Your best pal would be GLB.

Now, explanations.

.glb/.gltf is a rather new format (compared to old fossil like obj), that is designed to be “the jpeg for 3D models”. And indeed it is. It is lightweight, can have material/texture/animation info, and even lights and cameras (if… that matter). I would recommend conduct some further reading on this format.

But why are there 2 extensions? Well, .gltf isn’t a standalone file, it consists of a gltf file in json format, and a data file in binary format. .glb however, packs everything in one file (b for binary). And of course we would be interested in .glb due to its portability. gltf can come in handy if you really want to debug your model for some reason.

Now, how does Unity work with gltf/glb?

It is officially supported by Unity via the glTFast package (link). It isn’t well-known since 1. it isn’t in package manager and 2. gltf is a format for presentation, not really for editing.

I tested runtime import of glb files and to my surprise, not only it works, it also creates correct materials and animations… which isn’t possible with obj.

And most software support gltf/glb. Blender, for example, does it perfectly. And I tested Houdini by snatching a friend’s computer. It can handle it partially, but if you try to animate an attribute that you created yourself… it will not work, Unity complains about blend shape weights. But if you simply import the glb in Blender and do nothing, export it, it will actually make Unity happy. The downside is that the glb would grow about 3 times in size; I suppose something hacky done by Houdini is reverted to a simpler state by Blender upon import.

Something about Animations

When you have animations in glb files, import it in the editor creates animations, and loading the asset creates a model instance with Animator. However, this is not the case when you import a model in runtime. There are two reasons: 1. the glTFast package defaults legacy animation system. and 2. You can’t create animator controller in runtime.

I actually tried to force glTFast using Mechanim import instead of legacy, but it doesn’t solve the animator controller problem, as there’s no information in glb files to author the creation of animator controller.

My final solution is to overthrow the animator controller and rewrite it using the Playables API. And I had to use a manual update to control the playable graph because imported animations are one-shot, so I had to manually control the “elapsed time” of an animation. But this topic is vast, and hopefully I can cover it in another post.

Share: X (Twitter) Facebook LinkedIn