Game Development

Blog 650: (Inter)Face Cream

So I had this grand plan to use 3D objects in my game’s UI. I wanted to escape all the woes of having to create icons, and recreate them every time I fiddled with a design.

Like most of my dreams of course, it was never going to work.

Inter-Face Cream

It didn’t really pan out because of a few annoying practicalities.

  • The actual UI and the 3D objects didn’t truly coexist; the UI and its parts had to be placed in the actual level.
  • I couldn’t work out how to cut geometry that exceeded the icon area.
  • The 3D objects fir the UI refused to be lit by the right lights, they kept getting illuminated by the level lights or nothing at all.

So I had to admit defeat and start again from scratch.

You can't see the current weapon icon in-game through the magic of layers, but it's THERE.
You can’t see the current weapon icon in-game through the magic of layers, but it’s THERE.

So, resigning myself to using flat, 2D icons that would at least properly inhabit the UI (and unlock all the flexibility that a self-contained UI brings), I had to attack all of my problems from a new angle.

Harking back to my work in Warcraft III, icon generation was one of the most annoying parts of modding. First, you have to pose the object in the editor, then you have to make sure the lighting is right, then you have to time your screenshot so it’s not playing one of its rare idle animation at the wrong moment.

It would be bad enough if that was the whole process; there’s far too much inconsistency already baked into that. But no, that leaves you with a desktop-sized image, which must then be cropped and resized… and then you have to apply standard icon borders — AT LEAST TWICE (normal icon, disabled icon; then possibly passive and disabled passive too). Finally, import each of the variations to the correct (different) paths. Sigh.

Look at them, they're attempting to be at the same angle as each other *but are all slightly off*. Eurgh!
Look at them, they’re attempting to be at the same angle as each other *but are all slightly off*. Eurgh!

The solution is, as with most annoying processes in life, automation. What if I could get Unity to take screenshots in a perfectly controlled environment, then crop them and put them in the right folders by itself? If I changed a model, all I’d need to do would be to run the generator again.

Unity couldn’t make life easy on me, of course. Taking screenshots is easy enough (Application.TakeScreenshot will do the trick), but taking screenshots with transparent backgrounds is quite a lot harder. After trawling various old forum threads for answers, none of them quite worked — I had to cobble this monstrosity together from a slew of similar-but-not-quite implementation examples before I got my working answer…

// Ensure any background guff that was previously rendered is cleared.
Camera.clearFlags = CameraClearFlags.Color;
Camera.backgroundColor = Color.clear;

RenderTexture icon = new RenderTexture(Width, Height, 32);
RenderTexture currentRT = RenderTexture.active;
RenderTexture.active = icon;

GameObject target = RDZ.Factories.ItemFactory.SpawnItem(PrefabsToScreenshot[ScreenshotItemIndex], Side.Right, transform);

Camera.targetTexture = icon;
Camera.Render();
Camera.targetTexture = null;

Texture2D screenShot = new Texture2D(Width, Height, TextureFormat.ARGB32, false);
screenShot.ReadPixels(new Rect(0, 0, Width, Height), 0, 0);
screenShot.Apply();

RenderTexture.active = currentRT;
Destroy(icon);

byte[] bytes = screenShot.EncodeToPNG();
String fileName = ResourcesDirectory + target.GetComponent<EquipmentItem>().IconPath + ".png";
File.WriteAllBytes(fileName, bytes);

Destroy(target);

I’ll be honest with you; I haven’t the faintest idea how it works, why it works, or even what it’s doing. It’s something along the lines of hijacking the game camera, forcing it to draw what’s in front of it onto something else instead of the screen, and then… copying that into a texture?

Ach, I don’t really care — the important thing is that it does work. I press Play on my IconScreenshotter scene and it spits out all my icons, straight into the correct paths for each item in the list. Job done!

You can't tell the difference from the previous version that used the *actual* 3D model because it's rendered in exactly the same way.
You can’t tell the difference from the previous version that used the *actual* 3D model because it’s rendered in exactly the same way.

Then all I had to do was unwind all the awful gubbins I was doing to create and destroy the icon objects, and replace it with a single image object that is updated as necessary. Success!

You can't even tell the difference, can you? (Except that empty bit to the right where I'm in the middle of building up the ammunition system.)
You can’t even tell the difference, can you? (Except that empty bit to the right where I’m in the middle of building up the ammunition system.)

2 thoughts on “Blog 650: (Inter)Face Cream”

    1. I did find a few threads suggesting things like that, but I don’t know anything about shaders so I’m not really comfortable messing with them. Thanks though! 😀

      Like

And you tell me...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.