OrientationControl - Make your game work at any orientation and resolution

OrientationControl makes your GUI, Input and Cameras work at any orientation and any resolution!

• Simply select all device orientations you want to support, link your cameras, input scripts and GUI to the OrientationControl Singleton and the game will softly rotate towards the new orientation when you turn the device.
• Detect retina-displays and load different sets of assets for normal and retina resolution. OrientationControl provides a way to use the same code for both resolutions - no double-coding needed!
• Works on iPhone, iPad, Android, PC/MAC and Web
• All scripts are provided in JS and C#.

OrientationControl is also available as a part of GUIKit001

Hope you find this useful - Please let us know what you think!

Here’s a short video overview of OrientationControl: Watch it on Facebook, Youtube or right here: (you might want to switch to HD for this)

Just sent out the first little update to OrientationControl!

Not a big change, but a very nice one: screenWidth and screenHeight no longer switch in the middle of the orientation-change, but instead they morph from one value to the other. That means that if you use these two variables to place your gui-elements, they will now smoothly change position!

HI,

Orientation switch from Landscape_L to Landscape_R works fine, but we’re still getting that dreaded ‘black frame border’ rotating along with it, but just a second or so later. Anything you can think of so we can get rid of this?

thanks,
Brendang

Yes, there’s a variable in the inspector that’s called something like autoRotateKeyboard… Disable this and the black border is gone (for some weird reason the black frame is a part of the (usually out of view) keyboard and if you stop that from aligning with your orientation the black frame won’t show. - if you need the keyboard in your project you might have to enable keyboardrotation again manually before you show it.)

@col000r - This doesn’t seem to be rotating my GUIText Objects. Am I missing something simple?

@Jacob Williams: GUIText and GUITexture belong to the old GUI-System and can’t ever be rotated.The UnityGUI replacement for a GUIText would be GUI.Label()

hi there

will this work with ezgui

thank you

I haven’t tried and don’t know enough about EZGUI to speculate, sorry. Anyone else?

-25% on everything till the end of the year 2010! - Only on GameAssets.net

Dedicated thread here

Update to 1.2 just went out to everyone who bought it on http://GameAssets.net!

ChangeLog:

  • Added a new set of functions that makes it easier to position GUI-elements in the corners while adjusting their size to the current scaleFactor (Works in any resolution!) : ScaleRectTopLeft(Rect), ScaleRectTopRight(Rect), ScaleRectBottomLeft(Rect), ScaleRectBottomRight(Rect)
  • Added a second set of functions that only helps with positioning and does no scaling: PositionRectTopLeft(Rect), PositionRectTopRight(Rect), PositionRectBottomLeft(Rect), PositionRectBottomRight(Rect)
  • New Function: AlignInput(Vector2) - feed it touch or mouse coordinates and you’ll get the GUI coordinates in the current orientation
  • New Function: LoadTexture2D(string) - loads and returns a texture from the current resource path.

AssetStore Update will follow eventually (getting a server error when trying to submit…)

I’ve purchased it using AssetStore, hope it get’s the update soon :slight_smile:

OrientationControl is really great, I’m just wondering about one thing though. In my game, I have many different scenes I switch between, and on each scene I have an OrientationControl instance.

The problem I’m having is that, if I run the game on an iPad, if the default orientation is LandscapeLeft, and I rotate my iPad to LandscapeRight, every time I switch to a new scene, the new scene opens as LandscapeLeft again, then after 0.5 secs it rotates normally to LandscapeRight.

I’ve tried to put this code at the Awake() on new scenes to make it rotate right away quickly:

if(theCurrentOrientation == DeviceOrientation.LandscapeRight)
{	
	StartCoroutine(OrientationControl.instance.RotateScreenTo(OrientationControl.instance.matrixAngle + 180.0f, 0.01f, theCurrentOrientation));
}

Which works, but for 0.5 secs the new scene shows up LandscapeLeft before it quickly rotates to LandscapeRight.

Do you know if there’s a way to fix this? Thanks! :slight_smile:

@TMK: Hm… So it shows up in the default orientation for a short moment before the call from Awake turns it correctly? A few ideas: I use LoadLevelAdditive or LoadLevelAdditiveAsync and there you don’t really get a level-change, since all the stuff from the new level is added to the current one.

If you don’t want to change your project that much though, a simple (though admittedly inelegant) solution could be to add a fade from black 0.5 sec after the scene was loaded.

