iPhone 3GS vs. iPhone 4 resolution

So I am beginning work on the Main Menu, the UI, the HUD (all these GUI 2d elements really) I want to initially support the iPhone 3G, 3GS and iPhone 4. My question is…should I go about designing everything to iPhone 4 resolution (960x640) and really doing some device resolution detection script to kind of automatically scale all assets down to 3GS resolution? I have done some researching around the forums before posting, but I can’t seem to compile a consensus on how to approach this. If there is some kind of script to autodetect the device and scale all of the artwork down or up?

My solution for this is check for device generation then load the level additively that has the specific resolution HUD. Create two scenes with different HUD resolutions then do this:

	//Load device specific HUD
	if (iPhoneSettings.generation == iPhoneGeneration.iPhone3G){
		Application.LoadLevelAdditive ("HUD 480X320");
		//print ("Yes Loaded for iPhone 3G");
	} else if (iPhoneSettings.generation == iPhoneGeneration.iPhone4){
		Application.LoadLevelAdditive ("HUD 960X640");
		//print ("Yes Loaded for iPhone 4");
	}

the check though is incorrect, cause you must also check for itouch.

Optimally you do a 2 tier check:

  1. is ipad, yes or no → YES: 1024x768
  2. if no, is it an itouch4 / iphone 4 yes or no → YES: 960x640
  3. NO: 480x320

that way you save yourself a whole host of checks for the 6 devices with low resolution

That or you just use Screen.height Screen.width :wink:

dreamora - So if I used Screen.Height and Screen.Width, is that just setting a fixed screen size, i.e. like 480x320 and then on an iPhone 4 it would just scale it up to fit or center it on that device’s screen?

jrricky - So to see if I understand what you mean…basically I would run a check on the device type, and load the matching resolution scene for that device? In essence I would need 3 versions of each scene in each resolution?

No, but by using Screen.Height and Screen.width you get the actual screen width and height, you don’t need to do dirty “assumption magic” basing on model numbers which with the release of new devices are no longer correct

Scale up does not exist for 3D context. Either its at high res or it isn’t, in the later case unity will really render 480x320 pixels and only those will show.

auto upscale only exists with UIKit

I guess my main concern isn’t with the actual 3D content of the game itself as it is with the 2D elements for the heads up display going over the 3D content of the game. In my case it would be like a speedometer, a gas pedal, a brake pedal and some lap/time counters at the top. I would want these elements to appear the size I designed them to be on both 3GS and iPhone 4. I’m imagining here in my head, that my gas pedal (2d GUI texture) on a 3GS will be the proper size and appear ultra small on an iPhone 4 (thanks to it’s doubled resolution).

that kind of stuff would normally be done with a real 3d thing anyway, be it EZGUI or something you do yourself, you aren’t going to use ongui due to performance constraints.

As you can make those using a layer and then have an orthographic cam render just them that, my trick with the orthographic size applies and with the same aspect ratio works without any problem basically

okay so as long as the UI stuff is constrained on a layer with an orthographic camera (so no tweak to aspect ratio)…then everything will be proportionate on either device. It will scale evenly between iPhone4 and 3Gs basically, so I would want to basically create my UI textures at iPhone 4 resolution so they look crisp and not blurry.

I usually do two applications so the one with HD on its name would be the iPhone4 and iPad resolutions. With this I avoid adding textures for each resolutions so the game does not gets higher than 20MB (users can download them without needing wifi). On the other hand you can have memory problems loading 960x480 textures on a 3G mobile. As someone mentioned you could load an scene or another depending on the mobile generation but then your application size will exceed for sure the 20MB :slight_smile: Good luck on this!

Yes, build your GUI for iPhone 4 (I would say even higher to reduce having to go back and redo if newer devices have higher res), then save out the 3G lower scaled GUIs. Build two scenes that have each res HUD, then as dreamora stated, do 3 checks instead of 6 in your main gameplay level, and use the code I pasted in a GameManager script or something that checks this in a start function.

I would recommend EZGUI extension for your HUD creations since there is a steps you could take that reduces headaches when trying to place you GUI at certain spots. Its saved me so much time.

@Barbur, thats a good thing to look out for but with increasing limits and faster speeds around the corner, I wouldn’t worry about it that much, especially if your game is 3D, that’s something you rarely are going to be able to avoid.

Thanks for all the help guys…Seriously appreciated! I think I’m going to create an iPad build all to itself and call it the HD version of the app. I will then make the app iPhone 4 resolution and do a scale down for 3GS and earlier via startup code check.

Ok it seems that now you cannot do two applications anymore. There is a new apple rule that says:

I had two games one of them HD and they just aproved the HD and rejected the other one :-/

So I guess now it comes down to a script that can recognize the device generation and scale it down accordingly right? I’m thinking if my UI stuff is 3D as well, it should scale properly with the rest of the 3d world. In fact now that I think about it…most folks have said that the 3d stuff in the world is pretty independent of device resolution, it scales up or down. So if my UI elements were 3D elements I wouldn’t have in-game scale issues correct?

Hi James,
You just need to have a scale factor and calculate the GUI sizes on the Awake or Start functions. The scale factor is usually:

Being the native_resolution the resolution you used by default to build your GUI.

