Asset Bundle and Mesh Missing Tangents

I just tracked down a problem in a game we are making, that turned out to be caused by a mesh loaded from an asset bundle not having any tangents.

The symptom was that, on some devices (Nexus 6 and iPad Mini 1st gen, as examples), a mesh was not rendering properly - the lighting was wrong, and the mesh just looked bad. Upon some investigation, we discovered that the problem would go away if we did not load the mesh from an asset bundle, and had the mesh built directly into the build. This, however, was not a valid solution, as the build was already close to the 100MB IPA limit. Upon further investigation, I discovered that the mesh did not have any tangents loaded, but only when built into the asset bundle. The lack of tangents was visible in editor (which did not have the rendering problem), as well as on the problematic devices. I confirmed this both by checking the Mesh.tangents array size, as well as hacking the shader to output the tangents as the color, whereby they were completely black when loaded from an asset bundle, but seemed reasonable when loaded straight from the main package. The fbx in both cases is identical, as well as the import settings, where Tangents is set to Calculate.

I was able to work around the problem by adding code to calculate tangents on the meshes loaded from asset bundles, however this is less than ideal as it requires the meshes to be set to “Read/Write Enabled”, as well as just requiring extra load time.

The question then is: Is this a known problem in Unity 4.6? Is there something wrong with the way we are building or loading the asset bundles. Is there a better way to work around the problem?

For building the asset bundle, we are using BuildPipeline.BuildAssetBundle with a potentially different asset as the main asset (this bundle has a few meshes in it, two of which have the problem), and the mesh’s FBX is in the assets list. We are using the options: CollectDependencies | DeterministicAssetBundle. I have also tried adding CompleteAssets to that list, however it had no effect. The download of the asset bundle is occurring with WWW.LoadFromCacheOrDownload, and the load then uses AssetBundle.LoadAll().

We have are using Unity 4.6.8f1 and 4.6.7f1 for Android, and 4.6.8p3 (the version distributed on the forums) for iOS.

I’m not sure if it’s impacting the asset bundles but maybe the optimize mesh option in the playersettings could lead to this behavior.
If unity do not sees for whatever reason that the tangents are used, it will try to strip them out to save some file and memory size.

Ensure that Unity isn’t stripping your meshes of tangent data. We had this issue and setting StripUnusedMeshComponents to 0 fixed it for us. You can either write a script to set it or go into PlayerSettings.asset and change it in your text editor.