Alright… I tried a few things and the following should work without requiring any changes to your project (Note that it will only work on the Device! it doesn’t work correctly in the Editor+Remote). Add this to OrientationControl:

	void OnDestroy() {
		int orient = 0; //LandscapeLeft
		if(Input.deviceOrientation == DeviceOrientation.LandscapeRight) orient = 1;
		else if(Input.deviceOrientation == DeviceOrientation.Portrait) orient = 2;
		else if(Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown) orient = 3;
		PlayerPrefs.SetInt("OCOrient", orient);	
	}
	
	void OnLevelWasLoaded() {
		if(PlayerPrefs.HasKey("OCOrient")) {
			int orient = PlayerPrefs.GetInt("OCOrient");
			if(orient == 0) {
				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.LandscapeLeft;
				currentDeviceOrientation = DeviceOrientation.LandscapeLeft;
			} else if(orient == 1) {
				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.LandscapeRight;
				currentDeviceOrientation = DeviceOrientation.LandscapeRight;
			} else if(orient == 2) {
				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.Portrait;
				currentDeviceOrientation = DeviceOrientation.Portrait;
			} else if(orient == 3) {
				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.PortraitUpsideDown;
				currentDeviceOrientation = DeviceOrientation.PortraitUpsideDown;
			}
		}

And add this to OnApplicationQuit() or OrientationControl:

PlayerPrefs.DeleteKey("OCOrient");

Hope this helps!

Regarding the AssetStore: I have submitted the update a short while ago and it should become available shortly after Unity 3.2 is out!

Ah, awesome, thanks! Only problem I had was that OnDestroy wasn’t being called for some reason, so I ended up just calling it manually when I switch scenes (I switch scenes using LoadLevelAsync, perhaps that somehow makes it not call it all the time). Works great now though :slight_smile:

By the way, for anyone wondering, I’m also using EZGUI and OrientationControl works great with that, rotates everything correctly.

Yeah I’m having the same black frame rotation as well, even though I disabled the auto Rotate Keyboard. Strangely it happens in one scene but not the other and not all the time and I’m using the same OC prefab for both scenes. Another funny thing is the black frame rotates in the opposite direction as the camera. Not sure if it matters, but the scene with the issue is using an ortho camera.

I’m also getting the same rotation issues as TMK though I’m on iPhone. Mind you I haven’t tried your above solution yet.

I don’t consider myself a programmer, but would this be the correct conversion of the above C# code.

function OnDestroy() {

		var orient : int = 0; //LandscapeLeft

		if(Input.deviceOrientation == DeviceOrientation.LandscapeRight){

			orient = 1;

		}else if(Input.deviceOrientation == DeviceOrientation.Portrait){

			orient = 2;

		}else if(Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown){

			orient = 3;

			PlayerPrefs.SetInt("OCOrient", orient);	

		}
}

	

function OnLevelWasLoaded() {

		if(PlayerPrefs.HasKey("OCOrient")) {

			var orient : int = PlayerPrefs.GetInt("OCOrient");

			if(orient == 0) {

				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.LandscapeLeft;

				currentDeviceOrientation = DeviceOrientation.LandscapeLeft;

			} else if(orient == 1) {

				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.LandscapeRight;

				currentDeviceOrientation = DeviceOrientation.LandscapeRight;

			} else if(orient == 2) {

				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.Portrait;

				currentDeviceOrientation = DeviceOrientation.Portrait;

			} else if(orient == 3) {

				iPhoneSettings.screenOrientation = iPhoneScreenOrientation.PortraitUpsideDown;

				currentDeviceOrientation = DeviceOrientation.PortraitUpsideDown;

			}

		}
}

On another note is there a way to snap the screen orientation instead of smooth rotation from one to the other.

Great product and I thank you for it. I am also using it with EZGUI with no issues so far.

Ok so I figured out the black frame issue. EZGUI has the same auto rotate keyboard setting that needs to be disabled.

I also tried the the above code with no luck on the screen Orientation issue.

@wadoman:

To make it snap instead of rotate: Have a look inside Update and find the call to RotateScreenTo() - it takes 3 arguments, the desired new angle, the time it should take to get there and the new deviceOrientation it will have when done. Try setting the middle one (the time) to 0.

What happens if you use the above code? It looks like correct JS code to me. - One thing that could be is that OnDestroy() might be new to 3.2 and thus wouldn’t work if your Unity-version is below 3.2 (which will be out soon, i hear).

Oh, on second look I found one small error in OnDestroy:

function OnDestroy() {

		var orient : int = 0; //LandscapeLeft

		if(Input.deviceOrientation == DeviceOrientation.LandscapeRight){

			orient = 1;

		}else if(Input.deviceOrientation == DeviceOrientation.Portrait){

			orient = 2;

		}else if(Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown){

			orient = 3;

		}

		PlayerPrefs.SetInt("OCOrient", orient);	
}

The PlayerPrefs-call should be outside the last else if!

A temporary (and slightly less elegant) way to solve this would be to take this code out of OnDestroy and put it in the end of RotateScreenTo(), right before rotationBusy = false; - that way it will get saved every time it rotates and not just when you exit the scene. the other solution is better, but it should work for now!

Just a small thing, I had to make this change in Awake(), just after “SetupDeviceOrientationAngles();”, I added a call to the same code that “OnLevelWasLoaded” runs.

The reason is that “SetupDeviceOrientationAngles()” resets the value that “OnLevelWasLoaded” set back to the default LandscapeLeft.

Not sure if this change messes up anything else though, but it seems to work fine with that change :slight_smile:

I have an issue.
I integrated the OrientationControl in my project.
However, if my project is set to LandscapeLeft, when I’m in game, in say Portrait, and I double click the home button, the multi-task bar appears and the game rotates half way back to Landscape…

How can I avoid this?

Asset Store still has 1.0 …

Anyways, I have a question: I’ve tried integrating OrientationControl into an existing game with existing UI based on UnityGUI. When I had “Center Matrix On Screen” active (default setting), my GUI was completely broken. When I deactivate this, the GUI works fine on the default orientation but disappears in any other rotation.

Not sure if this is a known issue or maybe even fixed in the current release but would be nice to be able to use it. Aside from that: Pretty nice script. The only thing that bugged me a little is that it “installed” itself with a couple of folders into my project. Would be nice to have it packaged with everything where it’s possible in its own “OrientationControl” folder (this won’t work for “Resources”, of course - but for all the rest :wink: ).