AR窗口与Window切换处理

最近做的一个项目需要AR模块,具体功能就是用户到一个地方后,拿起手机切换到AR窗口会有活动图标。点击图标然后跳转到新的页面。比如图片浏览,视频播放,领取红包功能。当然今天不会写这些的具体的功能及如何整合。主要还是说下窗口来回切换的问题及处理方法。

其实当应用启动时 ,AR的窗口已经在运行了。其实就是切换window的rootView。

入口类处理

AppDelegate.h

1
2
@property (strong, nonatomic) UIWindow *unityWindow;
@property (strong, nonatomic) UnityAppController *unityController;

AppDelegate.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-(UIWindow *)unityWindow{

return UnityGetMainWindow();
}

-(void)showUnityWindow{

[[UIApplication sharedApplication] setStatusBarHidden:YES];
self.unityWindow.hidden = NO;

[self.unityWindow makeKeyAndVisible];
}

-(void)hideUnityWindow{

[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
self.unityWindow.hidden = YES;
[self.window makeKeyAndVisible];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//添加如下代码
BOOL returnBool;
if (_unityController == nil) {

_unityController = [[UnityAppController alloc] init];
}

returnBool = [_unityController application:application didFinishLaunchingWithOptions:launchOptions];

}

创建一个单利类,管理切换标识控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@interface SendInfoARManager : NSObject
/** 是否暂停Unity */
@property (assign, nonatomic) BOOL unityIsPaused;
@property (strong,nonatomic) NSTimer *timer;
+ (instancetype)sharedInstance;
@end

@implementation SendInfoARManager

+ (instancetype)sharedInstance
{
static LARManager *manager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[self alloc] init];
});
return manager;
}

- (instancetype)init
{
if (self = [super init]) {
self.unityIsPaused = NO;
NSLog(@"单例初始化成功");
}
return self;
}


@end

UnityAppController.h

我把整个代码都贴下,怎么修改对照比对下就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#pragma once

#import <QuartzCore/CADisplayLink.h>

#include "PluginBase/RenderPluginDelegate.h"

@class UnityView;
@class UnityViewControllerBase;
@class DisplayConnection;

@interface UnityAppController : NSObject<UIApplicationDelegate>
{
UnityView* _unityView;
CADisplayLink* _displayLink;

UIWindow* _window;
UIView* _rootView;
UIViewController* _rootController;
UIView* _snapshotView;

DisplayConnection* _mainDisplay;

// we will cache view controllers for fixed orientation
// auto-rotation view contoller goes to index=0
UIViewController* _viewControllerForOrientation[5];
#if !UNITY_TVOS
UIInterfaceOrientation _curOrientation;
#endif

id<RenderPluginDelegate> _renderDelegate;
}

// override it to add your render plugin delegate
- (void)shouldAttachRenderDelegate;

// this one is called at the very end of didFinishLaunchingWithOptions:
// after views have been created but before initing engine itself
// override it to register plugins, tweak UI etc
- (void)preStartUnity;

// this one is called at first applicationDidBecomeActive
// NB: it will be started with delay 0, so it will run on next run loop iteration
// this is done to make sure that activity indicator animation starts before blocking loading
- (void)startUnity:(UIApplication*)application;


- (void)startLocation;

// this is a part of UIApplicationDelegate protocol starting with ios5
// setter will be generated empty
@property (retain, nonatomic) UIWindow* window;


@property (strong, nonatomic) UILabel *loclab;
@property (strong, nonatomic) UIButton *mapBtn;

@property (strong, nonatomic) UIViewController *vc;
@property (strong, nonatomic) NSDictionary *scenicPoints;



@property (readonly, copy, nonatomic) UnityView* unityView;
@property (readonly, copy, nonatomic) CADisplayLink* unityDisplayLink;

@property (readonly, copy, nonatomic) UIView* rootView;
@property (readonly, copy, nonatomic) UIViewController* rootViewController;
@property (readonly, copy, nonatomic) DisplayConnection* mainDisplay;

#if !UNITY_TVOS
@property (readonly, nonatomic) UIInterfaceOrientation interfaceOrientation;
#endif

@property (nonatomic, retain) id renderDelegate;
@property (nonatomic, copy) void(^quitHandler)();

@end

// Put this into mm file with your subclass implementation
// pass subclass name to define

#define IMPL_APP_CONTROLLER_SUBCLASS(ClassName) \
@interface ClassName(OverrideAppDelegate) \
{ \
} \
+(void)load; \
@end \
@implementation ClassName(OverrideAppDelegate) \
+(void)load \
{ \
extern const char* AppControllerClassName; \
AppControllerClassName = #ClassName; \
} \
@end \

//inline UnityAppController* GetAppController()
//{
// return (UnityAppController*)[UIApplication sharedApplication].delegate;
//}

inline UnityAppController* GetAppController()
{
return (UnityAppController*)[[UIApplication sharedApplication] valueForKeyPath:@"delegate.unityController"];
}
#define APP_CONTROLLER_RENDER_PLUGIN_METHOD(method) \
do { \
id<RenderPluginDelegate> delegate = GetAppController().renderDelegate; \
if([delegate respondsToSelector:@selector(method)]) \
[delegate method]; \
} while(0)

#define APP_CONTROLLER_RENDER_PLUGIN_METHOD_ARG(method, arg) \
do { \
id<RenderPluginDelegate> delegate = GetAppController().renderDelegate; \
if([delegate respondsToSelector:@selector(method:)]) \
[delegate method:arg]; \
} while(0)



// these are simple wrappers about ios api, added for convenience
void AppController_SendNotification(NSString* name);
void AppController_SendNotificationWithArg(NSString* name, id arg);

void AppController_SendUnityViewControllerNotification(NSString* name);

UnityAppController.m

主要修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- (void)startUnity:(UIApplication*)application
{
//这个地方是主要的处理逻辑
if ([SendInfoARManager sharedInstance].unityIsPaused) {
UnityPause(false);
[SendInfoARManager sharedInstance].unityIsPaused = NO;
NSLog(@"设置rootView为Unity界面");
self.window.rootViewController = self.rootViewController;
return ;
}

NSAssert(_unityAppReady == NO, @"[UnityAppController startUnity:] called after Unity has been initialized");

UnityInitApplicationGraphics();

// we make sure that first level gets correct display list and orientation
[[DisplayManager Instance] updateDisplayListInUnity];

UnityLoadApplication();
Profiler_InitProfiler();

[self showGameUI];
[self createDisplayLink];

UnitySetPlayerFocus(1);
UnityPause(true); //解决手机发烫临时补救措施
[UIApplication sharedApplication].idleTimerDisabled=NO;//自动锁屏

}

最终切换实现

显示AR

1
2
3
4
5

//进入unity界面
AppDelegate *app = (AppDelegate*)[UIApplication sharedApplication].delegate;
[app showUnityWindow];
UnityPause(false);

隐藏AR界面

1
2
3
4
5
[SendInfoARManager sharedInstance].unityIsPaused = YES;
UnityPause(true);
AppDelegate *app = (AppDelegate*)[UIApplication sharedApplication].delegate;
[app hideUnityWindow];
app.window.rootViewController = "你的原始窗口根控制器";

将u3d工程与自己工程整合的相关链接

http://www.jianshu.com/p/487015f3bb13

http://www.qingpingshan.com/rjbc/ios/187333.html