I recently ported a large and very well-tested game from Unity 4.2.2 to Unity 4.3. Although 4.3 is very new, the rendering engine in 4.2.2 contains a number of serious bugs for mobiles and the fixes to those rendering issues are only available in 4.3, so my options are limited. Since I know other Unity developers are considering upgrading to 4.3, I wanted to document my experiences bringing a complex 3D Action RPG called The Shadow Sun into Unity 4.3.
Mouse Scroll Wheel
After upgrading from Unity 4.2.2 to Unity 4.3, one of the first problems that I encountered was that my trusty Apple Mighty Mouse no longer worked correctly in MonoDevelop. In particular, the mouse scroll wheel did not work in the code editor. This seems to be a defect in the version of MonoDevelop (4.0.1) that ships with Unity 4.3. The problem only affects certain types of mice and is perhaps fixed in MonoDevelop version 4.0.3 which doesn’t help me very much. I suppose simplest workaround is to purchase a new mouse?
FPS Reduction
In a small number of the scenes in my game, Unity 4.3 reduced the rendering speed from around 60 FPS to around 30 FPS. In most scenes, the frame rate is unchanged from Unity 4.2.2. I have not located the root cause other than that CreateVBO is slower in 4.3 but only along certain sight lines in certain scenes.
Meta Files
With 4.3, Unity now requires that all projects use meta files. So if you haven’t been using Unity’s built-in version control, you might be surprised to see your source directories littered with hundreds of mysterious meta files.
Invisible Player Character
After upgrading to Unity 4.3, sometimes my player character would disappear temporarily when walking around in certain levels containing fog. Although I think this problem has been around for years, the behaviour is certainly different between Unity 4.2.2 and Unity 4.3. I would have noticed my player character vanishing in 4.2.2! After many hours of debugging, I traced the problem to the way that Unity compiles GLSL shaders at run-time. While running your game, look in the Xcode console for a strange error:
-------- GLSL error: ERROR: 0:81: Use of undeclared identifier '_patchFragColor'
The error is strange because none of my shaders use anything called _patchFragColor! My best guess is that Unity secretly modifies our GLSL shaders to handle fog automatically. However, if your GLSL shader includes a conditional structure which references gl_FragColor in multiple branches, Unity breaks the shader by inserting a _patchFragColor variable definition in the wrong spot. Take a look where Unity placed the definition of _patchFragColor:
*
#ifdef VERTEXLIGHT_ON
* * *#ifdef PIXEL_POINT_LIGHTING
* * * lowp vec4 nonRampLighting = NonRampLighting(vectorsTo4Lights_tangent, normal, intensitiesFor4Lights);
* * *lowp vec4 _patchFragColor;
#endif
* * *_patchFragColor = mainTex * nonRampLighting + rimAndSpecular;
* _patchFragColor = _patchFragColor * _unity_FogVar +_unity_FogColorPreMul; gl_FragColor = _patchFragColor;
* * #else
* * *_patchFragColor = mainTex * _Color + rimAndSpecular;
* * #endif
The simplest work-around is to only reference gl_FragColor outside of a conditional. I think Unity’s parser is blindly scanning for the first mention of gl_FragColor and simply inserting the _patchFragColor variable definition immediately above that line. It’s a little spooky.
Vanishing Tiles While Moving
After upgrading to Unity 4.3, tiles directly in front of the camera randomly vanished while walking around. I solved this occlusion problem by decreasing Unity’s “smallest occluder size” from the default 5 to 1. In one particularly troublesome scene, I had to use 0.75. The disadvantage of this solution is that the size of the occlusion data stored in memory increases. Because of this, the occlusion data in my game now consumes more memory than earlier versions of Unity. For example, one of my scenes now requires 1.5M of occlusion data in 4.3 when it used less than 500K of occlusion data in Unity 4.2.2.
Vanishing Tiles During Camera Pan
When compared to previous Unity releases, the 4.3 occlusion culler is more sensitive to the camera sliding into walls. In our game, if the player is facing a wall and spins the camera around in a complete circle, the camera must pass between the player’s body and the wall. Sometimes the camera moved through the wall a tiny bit. At this point, Unity’s new culler blanks everything out. The fix was to adjust the minimum camera distance by a small amount so that the camera does not slide too far into the walls.
Vanishing Tiles In Hidden Rooms
In my game, clever players can spot several secret rooms hidden behind the crumbling sewer walls. In Unity 4.3, most of the geometry within these secret rooms is culled even when the camera is inside the secret room. No amount of fiddling with the occlusion settings helped. There are no non-static doors leading into these rooms so my assumption is that Unity’s new culler doesn’t expect the player to ever get inside these areas since there is no walkable path. I also saw the same problem in scenes which had several different “sections” which were not physically connected. The best work-around was to carve artificial non-static “doors” leading into the secret areas. This reduces the effectiveness of the culler, but at least it works. Note that this was not an issue with Unity 4.2.2’s culler.
Incorrect Occlusion Data
According to the documentation, the StaticOcclusionCulling.umbraSize property is supposed to return the size of the baked occlusion data. This property always returns zero even after a scene is baked. I don’t know of a workaround, other than to not use this property.
Stale Occlusion Grids
If you bake a scene in the editor and then open another scene, you’ll still see the previous scene’s occlusion data super-imposed in blue over top of the new scene. Fortunately, this seems to be only a visual glitch.