Last active
December 21, 2015 18:48
-
-
Save pix0r/6349387 to your computer and use it in GitHub Desktop.
UnityView.mm that uses rotation notification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "UnityView.h" | |
#include "iPhone_View.h" | |
#include "iPhone_OrientationSupport.h" | |
#include "Unity/UnityInterface.h" | |
#include "Unity/GlesHelper.h" | |
#include "Unity/DisplayManager.h" | |
extern void UnitySendTouchesBegin(NSSet* touches, UIEvent* event); | |
extern void UnitySendTouchesEnded(NSSet* touches, UIEvent* event); | |
extern void UnitySendTouchesCancelled(NSSet* touches, UIEvent* event); | |
extern void UnitySendTouchesMoved(NSSet* touches, UIEvent* event); | |
@implementation UnityView | |
{ | |
CGSize _surfaceSize; | |
ScreenOrientation _curOrientation; | |
BOOL _recreateView; | |
} | |
- (BOOL)currentOrientationMatchesDevice { | |
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; | |
if (UIDeviceOrientationIsValidInterfaceOrientation(deviceOrientation)) { | |
if ((int)deviceOrientation != (int)_curOrientation) { | |
return NO; | |
} | |
} | |
return YES; | |
} | |
- (void)didRotateNotification { | |
if (![self currentOrientationMatchesDevice]) { | |
// After a short delay, re-check orientation, and force rotation | |
double delayInSeconds = 0.1; | |
__block id bSelf = self; | |
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); | |
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ | |
[bSelf ensureOrientation]; | |
}); | |
} | |
} | |
- (void)ensureOrientation { | |
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; | |
if (![self currentOrientationMatchesDevice]) { | |
// Orientation does not match; force! | |
[self willRotateTo:(ScreenOrientation)deviceOrientation]; | |
} | |
} | |
- (id)initWithFrame:(CGRect)frame | |
{ | |
if( (self = [super initWithFrame:frame]) ) | |
{ | |
[self setMultipleTouchEnabled:YES]; | |
[self setExclusiveTouch:YES]; | |
_surfaceSize = frame.size; | |
// Register for rotation notification | |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotateNotification) name:UIDeviceOrientationDidChangeNotification object:nil]; | |
} | |
return self; | |
} | |
- (void)layoutSubviews | |
{ | |
if (_surfaceSize.width != self.bounds.size.width || _surfaceSize.height != self.bounds.size.height) | |
{ | |
_surfaceSize = self.bounds.size; | |
_recreateView = YES; | |
} | |
} | |
- (void)willRotateTo:(ScreenOrientation)orientation | |
{ | |
_curOrientation = orientation; | |
UnitySetScreenOrientation(_curOrientation); | |
} | |
- (void)didRotate | |
{ | |
if(_recreateView) | |
{ | |
// we are not inside repaint so we need to draw second time ourselves | |
[self recreateGLESSurface]; | |
UnityPlayerLoop(); | |
} | |
} | |
- (ScreenOrientation)contentOrientation | |
{ | |
return _curOrientation; | |
} | |
- (void)recreateGLESSurfaceIfNeeded | |
{ | |
unsigned requestedW, requestedH; UnityGetRenderingResolution(&requestedW, &requestedH); | |
int requestedMSAA = UnityGetDesiredMSAASampleCount(MSAA_DEFAULT_SAMPLE_COUNT); | |
if( GetMainDisplay()->surface.use32bitColor != UnityUse32bitDisplayBuffer() | |
|| GetMainDisplay()->surface.use24bitDepth != UnityUse24bitDepthBuffer() | |
|| requestedW != GetMainDisplay()->surface.targetW || requestedH != GetMainDisplay()->surface.targetH | |
|| (_supportsMSAA && requestedMSAA != GetMainDisplay()->surface.msaaSamples) | |
|| _recreateView == YES | |
) | |
{ | |
[self recreateGLESSurface]; | |
} | |
} | |
- (void)recreateGLESSurface | |
{ | |
extern bool _glesContextCreated; | |
extern bool _unityLevelReady; | |
extern bool _skipPresent; | |
if(_glesContextCreated) | |
{ | |
unsigned requestedW, requestedH; | |
UnityGetRenderingResolution(&requestedW, &requestedH); | |
[GetMainDisplay() recreateSurface:UnityUse32bitDisplayBuffer() use24bitDepth:UnityUse24bitDepthBuffer() | |
msaaSampleCount:UnityGetDesiredMSAASampleCount(MSAA_DEFAULT_SAMPLE_COUNT) | |
renderW:requestedW renderH:requestedH | |
]; | |
if(_unityLevelReady) | |
{ | |
// seems like ios sometimes got confused about abrupt swap chain destroy | |
// draw 2 times to fill both buffers | |
// present only once to make sure correct image goes to CA | |
// if we are calling this from inside repaint, second draw and present will be done automatically | |
_skipPresent = true; | |
{ | |
SetupUnityDefaultFBO(&GetMainDisplay()->surface); | |
UnityPlayerLoop(); | |
UnityFinishRendering(); | |
} | |
_skipPresent = false; | |
} | |
} | |
_recreateView = NO; | |
} | |
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event | |
{ | |
UnitySendTouchesBegin(touches, event); | |
} | |
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event | |
{ | |
UnitySendTouchesEnded(touches, event); | |
} | |
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event | |
{ | |
UnitySendTouchesCancelled(touches, event); | |
} | |
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event | |
{ | |
UnitySendTouchesMoved(touches, event); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment