Making unity play nice with iPad and multiple interface orientations

I'm trying to take advantage of some Cocoa/iPhone OS features inside my Unity application on the iPad.

The current problem I'm running in to is that what cocoa thinks is going on and what the unity application thinks is going on with respect to the orientation of the device don't seem to be in sync. I would try to use a UIPopoverController for something, and the orientation of that would just follow the orientation of the device, whereas the game portion would stay fixed.

I managed to fix that by adding in this function in

- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
    iphone::SetScreenOrientation((iphone::ScreenOrientation)[application statusBarOrientation]);

It's not perfect, but it's mostly functional. For my purposes having the game run in both landscape and portrait isn't a big deal, but I would imagine that most people would probably want to put in some kind of limitation in the app to prevent orientation switches to portrait types.

The next problem I ran in to is that the coordinate system for Unity GUI and a UIPopoverController don't seem to be the same on any orientation other than portrait.

For example, I have a GUI button that opens a UIPopoverController to do something. So code that looks like this:

void OnGUI()
    if( GUI.Button( new Rect( 5, 384, 100, 40 ), "Select Photo" ) )

(Where SelectPhoto eventually calls a function in native code that pushes a UIPopoverController with a photo picker.)

On the cocoa side, I have this code:

- (void)OpenImagePicker
    UIImagePickerController* picker = [[[UIImagePickerController alloc] init] autorelease];
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    picker.delegate = self;
    picker.allowsEditing = YES;

    self.popOver = [[[UIPopoverController alloc] initWithContentViewController:picker] autorelease];
    popOver.delegate = self;
    [popOver presentPopoverFromRect:CGRectMake( 5, 384, 100, 40 ) inView:view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

This only points to the button correctly in portrait. If I press the button in any other orientation it's pointing to some weird position. I'm assuming I'm going to need to change the rect that it's presenting from depending on the current interface orientation, but I'm somewhat stumped as to how to figure it out.

Also, weirdly enough, if I press the button in portrait and rotate to any given orientation, the popover points correctly to the button. It's only if I press it while I'm in a different orientation that it fails to work.

Question 1: How do I get cocoa-appropriate positions from unity screen positions?

Answered: I fiddled around with it for a bit and managed to make a function that seems to solve my problems:

- (CGRect)GetMuxedRect:(CGRect)portraitRect // this is the rect that we're using in Unity GUI
    switch( [[UIApplication sharedApplication] statusBarOrientation] )
    case UIInterfaceOrientationPortrait:
        return portraitRect;
    case UIInterfaceOrientationPortraitUpsideDown:
        return CGRectMake( 768 - portraitRect.origin.x - portraitRect.size.width, 1024 - portraitRect.origin.y - portraitRect.size.height, portraitRect.size.width, portraitRect.size.height );
    case UIInterfaceOrientationLandscapeLeft:
        return CGRectMake( portraitRect.origin.y, 1024 - portraitRect.origin.x - portraitRect.size.width, portraitRect.size.height, portraitRect.size.width );
    case UIInterfaceOrientationLandscapeRight:
        return CGRectMake( portraitRect.origin.y - portraitRect.size.height, portraitRect.origin.x, portraitRect.size.height, portraitRect.size.width );
        return portraitRect;

Question 2: What do I need to do with Unity cameras to make the horizontal FOV in landscape modes match the vertical FOV in portraits modes

This was a limitation with previous versions of Unity. With Unity 3.4 this issue is addressed: