Posts Tagged ‘Programming’

In a previous post I talked about a few stumbling blocks to supporting the three different iOS aspect ratios. To review:

iPad, iPhone4, and iPhone5 have different aspect ratios, and the iPad3 and newer have whopping big retina displays. This issue has some simple side-effects, like needing different splash-screen images. Not a big deal. More complex is how to handle this in-game. Do you have different sets of texures for each aspect ratio and maybe different textures for the iPad3 and 4?  That’s tricky if you want to have a “Universal” app; one that can be loaded on any type of i-device, and still fit within that 50 Mbyte OTA download limit. One solution is not to care about the download limit. I didnt’ like that one. Or one could have two different versions of your app. That’s a potential QA problem and Apple (anecdotally) seems to like it better if you make Universal apps.

If you look around on the Unity3D iOS forum there are many many posts about how to handle this, and to be fair, many have to do with true 3D games and I was only concerned with Numberheads, my 2D puzzle game. So I don’t assert any sort of universal solution, sorry.

One way to lay out a 2D game is to have an Orthographic camera, a background image,  and then to layer the other game elements (sprites, control buttons etc.) on top of that background layer. The background layer has no transparency, and the whole scene is often unlit so as to improve performance on mobile platforms. But how to reconcile these three different screen sizes:

  • iPad3 (and newer) 2048 px X 1536 px
  • iPhone4 (and similar sized iPod Touches) 960 px X 640 px
  • iPhone5 1136 px X 640 px

It actually turns out that you can use the nature of the Ortho camera and automatic scaling(note 1) to solve the problem rather simply. Simply use a 1 pixel = 1 game unit sizing scheme for all of your game assets, size the background texture for the iPad3 screen size and then adjust the camera’s ortho size as appropriate. Here is an image that can help understand this:

NHBG_website

This image (you can click on it to enlarge) is a screenshot taken right from Adobe Illustrator. Note that the HEIGHT of the image is 2750 pixels and the width is 1536 pixels. Huh?   That doesn’t make a heck of a lot of sense at first look; doesn’t seem right.  But, if you position the camera “above” the exact center of the image  and pointing directly at it you can then adjust the camera for the different devices. The key is to keep your game elements inside the lines “iPad Top” and “iPad bottom”. The other devices (i.e., not iPads) will have some empty space, that is, the background (whatever you choose to show).

It’s easy to programmatically determine which device you’re on using the iPhoneGeneration enumeration. For iPad-type aspect ratios set the camera’s “Orthographic Size” parameter to 1024, for iPhone4-type aspect ratios set the size to 1160, and for iPhone5-type aspect ratios set the size to 1374. Note that you have to be sure to choose the correct size for iPod Touch devices as well, those are like one or the other iPhone, and note that (as of this writing) all the iPads have the same aspect ratio.

While this may sound a bit confusing, it works because the camera’s presentation is scaled to the physical screen size. Recall that the “Orthographic Size” parameter is “half of the vertical size of the viewing volume” (from the scripting reference). So if it’s set to 1024 for iPad then the vertical size is 2048 which maps 1:1 to the iPad3 screen pixel height in Portrait mode. But on an iPad2 or other 1024×768 devices, this 2048 x 1536 presentation is scaled to fit in that size.

Minor con – you need a huge background texture. But in actuality, if you compress the source image down to a square texture and display that texture on a cube with the Transform scaled to 1536 x 2745 x 1 you’ll have a “pixel perfect” display. That’ll  look great even on the large Retina displays. Be sure to use the “best” RGB (not RGBA) Compressed PVRTC 4-bits compression and the texture will only be 2 mBytes. That’s a lot less space than if you needed three images, one for each aspect ratio.

This actually works in Landscape or Portrait orientations, has been tested on devices, and is in a shipping product on the App Store. Hopefully some Unity developers will find this information useful.

Note 1: The mechanism by which the scaling occurs is way beyond the scope of this post but can be seen by examining a built project’s “Classes/Unity” folder from within Xcode. Clearly I can’t post any of that without violating the Unity3D license agreement.

 

You say you’re a smart dev using Unity3D Pro and you’re trying to make it to the under-50 megabyte OTA cap on iOS and ya just need a little more weight reduction?  Here’s a quick tip: use small, uncompressed png files for your unused splash images.

splashesNotice that since this App is portrait-mode only, there are three potential unused splash screen images. Well, if you look at your Xcode project or an archived build you’ll see that there are some PNG files there for these unused orientations. They’re just the Unity3D logo, but there are several – for normal and retina resolutions.

  • Default-Portrait.png is 59 Kb, Default-Portrait@2x.png is 195 Kb, Default.png is 65 Kb, Default@2x.png is 204 Kb, and so on. If you’re not using them why waste the space? Just add a very small (say 64×64) black texture to your assets folder and use that instead of leaving the Unity inspector setting as “none”.

For example, “Default-Landscape@2x.png” (corresponding to “High Res iPad Landscape” in the image shown here)  is a 64×64 black texture and is just 9 Kb.  Now of course Apple uses its wierd PNG compression and will reduce these file sizes a bit more but you will still save space – try archiving before and after and you’ll always save something.

Why waste the space – save bytes, and take comfort in the fact that when you sell 10 million copies of your masterpiece the energy save by not transmitting these spurious bytes you’ll save people money on their data plans and save enough energy to light a 20 W LED bulb for 29 seconds!

Notes: You need Unity Pro to change the splash screen images in the first place. If you use a compressed texture you’ll get a warning every time you build.