Finding *physical* screen size

Hi, while i was making my tiny game i wanted to know the physical screen size of a device in order to know which screen to load.
I had one layout suitable for smaller screens and another one suitable for big screens. You know, talking about the size and placement of GUI elements and buttons.

Knowing just the resolution wouldn’t be any good, because a phone with a small physical screen can now have a resolution bigger than a 10" tablet. So it was a matter of the buttons being big enough depending on the size of the device rather than the screen resolution.

I couldn’t find a function in Unity nor the forums, people said about looking at the manifest or a native plugin.
Problem with the manifest is that its not really sure. You’ll just get that your screen is in one of the general sizes. Small,medium and such. That doesn’t help a lot since some of the size groups actually overlap with each other.

P.S. yeah i just noticed that you can do away with one of the lines.

So i thought about using Pythagoras’s theorem.

private var diagonalInches:float;
private var width:float;
private var height:float;
private var ypotinousa:float;

//calculate physical inches with pythagoras theorem
function screenInch(){

	width=Screen.width*Screen.width;
	height=Screen.height*Screen.height;
	ypotinousa=width+height;
	ypotinousa=Mathf.Sqrt(ypotinousa);
	diagonalInches=ypotinousa/Screen.dpi;
}

So at the end diagonalInches will have the a number stored in it that is the physical diagonal screen size.
Now i would know the size.

I just thought that someone might need it someday. Not a really wow thing but anyway.

5 Likes

Thanks for the snippet …I didnt know there was Screen.dpi

Apparently Screen.dpi is not guaranteed to be accurate in general, but on mobile devices it’s probably a good bet. Standalone or OUYA may not be able to get this information about your generic plugged-in monitor or TV, for example. If you find DPI to be less than 25 or over 1000, the device is probably not supported. I default to something typical of mid-range devices just in case, rather than getting something sure to be unsafe or unusable.

    dpi = Screen.dpi
    if dpi < 25 or dpi > 1000:
        dpi = 150
2 Likes

I guess yeah, for desktop it may not work, i’ll have to test it sometime. The game is for tablets and phones.
Don’t know if there is some sort of function that returns the name of the device?
Like on an ios project that you can ask for the iphone generation.

If you scale your UI according to Android’s DP (device independent pixels) your UI will always be physically the same size.

Grab the size and density from code (I used an Android Java call to get them) and then scale according to the DP math on this page:

That’s exactly how the Android native UI works, and why a button is always physically the same size no matter what device it runs on.

I’m no programmer and native code is beyond me. Would that work with my in game GUI made from unity’s guitextures?

It actually shouldn’t be too hard to do.

As mentioned, Screen.dpi won’t be entirely accurate. But the number it returns for an Android device is what you want to work with. It most likely isn’t the true DPI for the device, but it is the correct DPI to use if you want to use Android DP scale system. But there should be an even better way, Android devices have already calculated the correct scaling factor for you if you design for a 160DPI 4 inch screen.

I haven’t touched it in a while, but try playing around with this idea:

Design your UI on Android as if you are using a 160DPI phone screen.

Then scale it by DisplayMetricsAndroid.Density using the code below. Put the code below in a script that will run at startup.

DisplayMetricAndroid.Density is automatically set to the correct number to scale your UI for every Android device. But only if you have designed for a 160DPI phone screen (about a 4 inch screen).

Of course, you might have to fiddle with your layout and scaling factor until it is perfect, for instance if you wanted to design for a 320DPI phone screen then you just divide the scaling factor by two as well. It’s something you can try out if you want to fiddle a bit.

public class DisplayMetricsAndroid {

    // The logical density of the display
    public static float Density { get; protected set; }

    // The screen density expressed as dots-per-inch
    public static int DensityDPI { get; protected set; }

    // The absolute height of the display in pixels
    public static int HeightPixels { get; protected set; }

    // The absolute width of the display in pixels
    public static int WidthPixels { get; protected set; }

    // A scaling factor for fonts displayed on the display
    public static float ScaledDensity { get; protected set; }

    // The exact physical pixels per inch of the screen in the X dimension
    public static float XDPI { get; protected set; }

    // The exact physical pixels per inch of the screen in the Y dimension
    public static float YDPI { get; protected set; }

    static DisplayMetricsAndroid() {
       // Early out if we're not on an Android device
       if (Application.platform != RuntimePlatform.Android) {
         return;
       }

       // The following is equivalent to this Java code:
       //
       // metricsInstance = new DisplayMetrics();
       // UnityPlayer.currentActivity.getWindowManager().getDefaultDisplay().getMetrics(metricsInstance);
       //
       // ... which is pretty much equivalent to the code on this page:
       // http://developer.android.com/reference/android/util/DisplayMetrics.html

       using (
         AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"),
         metricsClass = new AndroidJavaClass("android.util.DisplayMetrics")
       ) {
         using (
          AndroidJavaObject metricsInstance = new AndroidJavaObject("android.util.DisplayMetrics"),
          activityInstance = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity"),
          windowManagerInstance = activityInstance.Call<AndroidJavaObject>("getWindowManager"),
          displayInstance = windowManagerInstance.Call<AndroidJavaObject>("getDefaultDisplay")
         ) {
          displayInstance.Call("getMetrics", metricsInstance);
          Density = metricsInstance.Get<float>("density");
          DensityDPI = metricsInstance.Get<int>("densityDpi");
          HeightPixels = metricsInstance.Get<int>("heightPixels");
          WidthPixels = metricsInstance.Get<int>("widthPixels");
          ScaledDensity = metricsInstance.Get<float>("scaledDensity");
          XDPI = metricsInstance.Get<float>("xdpi");
          YDPI = metricsInstance.Get<float>("ydpi");
         }
       }
    }
}
4 Likes

Thx, i’ll save it an test it later.

Need “using UnityEngine;” in the Chris Clark’s code to work.

Hi, Are there any to get physical screen size for iOS?