Game may start with incorrect Orientation

My game limits “Allowed Orientations for Auto Rotation” to “Landscape Right” and “Landscape Left” in “Player Settings”.
However, it sometimes starts in “Portrait” or “Portrait Upside Down” on the iPhone.

This started happening after I updated from Unity2020 to 2021.

Current environment is Unity 2021.3.16f1, running iOS 16.2.
We have not been able to investigate this issue in detail due to its infrequency.
Does anyone have any information on this?

Is the iOS screen rotation buggy in relation to this issue?
Does anyone know of any workarounds?

1 Like

Player Settings are as follows

Same here on 2021.3.18f1, without autorotation enabled. The game would just randomly rotate to landscape on its own, started seeing this since iOS 16 update in particular.

same here 2021.3.18,
My app is starting and landscape but in one scene it needs to switch to Portrait
On Android and ios 15 it’s fine but it’s keeping landscape and cannot switch to portrait on ios 16

Same Problem in Unity 2019.4.18f1, still looking for a fix.

We may be seeing a similar bug, where a portrait orientation is displayed when we switch from an iOS OS screen (lock screen, etc.) to our Unity player application, which has only landscape modes checked for the Allowed Orientations for Auto Rotation.
We noticed that the bug may not have reproducible on an iPhone 13 with iOS 16.1.2, but it did occur when upgrading that device to iOS 16.4.1, which was done just to attempt the reproduction of the bug.

https://developer.apple.com/forums/thread/710354
it seems that apple introduced new api, and, as usual, broke some existing code. We are researching what is happening

1 Like

Is there a temporary solution please, I see that someone in IOS developer calls when rotating
if #available(iOS 16.0, *) {
self. setNeedsUpdateOfSupportedInterfaceOrientations()
}
solve this problem

1 Like

As a temporary solution, is it feasible to call SetNeedsUpdateOfSupportedInterfaceOrientations once when the game starts in xcode?

is it feasible to call SetNeedsUpdateOfSupportedInterfaceOrientations once when the game starts in xcode?

yeah, in UI/UnityViewControllerBase+iOS.mm we have two places (why two? oh well, that happened) where we update controller orientations: in init and updateSupportedOrientations
you can add to both i guess (alas, i was not able to repro still, so blindly “fixing” is a bit meh)

This bug cannot be reproduced stably. First of all, you need to make your iphone as parallel to the ground as possible, cut the game in vertical screen or lock the screen and exit and then quickly open the game. This may also have something to do with the sensor

- (id)init
{
    if ((self = [super init]))
    {
        if (@available(iOS 16.0, *)) {
            [self setNeedsUpdateOfSupportedInterfaceOrientations];
        }
        NSAssert(UnityShouldAutorotate(), @"UnityDefaultViewController should be used only if unity is set to autorotate");
        _supportedOrientations = EnabledAutorotationInterfaceOrientations();
       
       
    }
    return self;
}

- (void)updateSupportedOrientations
{
    if (@available(iOS 16.0, *)) {
        [self setNeedsUpdateOfSupportedInterfaceOrientations];
    }
    _supportedOrientations = EnabledAutorotationInterfaceOrientations();
}

I try this method but it doesn’t work, if anyone is proficient in IOS development, please guide me

I read in some posts that it seems that the

[[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];

Call requestGeometryUpdateWithPreferences instead

NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
         UIWindowScene *scene = [array firstObject];
         // screen orientation
         UIInterfaceOrientationMask orientation = isLaunchScreen ? UIInterfaceOrientationMaskLandscapeRight : UIInterfaceOrientationMaskPortrait;
         UIWindowSceneGeometryPreferencesIOS *geometryPreferencesIOS = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:orientation];
         // start switching
         [scene requestGeometryUpdateWithPreferences:geometryPreferencesIOS errorHandler:^(NSError * _Nonnull error) {
             NSLog(@"Force %@Error: %@", isLaunchScreen ? @"Horizontal screen" : @"Vertical screen", error);
         }];

May I ask where is the place where unity modifies the orientation?

We’ve been able to reproduce the issue with orientation on iPhone XR ( iOS 16.3.1). We use “Auto Rotation” with “Ladscape Left” and “Landscape Right” checked. But still the game will be displayed in a portrait mode if these steps are followed:

  1. Open the game
  2. Don’t touch the screen for a few minutes while the screen goes to the screen lock mode
  3. Wait for 5 minutes
  4. Unlock the screen
  5. Turn the phone to the portrait mode

