Commit fb3f3ce2 cgx

优化unity

1 个父辈 5d1f390f
......@@ -10,6 +10,7 @@
// APP和KeyWindow
#define DSApplication [UIApplication sharedApplication]
#define DSKeyWindow DSApplication.keyWindow
#define DSDelegateWindow DSApplication.delegate.window
// 系统及APP版本
#define DSSystemVersion ([[[UIDevice currentDevice] systemVersion] floatValue])
......
......@@ -7,10 +7,6 @@
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/// 三分钟即刻入睡VC(哄睡界面、Unity界面)
@interface ThreeMinuteController : UIViewController
@end
NS_ASSUME_NONNULL_END
......@@ -7,8 +7,10 @@
#import "ThreeMinuteController.h"
#import "AppDelegate.h"
#import <UnityFramework/UnityFramework.h>
@interface ThreeMinuteController ()
@interface ThreeMinuteController () <UnityFrameworkListener>
@property (nonatomic, strong) UnityFramework* ufw;
@end
@implementation ThreeMinuteController
......@@ -18,9 +20,7 @@
self.view.backgroundColor = DSBlack;
// 加载unity
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate showUnityView];
[self showUnityView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitCoaxSleep) name:ExitCoaxSleep object:nil];
}
......@@ -42,4 +42,50 @@
return YES;
}
#pragma mark - Unity
UnityFramework* UnityFrameworkLoad(void) {
NSString* bundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Frameworks/UnityFramework.framework"];
NSBundle* bundle = [NSBundle bundleWithPath:bundlePath];
if ([bundle isLoaded] == false) { [bundle load]; }
UnityFramework *ufw = [bundle.principalClass getInstance];
if (![ufw appController]) { [ufw setExecuteHeader:&_mh_execute_header]; }
return ufw;
}
- (bool)unityIsInitialized {
return [self ufw] && [[self ufw] appController];
}
extern int gArgc;
extern char** gArgv;
- (void)initUnity {
// unity如果初始化了,首先需要卸载unity
if ([self unityIsInitialized]) {
[DSProgressHUD showDetailInfo:@"Unity already initialized,please unload unity first"];
return;
}
[self setUfw:UnityFrameworkLoad()];
[[self ufw] setDataBundleId:"com.unity3d.framework"];
[[self ufw] registerFrameworkListener:self];
[[self ufw] runEmbeddedWithArgc:gArgc argv:gArgv appLaunchOpts:nil];
}
- (void)showUnityView {
[self initUnity];
[self.ufw showUnityWindow];
}
#pragma mark - UnityFrameworkListener
- (void)unityDidUnload:(NSNotification*)notification {
DSLog(@"unityDidUnload");
[[self ufw] unregisterFrameworkListener:self];
[self setUfw: nil];
[DSDelegateWindow makeKeyAndVisible];
}
@end
......@@ -6,16 +6,8 @@
//
#import <UIKit/UIKit.h>
#import <UnityFramework/UnityFramework.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, UnityFrameworkListener>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow * window;
#pragma mark - Unity
@property (nonatomic, strong) NSDictionary * appLaunchOpts;
@property (nonatomic, strong) UnityFramework* ufw;
/// 显示unity
- (void)showUnityView;
@end
......@@ -158,55 +158,4 @@
}
}
#pragma mark - Unity
UnityFramework* UnityFrameworkLoad(void) {
NSString* bundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Frameworks/UnityFramework.framework"];
NSBundle* bundle = [NSBundle bundleWithPath:bundlePath];
if ([bundle isLoaded] == false) { [bundle load]; }
UnityFramework *ufw = [bundle.principalClass getInstance];
if (![ufw appController]) { [ufw setExecuteHeader:&_mh_execute_header]; }
return ufw;
}
- (bool)unityIsInitialized {
return [self ufw] && [[self ufw] appController];
}
extern int gArgc;
extern char** gArgv;
- (void)initUnity {
// unity如果初始化了,首先需要卸载unity
if ([self unityIsInitialized]) {
[DSProgressHUD showDetailInfo:@"Unity already initialized,please unload unity first"];
return;
}
[self setUfw:UnityFrameworkLoad()];
[[self ufw] setDataBundleId:"com.unity3d.framework"];
[[self ufw] registerFrameworkListener:self];
[[self ufw] runEmbeddedWithArgc:gArgc argv:gArgv appLaunchOpts:self.appLaunchOpts];
}
- (void)showUnityView {
[self initUnity];
[self.ufw showUnityWindow];
}
#pragma mark - UnityFrameworkListener
- (void)unityDidUnload:(NSNotification*)notification {
DSLog(@"unityDidUnload");
[[self ufw] unregisterFrameworkListener:self];
[self setUfw: nil];
[self.window makeKeyAndVisible];
}
- (void)applicationWillResignActive:(UIApplication *)application { [[[self ufw] appController] applicationWillResignActive: application]; }
- (void)applicationDidEnterBackground:(UIApplication *)application { [[[self ufw] appController] applicationDidEnterBackground: application]; }
- (void)applicationWillEnterForeground:(UIApplication *)application { [[[self ufw] appController] applicationWillEnterForeground: application]; }
- (void)applicationDidBecomeActive:(UIApplication *)application { [[[self ufw] appController] applicationDidBecomeActive: application]; }
- (void)applicationWillTerminate:(UIApplication *)application { [[[self ufw] appController] applicationWillTerminate: application]; }
@end
......@@ -29,7 +29,7 @@ extern bool _unityAppReady;
{
_curOrientation = orientation;
[_unityView boundsUpdated];
[_unityView willRotateToOrientation: orientation fromOrientation: (UIInterfaceOrientation)UIInterfaceOrientationUnknown];
[_unityView didRotate];
}
......@@ -59,7 +59,7 @@ extern bool _unityAppReady;
case UIInterfaceOrientationPortraitUpsideDown: return [[UnityPortraitUpsideDownOnlyViewController alloc] init];
case UIInterfaceOrientationLandscapeLeft: return [[UnityLandscapeLeftOnlyViewController alloc] init];
case UIInterfaceOrientationLandscapeRight: return [[UnityLandscapeRightOnlyViewController alloc] init];
default: NSAssert(false, @"bad UIInterfaceOrientation provided");
}
return nil;
......@@ -76,7 +76,7 @@ extern bool _unityAppReady;
_viewControllerForOrientation[0] = [self createUnityViewControllerDefault];
ret = _viewControllerForOrientation[0];
}
#if UNITY_SUPPORT_ROTATION
if (ret == nil)
{
......@@ -99,7 +99,7 @@ extern bool _unityAppReady;
{
_unityView.contentScaleFactor = UnityScreenScaleFactor([UIScreen mainScreen]);
_unityView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_rootController.view = _rootView = _unityView;
}
......@@ -114,7 +114,7 @@ extern bool _unityAppReady;
// so we imitate them here so unity view can update its size/orientation
[_unityView willRotateToOrientation: UIViewControllerInterfaceOrientation(toController) fromOrientation: ConvertToIosScreenOrientation(_unityView.contentOrientation)];
[_unityView didRotate];
// NB: this is both important and insane at the same time (that we have several places to keep current orentation and we need to sync them)
_curOrientation = UIViewControllerInterfaceOrientation(toController);
#endif
......@@ -135,86 +135,87 @@ extern bool _unityAppReady;
{
NSAssert(_unityView != nil, @"_unityView should be inited at this point");
NSAssert(_window != nil, @"_window should be inited at this point");
_rootController = [self createRootViewController];
[self willStartWithViewController: _rootController];
NSAssert(_rootView != nil, @"_rootView should be inited at this point");
NSAssert(_rootController != nil, @"_rootController should be inited at this point");
[UIView setAnimationsEnabled: NO];
ShowSplashScreen(_window);
#pragma mark - 3、修复首次加载unity页面出现主APP启动页面问题
// [UIView setAnimationsEnabled: NO];
// ShowSplashScreen(_window);
// make window visible only after we have set up initial controller we want to show
[_window makeKeyAndVisible];
// [_window makeKeyAndVisible];
#if UNITY_SUPPORT_ROTATION
// to be able to query orientation from view controller we should actually show it.
// at this point we can only show splash screen, so update app orientation after we started showing it
// NB: _window.rootViewController = splash view controller (not _rootController)
[self updateAppOrientation: ConvertToIosScreenOrientation(UIViewControllerOrientation(_window.rootViewController))];
#endif
NSNumber* style = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"Unity_LoadingActivityIndicatorStyle"];
ShowActivityIndicator([SplashScreen Instance], style ? [style intValue] : -1);
NSNumber* vcControlled = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"UIViewControllerBasedStatusBarAppearance"];
if (vcControlled && ![vcControlled boolValue])
printf_console("\nSetting UIViewControllerBasedStatusBarAppearance to NO is no longer supported.\n"
"Apple actively discourages that, and all application-wide methods of changing status bar appearance are deprecated\n\n"
);
"Apple actively discourages that, and all application-wide methods of changing status bar appearance are deprecated\n\n"
);
}
- (void)showGameUI
{
HideActivityIndicator();
HideSplashScreen();
// make sure that we start up with correctly created/inited rendering surface
// NB: recreateRenderingSurface won't go into rendering because _unityAppReady is false
#if UNITY_SUPPORT_ROTATION
[self checkOrientationRequest];
#endif
[_unityView recreateRenderingSurface];
// UI hierarchy
[_window addSubview: _rootView];
_window.rootViewController = _rootController;
[_window bringSubviewToFront: _rootView];
#if UNITY_SUPPORT_ROTATION
// to be able to query orientation from view controller we should actually show it.
// at this point we finally started to show game view controller. Just in case update orientation again
[self updateAppOrientation: ConvertToIosScreenOrientation(UIViewControllerOrientation(_rootController))];
#endif
// why we set level ready only now:
// surface recreate will try to repaint if this var is set (poking unity to do it)
// but this frame now is actually the first one we want to process/draw
// so all the recreateSurface before now (triggered by reorientation) should simply change extents
_unityAppReady = true;
// why we skip present:
// this will be the first frame to draw, so Start methods will be called
// and we want to properly handle resolution request in Start (which might trigger surface recreate)
// NB: we want to draw right after showing window, to avoid black frame creeping in
_skipPresent = true;
if (!UnityIsPaused())
UnityRepaint();
_skipPresent = false;
[self repaint];
[UIView setAnimationsEnabled: YES];
}
- (void)transitionToViewController:(UIViewController*)vc
{
[self willTransitionToViewController: vc fromViewController: _rootController];
// first: remove from view hierarchy.
// if we simply hide the window before assigning the new view controller, it will cause black frame flickering
// on the other hand, hiding the window is important by itself to better signal the intent to iOS
......@@ -222,23 +223,23 @@ extern bool _unityAppReady;
// due to that we do this hide/unhide sequence: we want to to make it hidden, but still unhide it before changing window view controller.
_window.hidden = YES;
_window.hidden = NO;
_rootController.view = nil;
_window.rootViewController = nil;
// second: assign new root controller (and view hierarchy with that), restore bounds
_rootController = _window.rootViewController = vc;
_rootController.view = _rootView;
_window.bounds = [UIScreen mainScreen].bounds;
// required for iOS 8, otherwise view bounds will be incorrect
_rootView.bounds = _window.bounds;
_rootView.center = _window.center;
// third: restore window as key and layout subviews to finalize size changes
[_window makeKeyAndVisible];
[_window layoutSubviews];
[self didTransitionToViewController: vc fromViewController: _rootController];
}
......@@ -246,7 +247,7 @@ extern bool _unityAppReady;
- (void)interfaceWillChangeOrientationTo:(UIInterfaceOrientation)toInterfaceOrientation
{
UIInterfaceOrientation fromInterfaceOrientation = _curOrientation;
_curOrientation = toInterfaceOrientation;
[_unityView willRotateToOrientation: toInterfaceOrientation fromOrientation: fromInterfaceOrientation];
}
......@@ -276,7 +277,7 @@ extern bool _unityAppReady;
// update the properties of view controllers when orientation is changed.
#if PLATFORM_IOS
[self executeForEveryViewController: ^(UIViewController* vc)
{
{
// setNeedsUpdateOfHomeIndicatorAutoHidden is not implemented on iOS 11.0.
// The bug has been fixed in iOS 11.0.1. See http://www.openradar.me/35127134
if ([vc respondsToSelector: @selector(setNeedsUpdateOfHomeIndicatorAutoHidden)])
......@@ -289,7 +290,7 @@ extern bool _unityAppReady;
{
#if PLATFORM_IOS
[self executeForEveryViewController: ^(UIViewController* vc)
{
{
[vc setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
}];
#endif
......@@ -313,14 +314,14 @@ extern bool _unityAppReady;
{
if (!UnityHasOrientationRequest() && !UnityShouldChangeAllowedOrientations())
return;
// normally we want to call attemptRotationToDeviceOrientation to tell iOS that we changed orientation constraints
// but if the current orientation is disabled we need special processing, as iOS will simply ignore us
// the only good/robust way is to simply recreate "autorotating" view controller and transition to it if needed
// please note that we want to trigger "orientation request" code path if we recreate autorotating view controller
bool changeOrient = UnityHasOrientationRequest();
// first we check if we need to update orientations enabled for autorotation
// this needs to be done *only* if we are to continue autorotating
// otherwise we will transition from this view controller
......@@ -346,13 +347,13 @@ extern bool _unityAppReady;
changeOrient = true;
}
}
if (changeOrient)
{
// on some devices like iPhone XS layoutSubview is not called when transitioning from different orientations with the same resolution
// therefore forcing layoutSubview on all orientation changes
[_unityView setNeedsLayout];
if (autorot)
{
if (_viewControllerForOrientation[0] == nil)
......@@ -371,7 +372,7 @@ extern bool _unityAppReady;
[self orientInterface: requestedOrient];
}
}
UnityOrientationRequestWasCommitted();
}
......@@ -379,22 +380,22 @@ extern bool _unityAppReady;
{
if (_unityAppReady)
UnityFinishRendering();
[KeyboardDelegate StartReorientation];
[CATransaction begin];
{
UIInterfaceOrientation oldOrient = _curOrientation;
UIInterfaceOrientation newOrient = orient;
[self interfaceWillChangeOrientationTo: newOrient];
[self transitionToViewController: [self createRootViewControllerForOrientation: newOrient]];
[self interfaceDidChangeOrientationFrom: oldOrient];
[UIApplication sharedApplication].statusBarOrientation = orient;
}
[CATransaction commit];
[KeyboardDelegate FinishReorientation];
}
......
......@@ -131,6 +131,7 @@ NSInteger _forceInterfaceOrientationMask = 0;
UnitySetPlayerFocus(1);
#pragma mark - 1、解决手机开启静音模式下播放没有声音问题
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive: YES error: nil];
......@@ -387,6 +388,7 @@ extern "C" void UnityCleanupTrampoline()
_didResignActive = false;
}
#pragma mark - 2、自定义
// 创建原生页面和控件,自己控制唤起Unity时机
- (void)startSelfIOSView
{
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!