I recently got into modeling in Blender and wanted to export them into Unity. Most written and video guides show how easy it is, but it ended up being much more complicated than I thought. So I'll summarize what I've learned after hours of trial and error and searching online. I am using Blender 3.1.0 Beta and Unity 2021.2.11f1, both for Apple Silicon.
It's easy, they say
First I'll start with a few quotes from Unity's marketing page about Blender. They start with an acknowledgement that Blender matters in game development:
Blender and Maya are two of the most powerful tools you’ll find, as they are industry leaders in art and animation software. [...] Blender has been a favorite for indie studios and small teams for more than a decade. That’s not surprising, as Blender is a free, open-source software that packs some serious power.
Then they explain how Unity can import Blender files without a hitch, unlike other software which can be unreliable they say:
Seamless importing into Unity: Having to convert third-party project files to be able to use them with other applications is time-consuming. It can also be unreliable, even with software products that promise compatibility. But natively importing project files from Blender and Maya is easy with Unity. To import Blender assets into Unity, click Assets > Import New Asset on the Unity menu bar, then find and open your .blend file.
And they reiterate one last time that you do not need to convert your files:
Using Blender or Maya with Unity is hassle-free: no complicated pipelines, no special installations or conversions.
After struggling so much to get it to work, I wish Unity had documented actual guides on how to do it properly and left a link in that marketing material.
Let's paint a cube
Let's create a model to export to Unity. I'll paint a cube to demonstrate each step of the process.
Create a texture to paint on
- Create a new file in Blender. It already comes with a cube in the scene. It also already has a Material applied to it, called simply "Material".
- Open the Shader Editor. It opens the shader for our Material by default.
- Add an Image Texture node.
- Link its Color output to the Base Color input of the Principled BSDF node.
- In the Image Texture node, click New to create a new texture.
- I named it "Painted Faces" and made it all back.
- Now in the 3D Viewport, switch to Viewport Shading to see the cube turned black.
Paint the cube
- Switch to Texture Paint mode.
- Paint the faces however you like.
Now comes trouble
Caveat 1: Blender does not save the texture when saving the .blend file
Save the .blend file, import into Unity
Now let's save the file. The .blend file ends up taking 800 KB.
Unity claims you can import Blend files directly into your asset. Let's do it. I drag the blend file into the Project window in Unity, and then drag that model into my scenegraph and get this:
Export to FBX
If Unity won't read the texture correctly from a blend file, let's export it to FBX.
- In Blender, go to File, Export, FBX.
- Change the Path mode to Copy.
- Click the Embed textures toggle.
- Click "Export FBX".
- I end up with a file called "painted cube.fbx". It is 30 KB big.
Now we can import it into Unity:
- Drag the file into the Project View.
- Now you can see the cube, but it's still not painted.
- If you expand the import, you can see it has the whole scene. It has the cube, the UV Map, a camera, a light and a material, but no texture.
- In the Inspector window, in the Materials tab, the "Extract Textures..." button is enabled.
- You can click it, and Unity will ask you where to extract the embedded textures.
- Pick a folder and hit Save.
- The cube is still unpainted, and no texture is actually saved in that folder.
Force saving the texture file
One reason why this did not work is because Blender didn't actually save the texture file anywhere. It's still stored only in memory.
In the Image Texture shader node, if you click Open, it'll open a file picker, but since the image was not saved anywhere, this file picker is of no use.
If you open the Image Editor, you'll see your texture. I can see my Painted Faces texture. However, notice the asterisk next to the menu item "Image*". It indicates that the image was not saved. Weird, since I did explicitly save my Blend file earlier, and it did indicate that it saved into "painted cube.blend".
Well it turned out it saved the blend file, but not the Painted Faces texture! When I try to quit Blender, only then does it tell me explicitly that the texture was not saved:
So I click Save, and Blender quits. I check my .blend file again, and this time it's 17.7 MB large. Quite a heavy for a 1024 by 1024 image...
But at least we're making some progress. Earlier Unity would have had no chance of getting the texture since Blender didn't actually include it in the .blend file, nor did it export it in the FBX file.
If I open the file in Blender again, I can see that in the Shader Editor, the icon in the Texture Image node has changed into a package icon. Hovering over it tells us that the texture is packed, and we can click the icon to unpack it. We'll discuss the significance of this later on.
In the Image Editor, the asterisk is gone as well.
Caveat 2: Unity doesn't import EXR images unless Blender unpacked them first.
Not sure who is at fault here, but both are guilty of not properly indicating what's going on.
EXR is an open HDR image file format. You can read more about it here, although that's really all you need to know.
Import the .blend file into Unity
Now that the .blend file actually includes the texture, let's import the .blend file into Unity again:
- I delete the previously imported models.
- I drag and drop the newer, larger .blend file into the Project window.
- Unity imports the cube, unpainted.
- Expand the import, and you'll see the cube and the unpainted, uncolored Material.
- If you check the Inspector window, you'll see that the "Extract Textures..." button is grayed out.
Export to FBX
Using the same steps as described earlier, I export the FBX file with embedded textures. This time the FBX file is 16.8 MB large, so it should be in there. Let's import it into Unity:
- In Unity, delete the old import.
- Drag the new FBX file into the Project window.
- The cube is imported, unpainted. The material too is unpainted.
- In the Inspector window, the "Extract Textures..." is enabled.
- Click "Extract Textures...".
- Choose where to save the textures. The project's Assets folder is preselected. I just pressed "Choose Folder".
- Unity briefly says it's importing.
- When it finishes, I can see no new file in the Assets folder, and the cube and material are still unpainted.
Fix: unpacking the textures
Since Unity won't extract nor read the EXR texture from .blend of FBX files automatically, we have to explicitly export the texture into a standalone file:
- In Blender, go to File, External Data, Unpack Resources. Alternatively, you can click the package icon in the Image Texture shader node in the Shader Editor.
- Pick where to save the EXR texture. By default it creates a subfolder called "textures" and saves it there.
- After unpacking, the icon reverts to an "Open Image" icon.
Now we can import the EXR texture into Unity:
- In Unity, drag the textures folder into the Project window.
- Click the texture and notice how Unity actually knows how to read EXR images.
Finally, let's import the model:
- Drag painted cube.blend. It still does not load correctly.
- The FBX with texture included we exported before unpacking does not either.
- The FBX with texture not included we exported before unpacking does not either.
Since it did not work, let's try exporting to FBX again, with and without textures included:
- File, Export, FBX. Set path mode to Copy. Click the Package icon to include the texture. Click Export FBX. This will create an FBX with the texture included. Again, the resulting file is 16.8 MB, just like the one we had exported before unpacking.
- File, Export, FBX. Set path mode to Auto. Click Export FBX. This will create an FBX without the texture included. The resulting FBX file is 30 KB, just like the one we had exported before unpacking.
Let's import the model:
- In Unity, I remove the previously imported texture and models, and drag the FBX with texture. Again, the cube gets imported unpainted, and the Extract Textures... is enabled.
- Click the Extract Textures...
- This time, Unity does manage to extract the EXR, and finally paints the cube!
Let's remove both and try again with the FBX without textures:
- Import the FBX without texture. Expectedly, the cube comes unpainted. Also "Extract Textures..." is disabled.
- Import the textures folder by dragging it into the Project window.
- Upon import, Unity correctly paints the cube automatically.
In the previous section, we covered how to import a textured Blender model into Unity. Now let's step it up a bit and cover the case of procedural textures. A procedural texture is a texture that is generated at render time. Procedural textures are great because they don't take space and they can scale to any resolution. The drawback is that those shaders work only in Blender. To export such a model for use in Unity, you have to render those into actual textures. This process is called Baking. Here's what the Blender doc says about Baking:
Cycles shaders and lighting can be baked to image textures. This has a few different purposes, most commonly: Baking textures like base color or normal maps for export to game engines.
For this I relied heavily on this awesome video which explains it better than I ever could.
Set up a cube painted with a procedural texture
- In a new file, open the Shader Editor and add a Voronoi Texture node.
- Link the output Color to the Base Color input of the Principled BSDF node.
- In the 3D Viewport, switch to Viewport Shading to see the painted cube.
Baking, ie Rendering into an image texture
Now we should bake the texture into an actual image.
- In the Shader Editor, add a Texture Image node.
- Click New to create a new image. I called it Voronoi. Notice how the Texture Image node has a white outline. It means it's the selected texture. This is where Blender will render the result into.
- Since you just created it, it is marked as the "selected texture". Notice the
- In the Render properties, select Cycles as the Render Engine.
- Scroll down to the Bake section. At this point you should read the docs to pick the render settings you want.
- Click Bake.
Once it finishes baking, Blender tells you it's saved internally and that we should either pack it or save it externally.
Indeed if we check in the Image Editor, the Voronoi image has been painted and there is the asterisk next to "Image*".
Let's try to pack it first.
When I go to File, External Data, Pack Resources, I get a warning message. It tells me I'll lose some of my changes if I do. That's probably not the right way to pack resources. So I'll do it like last time: quit Blender, and say Yes to saving the modified texture. Now the blend file is 17.7 MB.
Import the .blend file into Unity
I imported the blend file into Unity.
Just like earlier, Unity doesn't load the texture. The "Extract Textures..." button is disabled too.
Export the FBX with embedded texture
Again, this doesn't work. The FBX is only 26 KB.
Let's unpack the texture like last time. After unpacking the texture and saving the .blend file, it shrinks down to 860 KB while Voronoi.exr takes 16.8 MB.
I try loading the .blend file and textures into Unity. It doesn't work. I export to FBX with texture, but the output file is still only 26 KB. Clearly, it did not export the texture.
Relinking the material
The reason why it doesn't work is because you have to rewire the shader of the cube material. Instead of the procedural Voronoi Texture, you have to use the Voronoi image texture. Btw, instead of the Principled BSDF, I tried with a Diffuse node. This gives the exact same result within Blender, but this won't work when exporting to Unity. You have to use the Principled BSDF node.
Now I we're back to the first use case of a cube painted with a regular image texture. I can import the texture and the .blend file, and Unity paints it correctly.
I can also export the FBX embedded with the texture, import it into Unity, click "Extract Textures...", and it'll paint the cube correctly.
What if I pack the texture again?
Then Unity won't be able to import the texture from the .blend file. However, exporting the FBX with embedded texture, then clicking "Extract Textures..." in Unity works. This is truly confusing.
Here's how you can import Blender models into Unity.
For regular textured meshes:
- In Blender, after making sure that your textures are actually saved and packed (or unpacked), export the FBX with embedded textures (Path Mode set to Copy, and enable packaging the texture). In Unity, import the FBX. Then in the Inspector, click "Extract Textures...". You now have a textured mesh.
- If you don't want to have to click "Extract Textures...", you can export all the textures into separate image files. In Blender, unpack all textures (File, External Data, Unpack Resources). Now you can either load the blender file and textures folder directly in Unity. Or you can export the FBX with Path Mode set to Auto, ie without embedded textures. In Unity, import the textures folder and the FBX. It'll texture the meshes automatically.
For complicated shaders, you'll have to bake the result into regular image textures. Refer to the detailed steps in the previous section. Then you're back to the regular textured meshes case.
Last note, I've read that the direct import of .blend files into Unity requires Blender be installed on the machine. Also, you don't have much control over what gets exported. So I'd recommend using the FBX export so you can selectively export only the model you want, instead of the whole scene with lights for example.
Autodesk's FBX Viewer
While I was desperately trying to properly export FBX files, I came across Autodesk's FBX Viewer tool. Autodesk is the company which created the proprietary FBX format. They released a free viewer. You can find it here. But it failed to load the textures on any of my FBX files, even when they exported fine in Unity.
One possible way is to use SketchFab. It is a model marketplace and also has a collection of free models. According to this guide, users can upload their blend models to SketchFab. SketchFab will then convert it to another format, gITF. Finally the user can import the model to Unity with the SketchFab Unity plugin. I haven't tried it since it requires you to sign up. It also makes more sense to stay local since all my models are already on my machine.
Some of it is quite old:
- https://www.youtube.com/watch?v=qGRC2qnYo6A: Exporting with and without embedded textures. Their example worked well because the original texture was an external image, ie it was already unpacked.