好長時間沒有寫了,一直忙沒來得及寫只泼,繼續(xù)把上篇已經(jīng)實現(xiàn)了將Unity導出的工程集成到原生iOS項目中了剖笙,接下來實現(xiàn)與Unity相互切換、調(diào)起辜妓、傳值。
需要注意的是,Unity一旦初始化籍滴,是不能關(guān)閉的酪夷,否則App直接就會被關(guān)閉。所以孽惰,一旦調(diào)起Unity晚岭,內(nèi)存就不會降下來了。第一次啟動會比較慢勋功,之后就很快了坦报。另外,集成Unity之后狂鞋,就只能真機運行了片择。
1、之前我們已經(jīng)在pch中import了UnityAppController骚揍,所以其他地方不用再import了字管。所有的接口建議寫在AppDelegate中。
首先信不,將AppDelegate.m改名為AppDelegate.mm 嘲叔,然后,在AppDelegate.h中,如下
#import <UIKit/UIKit.h>
@class UnityAppController;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIWindow *unityWindow;
@property (strong, nonatomic) UnityAppController *unityController;
- (void)showUnityWindow;
- (void)hideUnityWindow;
- (void)shouldAttachRenderDelegate;
@end
接下來抽活,修改AppDelegate.mm 如有報錯硫戈,先暫時忽略
#import "AppDelegate.h"
@interface AppDelegate ()
{
//這里的兩個BOOL,是用來區(qū)分下硕,是否第一次加載Unity丁逝,以及Unity視圖是否出現(xiàn)
BOOL _notFirstShow;
BOOL _isShowing;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
self.unityController = [[UnityAppController alloc]init];
[self.unityController application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)shouldAttachRenderDelegate {}
- (void)showUnityWindow {
if (!_notFirstShow) {
//第一次啟動
[self.unityController startUnityFirstTime];
_notFirstShow = YES;
} else {
//已經(jīng)初始化
[self.unityController startUnityOtherTime];
}
_isShowing = YES;
}
- (void)hideUnityWindow {
[self.unityController doExitSelector];
//看到這里就明白了,我用的是模態(tài)的方式展示的~哈哈哈
[self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
_isShowing = NO;
}
- (void)applicationWillResignActive:(UIApplication *)application {
[self.unityController applicationWillResignActive:application];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self.unityController applicationDidEnterBackground:application];
_backgroundView = [Util createSnapShotView];
[self.window addSubview:_backgroundView];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self.unityController applicationWillEnterForeground:application];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self.unityController applicationDidBecomeActive:application];
if (_backgroundView != nil) {
[_backgroundView removeFromSuperview];
_backgroundView = nil;
}
if (_notFirstShow && !_isShowing) {
//如果unity處于暫停狀態(tài)卵牍,從后臺喚醒時也要保持暫停狀態(tài)
[self.unityController doExitSelector];
}
}
- (void)applicationWillTerminate:(UIApplication *)application {
[self.unityController applicationWillTerminate:application];
}
@end
現(xiàn)在來修改UnityAppController.h,添加如下方法
//自定義開啟關(guān)閉Unity
- (void)startUnityFirstTime;
- (void)startUnityOtherTime;
- (void)doExitSelector;
找到下面這個方法
inline UnityAppController* GetAppController()
{
return (UnityAppController*)[UIApplication sharedApplication].delegate;
}
替換成如下
inline UnityAppController* GetAppController()
{
// return (UnityAppController*)[UIApplication sharedApplication].delegate;
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
return delegate.unityController;
}
接下來修改UnityAppController.mm
在它引用頭文件的最后一行果港,引入自定義控制器#import "GameViewController.h" 為了放unity,如果沒有糊昙,創(chuàng)建一個
接下來找到方法
- (void)shouldAttachRenderDelegate {}
實現(xiàn)這個方法
- (void)shouldAttachRenderDelegate {
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate shouldAttachRenderDelegate];
}
找到如下方法
- (void)applicationDidBecomeActive:(UIApplication*)application
{
::printf("-> applicationDidBecomeActive()\n");
[self removeSnapshotView];
if (_unityAppReady)
{
if (UnityIsPaused() && _wasPausedExternal == false)
{
UnityWillResume();
UnityPause(0);
}
UnitySetPlayerFocus(1);
}
else if (!_startUnityScheduled)
{
_startUnityScheduled = true;
[self performSelector: @selector(startUnity:) withObject: application afterDelay: 0];
}
_didResignActive = false;
}
改成如下
//首先在這個方法上面聲明一個bool變量
bool homePageEnable = true;
//修改這個方法
- (void)applicationDidBecomeActive:(UIApplication*)application
{
::printf("-> applicationDidBecomeActive()\n");
if(_snapshotView)
{
[_snapshotView removeFromSuperview];
_snapshotView = nil;
}
if (homePageEnable) {
homePageEnable = false;
[self performSelector:@selector(startHomePage:) withObject:application afterDelay:0];
}
if(_unityAppReady)
{
if(UnityIsPaused())
{
UnityPause(0);
UnityWillResume();
}
UnitySetPlayerFocus(1);
}
else if(!_startUnityScheduled)
{
_startUnityScheduled = true;
}
_didResignActive = false;
}
- (void)startHomePage:(UIApplication *)application {
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate.window makeKeyAndVisible];
}
- (void)startUnityFirstTime {
[self startUnity:[UIApplication sharedApplication]];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:[[GameViewController alloc] init] animated:YES completion:nil];
}
- (void)startUnityOtherTime {
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:[[GameViewController alloc] init] animated:YES completion:nil];
if (_didResignActive) {
UnityPause(false);
}
_didResignActive = false;
}
- (void)doExitSelector {
UnityPause(true);
_didResignActive = true;
Profiler_UninitProfiler();
}
接下來找到剛才創(chuàng)建的GameViewController.h
#import <UIKit/UIKit.h>
@interface GameViewController : UIViewController
@property (strong, nonatomic) UnityAppController *unityController;
@property (strong, nonatomic) UIWindow *unityWindow;
@end
然后在GameViewController.m中辛掠,導入#import "UnityAppController.h"
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:UnityGetMainWindow().rootViewController.view];
[self addChildViewController:UnityGetMainWindow().rootViewController];
}
接下來就是調(diào)起Unity、關(guān)閉Unity释牺、相互傳值(交互)
調(diào)起Unity:
調(diào)起是很方便的萝衩,因為是從原生跳轉(zhuǎn)過去,比如點擊某個按鈕没咙,那么只需在按鈕的點擊方法中調(diào)用就可以了:
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate showUnityWindow];
這樣就會模態(tài)出來Unity的界面
關(guān)閉Unity:
接下來是關(guān)閉Unity猩谊,對于返回原生,要在做處理的GameViewController這個方法里進行處理_BackBtnPress這個方法名是需要和unity那邊點擊方法名一致
void _BackBtnPress(){
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate hideUnityWindow];
}
傳值呢祭刚,很簡單牌捷,就一句話墙牌,Unity那邊做接收就可以了
//第一個參數(shù):消息的接受者,或者說誰來執(zhí)行方法
//第二個參數(shù):函數(shù)名
//第三個參數(shù):需要傳的值
UnitySendMessage("ReceiveiOSMessage", "ReceiveiOSInputMessage", _unityStr);
//注意暗甥,三個參數(shù)都是C語言字符串喜滨,沒有@哦
OK啦~~