Retina Display Detection

Hi,
There’s been a few threads about supporting retina and I was hoping to find out what the officially UT recommended way to detect higher resolution devices is?

Is it hardcoding screen size like this thread?

http://forum.unity3d.com/viewtopic.php?t=58673

EDIT:
I guess a more direct question: is there plans to add a generic function in the Screen or other classes in U3 that return the scale factor for the display?

E.g. return “contentScaleFactor” on iPhone or whatever equivalent on desktop or Android, etc.

EDIT 2:
Added wish list item here:
http://forum.unity3d.com/viewtopic.php?p=389201#389201

Or maybe add a scaleFactor member variable to the Resolution struct?

I guess you can turn the setting in the editor in player settings to “highest resolution” and then make your hud by device detection using, iPhoneGeneration.iPhone4

Thanks for your post.

That’s not really portable workable if new devices are released and they run my game is it?

There are now new iPods and after my game is released if I’m checking for iPhone4, it means it might show low res art on iPhone 5 when it comes out. Or if I check for >= iPhone4 then they might release a standard res iPhone and again content won’t look right.

You can always do, if (Screen.width == 640) … assuming your running at 640x960

Right. But that’s still tied to specific hardware. If they released a square screen device or even moved to hi res 1024 x 768 displays, etc. that all breaks and then it falls back to low res art because it has such a specific pass/fail case.

I’ve gone for if (Screen.width > 500) as anything new over that will want the high-resolution graphics.

What about iPad? Different image aspect…

The original poster only appeared to be concerned with using high-resolution graphics at the right time.

It could be a similar case to my current game which is portrait, and on the iPad it just shows a bit more of the 3D scene to either side. Not a problem.

If the concern is also about aspect ratios, then Screen.width / Screen.height tests can also be used.

I made a system where before each scene, I have a “texture switcher scene”. It checks to see if the screen height is above 320, and if it is, it adds other textures to an array of materials (at 2x the size). I also set the texture tiling x and y to 2.
This is for a 2D game that was made without retina and iPad in mind, I had to hack it in afterwards. But with this system, all my world-coordinates, sprite atlas coordinates, orthographic camera size etc can stay the same, which is nice.
I only had to do a little bit of modifications to my input detection code, and if the screen ratio is different (on iPad) I move some GUI stuff around (just calculate their new position based on their current position and the difference in screen ratio) and some other small changes.

There’s sort of two things at work here though. Just because the screen is say higher than 320 in height or even 768 doesn’t mean I always want higher resolution textures.

I need in Unity to be able to help me manage logical units and pixel units separately. Just screen size isn’t enough, I need to make some other tests to decide what to do.

For example, I might have a button for help that’s 64 x 64 on both an iPad and lower res iPhone sitting in the corner of the screen. On Retina displays, I’d like that button to be 128 x 128 though so it looks the same size but is higher resolution.

So in this case the higher resolution image is used for a screen that is in-between two other screen sizes in pixel terms. Currently the only way to distinguish is to do an actual screen size check, not a >= check because it would fail in this case.

I think Apple’s idea of a contentScaleFactor is an interesting choice over some sort of pixel pitch or DPI style variable.

public static Vector2 contentScaleFactor = new Vector2(Resolution.width / 480, Resolution.height / 320);

It needs to be a Vector2 because different devices have different aspect ratios.

Then just add a script to each guiTexture you use that says
void Start()
{
guiTexture.size *= contentScaleFactor;
}

Although in Player Settings for Unity3 you can just enforce a GUI resolution of 320x480 for Retina devices. (the rest is still quite crisp, but it automatically resizes the textures for you)

There is no magic that will give you what you want.
As mentioned above, already the example with the aspect ratio shows that you will be going to write different UI handlers for the different cases commonly.

A single interface for desktop - ipad - iphone / android isn’t going to work out anyway
On the desktop drawcalls are not really a problem ( a major part of unity gui), yet on the mobiles you normally want touch interactivity, something totally uncommon and unrequired on the desktop for example.

@Ntero

What you propose doesn’t make sense. What is needed is info about the physical hardware, not the pixels, to map logical units to pixels. There is no way you can ever know form just width and height what the pixel pitch is relative to physical size.

@dreamora

I disagree. The point of something like a DPI or scale factor is precisely to support odd shaped or non-standard displays. It is simply a clue to the developer on how to select the content to be shown. We will never be able to derive any sensible values through software without hard coding the specific screen sizes and mapping that to a meaning. But the device maker knows and so through things like contentScaleFactor can let the developer know, in a portable and future proof way, what the physical device is like.

here is little plugin I wrote for iOS screen scale detection

DeviceDisplay.scaleFactor returns int value from 1 to 3 according do device screen scale factor

public class UIScale : MonoBehaviour {
void Start () {
Debug.Log(DeviceDisplay.scaleFactor);
}
}

http://doraslab.com/tools/DeviceDisplay.unitypackage