Any workarounds?

1 Like

Yes, on 16.3 and 16.4, this bug often occurs when you unlock the screen after a period of time. On 16.2, you don’t even need to lock the screen. You just need to enter the vertical screen and kill the process. Open the game again and it will appear

For this reason, I upgraded unity from 2020.3.2 to 2020.3.46 and still have the same problem
This BUG may need to be modified in the OC code used for rotation in unity, but I haven’t found the specific location, if anyone knows, please let me know

I don’t see updateSupportedOrientations in the UnityViewControllerBase.mm output from Unity 2020.3.45f1:

#import "UnityViewControllerBase.h"
#import "UnityAppController.h"
#import "UnityAppController+ViewHandling.h"

#include "OrientationSupport.h"


@implementation UnityViewControllerBase

@synthesize notificationDelegate = _notificationDelegate;

- (id)init
{
    if ((self = [super init]))
        self.modalPresentationStyle = UIModalPresentationFullScreen;
    return self;
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [_notificationDelegate onViewWillLayoutSubviews];
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [_notificationDelegate onViewDidLayoutSubviews];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear: animated];
    [_notificationDelegate onViewDidDisappear: animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear: animated];
    [_notificationDelegate onViewWillDisappear: animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear: animated];
    [_notificationDelegate onViewDidAppear: animated];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear: animated];
    [_notificationDelegate onViewWillAppear: animated];
}

@end

UnityViewControllerBase* AllocUnityDefaultViewController()
{
    return [UnityDefaultViewController alloc];
}

#if UNITY_SUPPORT_ROTATION
UnityViewControllerBase* AllocUnitySingleOrientationViewController(UIInterfaceOrientation orient)
{
    switch (orient)
    {
        case UIInterfaceOrientationPortrait:            return [UnityPortraitOnlyViewController alloc];
        case UIInterfaceOrientationPortraitUpsideDown:  return [UnityPortraitUpsideDownOnlyViewController alloc];
        case UIInterfaceOrientationLandscapeLeft:       return [UnityLandscapeLeftOnlyViewController alloc];
        case UIInterfaceOrientationLandscapeRight:      return [UnityLandscapeRightOnlyViewController alloc];

        default:                                        assert(false && "bad UIInterfaceOrientation provided");
    }
    return nil;
}

#endif

UnityViewControllerBase* AllocUnityViewController()
{
#if UNITY_SUPPORT_ROTATION
    if (UnityShouldAutorotate())
        return AllocUnityDefaultViewController();

    UIInterfaceOrientation orient = ConvertToIosScreenOrientation((ScreenOrientation)UnityRequestedScreenOrientation());
    return AllocUnitySingleOrientationViewController(orient);
#else
    return AllocUnityDefaultViewController();
#endif
}

Because he is in UI/UnityViewControllerBase+iOS instead of UnityViewControllerBase, I have tried this and it has not worked

1 Like

What is your highest reproduction percentage, roughly? And, which hardware, OS and steps?
I haven’t had any luck with an iPhone 12 pro max and iOS 16.4.1 with our app, which my team does see the bug with on iPhone 12-14 and iOS 16.3-4.

For whoever sees incorrect orientation, can you please try the following:
in Classes/UI/UnityViewControllerBase+iOS.mm
find - (void)viewDidAppear:(BOOL)animated and add above:

- (void)viewWillAppear:(BOOL)animated
{
    _currentOrientation = UIViewControllerOrientation(self);
    [GetAppController() updateAppOrientation: ConvertToIosScreenOrientation(_currentOrientation)];
    [super viewWillAppear: animated];
}

so it looks like this

- (void)viewWillAppear:(BOOL)animated
{
    _currentOrientation = UIViewControllerOrientation(self);
    [GetAppController() updateAppOrientation: ConvertToIosScreenOrientation(_currentOrientation)];
    [super viewWillAppear: animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    _currentOrientation = UIViewControllerOrientation(self);
    [GetAppController() updateAppOrientation: ConvertToIosScreenOrientation(_currentOrientation)];
    [super viewDidAppear: animated];
}

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
1 Like