Of course if you build your GUI thinking in a 480x320 resolution when you scale it up to retina display you will see very pixelated textures so you could use 960x480 textures and rescale them down to 480x320 or, another solution, would be to load the desired texture from the Resources folder.

That’s true but then you will have to care about repositioning it in front of the camera and launch rays to detect mouse clicking and so on. I would recommend you to go to the 2D option so at some time you will have to face the resolution problem :slight_smile:

Yeah I am considering the doing everything at 960x640 resolution and scaling down for the the older devices…considering there are no changes to the aspect ratio. However with this approach I am using far more texture memory than would have been needed on the older devices. Would be nice if I accomplish the following with code…scale down to the screen resolution of the older devices (if need be) and swap in the 320x480 screen res menu and GUI textures for the older devices. Is there a way to do this in script…the scaling to a lower screen resolution and swapping in the older gen textures if it’s scaled down?

Just realized the texture swapping for the different device generations would require me to have two sets of each texture, thus causing me to eat up even more texture memory overall in my game. Probably best just to create iPhone 4 res textures for menu UI and in game HUD and scale down to the older generation devices?

I have 2 sets of textures, one for low and one for high. I keep them in the resource directory and only low the one set I need so I don’t waster any memory.

Could you direct me to any info on the resource directory? I know about Unity’s asset folder structure…

Hi James,

in my projects, i have a prefab to which this script (name it “DeviceInfo.js”) is attached:

var simulate3G : boolean = false;
var simulate4G : boolean = false;
var simulateIPad : boolean = false;

static var deviceGeneration_3G   : int = 1;
static var deviceGeneration_4G   : int = 2;
static var deviceGeneration_iPad : int = 3;

function getDeviceGeneration() { 

	/*
	iPhone	 		//First generation device
	iPhone3G		// Second generation
	iPhone3GS		// Third generation
	iPodTouch1Gen	// iPod Touch, first generation
	iPodTouch2Gen	// iPod Touch, second generation
	iPodTouch3Gen	// 	iPod Touch, third generation
	sowie alle Devices mit 480 x 320
	*/
	if ( 	simulate3G
			|| iPhoneSettings.generation == iPhoneGeneration.iPhone 
			|| iPhoneSettings.generation == iPhoneGeneration.iPhone3G 
			|| iPhoneSettings.generation == iPhoneGeneration.iPhone3GS 
			|| iPhoneSettings.generation == iPhoneGeneration.iPodTouch1Gen 
			|| iPhoneSettings.generation == iPhoneGeneration.iPodTouch2Gen 
			|| iPhoneSettings.generation == iPhoneGeneration.iPodTouch3Gen
			|| ( Screen.width == 480  Screen.height == 320 )  
		) 
	{
		return deviceGeneration_3G;
	}
	
	/*
	iPhone4			// Fourth generation	
	iPodTouch4Gen 	// iPod Touch, fourth generation
	sowie alle Devices mit 960 x 640
	*/
	else if ( 	simulate4G 
				|| iPhoneSettings.generation == iPhoneGeneration.iPhone4 
				|| iPhoneSettings.generation == iPhoneGeneration.iPodTouch4Gen
				|| ( Screen.width == 960  Screen.height == 640 )
			)
	{
		return deviceGeneration_4G;
	}
	
	/*
	iPad1Gen
	sowie alle Devices mit 1024 X 768	
	*/	
	else if ( 	simulateIPad 
				|| iPhoneSettings.generation == iPhoneGeneration.iPad1Gen 
				|| ( Screen.width == 1024  Screen.height == 768 )
			)
	{
		return deviceGeneration_iPad;
	}
	
	// FALLBACK to 480 x 320
	else {
		Debug.Log("FALLBACK - unknown device!");
		return deviceGeneration_3G;		
	}

}

In the script that actually builds the hud (== changes textures based on device), there is this member var:

var deviceInfo : DeviceInfo;

dont forget to drag the GO, to which you attached the script “DeviceInfo.js”, to this variable in inspector.

and in the start method, i do thinks like:

// IPAD

if ( deviceInfo.getDeviceGeneration() == DeviceInfo.deviceGeneration_iPad ) {
		PromoCT.texture = Resources.Load("MenuIcons/Cubotronic_IPAD");
		helpTexture.pixelInset = Rect(0,0, 1024, 768);			
} 

} else ( deviceInfo.getDeviceGeneration() == DeviceInfo.deviceGeneration_4G  ) {
		PromoCT.texture = Resources.Load("MenuIcons/Cubotronic_4G");
} else {		
		PromoCT.texture = Resources.Load("MenuIcons/Cubotronic_3G");
		PromoCT.pixelInset = Rect(0,0, 112, 63 );
}

to test in the editor, just change the resolution of the game-view; or set one of this (!only one!) var to true in the inspector:

var simulate3G : boolean = false; << set this, or one of the others to true for testing.
var simulate4G : boolean = false;
var simulateIPad : boolean = false;

in my opionion, the best way is to just change the resolution of the gameview in editor.

hth!
thomas

PS:
Resources.Load(“MenuIcons/Cubotronic_4G”);

means:

  • you must have a folder “Resources” in your assets-folder
  • there is a subfolder named “MenuIcons”.

Wow good god, this is a life saver! Thank you so very much for taking the time to help out…people like you make Unity and these forums such an amazing thing.