Unity3D 4 Pet Peeves

I’ve been updating my older apps to use the newly released Unity3D 4 engine, as well as starting an entirely new project. I haven’t used many of Unity3D 4’s new features yet, but I figured this is as good a time as any to list a few of my pet peeves with Unity3D 4 as I did with Unity3D 3 a few years back.

It’s time Unity3D had a package manager.

Unity3D plug-ins and assets purchased from the Asset Store are invaluable. It’s becoming the most important feature that makes Unity3D the superior choice. However, managing projects with multiple plug-ins is can be a nightmare. A lot of this is how Unity3D handles file deletions.

If you click the “update” button to overwrite an existing plug-in with the latest version from the Asset Store, it may wreak havoc upon your entire project. Unity3D’s file hashing system will sometimes fail to overwrite files with the same name, even if you are importing a newer one. You’ll end up with a mess of old and new plug-in files causing chaos and mayhem. The only way to prevent this is to manually find delete all the old plug-in files before updating with the latest version.

Not to mention the fact that native plug-ins either require you to manually setup your own XCode project with external libraries or have their own proprietary scripts that edit your XCode project. Unity3D should provide an API and package manager that lets plug-ins forcibly delete and update their own files as well as modify settings in the XCode project Unity3D generates.

Let me import files with arbitrary extensions.

A minor annoyance is how Unity3D will only accept files with specific extensions in your project. If you want a custom binary data file you HAVE to give it the txt extension. It’s the only way you can drag the file in to the project. Unity3D should allow you to import files with any extension you want, but provide a method in the AssetPostprocessor API to be called when an unknown file extension is detected.

Where’s the GUI?

Come on now. It’s 2013. The new GUI has been “coming soon” for years. Unity hired the NGUI guy, which leads me to believe the mythical Unity3D 4 GUI is merely the stuff of legends and fantasies. I like NGUI but I’m really looking forward to an official solution from Unity. Although I’m not looking forward to re-writing all my GUIs once it arrives. Let’s just get it over with. Bring it on.

Monodevelop sucks.

My god. Monodevelop sucks. Lots of people use other text editors for code, but you still can’t avoid touching Monodevelop when it comes to debugging on OSX. I’m sure it can be whipped into shape with a minor overhaul, but it’s been awful for so long perhaps this is unlikely. Aside from the crashes and interface weirdness, how much human productivity has been destroyed waiting for Monodevelop to reload the solution every time so much as a single file has been moved to a different folder?

Is it time to update Mono?

While we’re at it, Mono recently updated to C# 5.0. I’m not sure if this is a big performance drag or not, but I’d love to see Unity3D’s Mono implementation updated to the latest. There are some C# 5.0 features I’ve been dying to use in Unity3D.

Tough Love

Don’t take it personally, Unity3D is still my engine of choice. This list of annoyances is pretty minor compared to previous ones. Every year, Unity gives me fewer and fewer things to whine about. It seems competing solutions are having trouble keeping up.

How To Prevent Performance Spikes in Unity3D When a Model is First Visible

In my latest Unity3D app I dynamically load assets from the Resources folder and place them in the world after the initial scene load. These assets use new materials and textures that must be uploaded to the GPU. I thought I was being slick by caching prefabs to prevent a loading hiccup when I needed to instantiate. However, that’s only part of the problem. After placing the object in the scene, my game would freeze up for a frame or two when the newly created object first became visible. The profiler showed this spike attributed to a function called AwakeFromLoad.

It turns out Unity3D does not load the GPU with your new object’s assets until it’s first visible. Apparently, this is what AwakeFromLoad does. This is an optimization technique presumably to prevent thrashing on the GPU by loaded assets that won’t be visible immediately. The downside is you’ll see a pause as Unity3D uploads data to the GPU. From what I can tell, this can even mean compiling the shader if it hasn’t been used in the scene yet.

Unity doesn’t provide a function to force the GPU to load assets. From looking at Unity forum threads, the most common solution is to put up a loading screen and show newly instantiated assets to the main camera for a frame to force a GPU load. Once all the assets have been made visible, the loading screen is dropped.

Putting up a loading screen just seemed like a huge pain in the ass, not to mention an ugly hack. So, I came up with a solution using Unity Pro’s RenderTexture and a second camera. Now, my game scene has two cameras: the Main Camera and a disabled secondary camera with a tiny 32×32 RenderTexture as its target. Whenever I instantiate a new asset in the world, I position the second camera in front of it and render a frame to this texture. This forced rendering does the trick of uploading all necessary data to the GPU. Yes, there still is a loading spike, but you decide when it’s going to happen and you don’t have to reposition your object in view of the main camera for a frame.

I put this in a behavior called AssetGPULoader, you can grab it here. It only works with Unity3D Pro as it needs RenderTexture. As far as I can tell, this does the trick. It has removed my unpredictable performance spikes. For an alternative solution, I also found this technique in the Unity forums.