Skip to content

Instantly share code, notes, and snippets.

@pix0r
Last active December 21, 2015 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pix0r/6349387 to your computer and use it in GitHub Desktop.
Save pix0r/6349387 to your computer and use it in GitHub Desktop.
UnityView.mm that uses rotation notification
#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