Unity項目集成到現(xiàn)有iOS項目
1.將Unity項目文件復制到到iOS項目跟目錄下
主要有5個文件业踢,Classes根竿,Data舰涌,Libraries猖任,MapFileParser,MapFileParser.sh瓷耙,(前三個是文件夾)朱躺。
2.在iOS項目中添加文件引用
(1)對Classes,Libraries搁痛,MapFileParser.sh添加
注意這里是在app的根目錄下长搀,右鍵“Add File to ...”
,選中三個文件(文件夾),記住在options里面勾選“Create groups”
鸡典,“Copy items if needed”
就不用選中了源请。
(2) 對Data添加
同樣是在app的根目錄下,右鍵添加文件彻况,選中Data文件夾谁尸,但是這里的options,是選“Create folder references”
疗垛,記住了症汹,別選錯。
完成這兩步之后贷腕,項目工程應該是這樣子背镇。
3.刪除項目文件.h文件咬展,跟libil2cpp的引用
(1)
在iOS項目中,找到Classes->Native
目錄瞒斩,將目錄下的.h
文件全部刪除引用破婆,注意只是.h
,因為里面還有.cpp
,這里只需要在Native
文件夾上右鍵選擇Sort by Type
就可以把.h
胸囱,.cpp
分開了祷舀。
。這里只是刪除引用烹笔,選擇這里面估計有幾千個文件慢慢等一下裳扯。
(2)
找到Libraries->libil2cpp
,刪除文件引用谤职,同上面選擇Remove References
4.對工程TARGETS進行配置饰豺。
note:這里的全部配置,其實都可以參考Unity導出的項目去配置的
(1)添加引用庫
注意有3個是選擇optional的允蜈。
(2)添加頭文件冤吨,庫搜索路徑
在項目TARGETS->Build Settings
搜索Search。
在Header Search Paths
下添加以下路徑
"$(SRCROOT)/Classes"
"$(SRCROOT)"
$(SRCROOT)/Classes/Native
$(SRCROOT)/Libraries/bdwgc/include
$(SRCROOT)/Libraries/libil2cpp/include
在Library Search Paths
下添加以下路徑
"$(SRCROOT)"
"$(SRCROOT)/Libraries"
$(SRCROOT)/Libraries/Plugins/iOS
(3)配置Other Linker Flags
在Other Linker Flags
下添加以下關鍵字:
-weak_framework
CoreMotion
-weak-lSystem
Note:當項目中集成了多個第三方庫的時候饶套,例如本次項目漩蟆,需要集成百度地圖SDK,兩個庫之間的文件妓蛮、文件內容可能有重復怠李,這時候就會出現(xiàn)duplicate symbol
的警報后來我找到了篇文章去解決。iOS 解決一個因三方靜態(tài)庫沖突產生的duplicate symbol的問題
(4)C仔引,C++扔仓,ObjC環(huán)境設置
這里的Prefix Header選擇自己項目的.pch文件距離,具體設置可以百度搜索咖耘。
(5)添加User-Defined設置
根據圖示
分別添加鍵值對翘簇。
GCC_THUMB_SUPPORT
-> NO
GCC_USE_INDIRECT_FUNCTION_CALLS
->NO
UNITY_RUNTIME_VERSION
->5.4.2f2
UNITY_SCRIPTING_BACKEND
->il2cpp
(6)添加Run Script
在Build Phases
頁面下左上角的加號,選擇New Run Script Phase
儿倒,然后在Run Script
進行配置.
Note:再說一遍版保,以上的所有項目TARGETS的配置,都可以在Unity導出的Xcode項目中參照著修改配置7蚍瘛3估纭!
5.文件配置和修改
(1)pch文件
在Classes
文件夾下凰慈,可以找到Prefix.pch
文件汞幢。如果你有自己的pch文件,那就可以把這個文件里面的全部內容復制到自己的.pch
文件里面微谓,如果你要使用它也可以森篷,那就在上面設置設置Prefix Header的時候設置好使用的文件路徑就好输钩。
(2)修改main文件
將Classes/
下的main.mm
文件里面的內容,全部復制到集成項目的Supporting Files/
下的main.m
文件中仲智,然后刪除Classes/main.mm
买乃,并且把文件后綴改成.mm
,。并且按照下圖對內容進行修改
(3)AppDelegate修改
AppDelegate.h
文件修改
#import <UIKit/UIKit.h>
#import "UnityAppController.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIWindow *unityWindow;
@property (strong, nonatomic) UnityAppController *unityController;
- (void)showUnityWindow;
- (void)hideUnityWindow;
@end
AppDelegate.m
文件修改
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(UIWindow *)unityWindow{
return UnityGetMainWindow();
}
-(void)showUnityWindow{
[self.unityWindow makeKeyAndVisible];
}
-(void)hideUnityWindow{
[self.window makeKeyAndVisible];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
_unityController = [[UnityAppController alloc] init];
[_unityController application:application didFinishLaunchingWithOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
[_unityController applicationWillResignActive:application];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
[_unityController applicationDidEnterBackground:application];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[_unityController applicationWillEnterForeground:application];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
[_unityController applicationDidBecomeActive:application];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[_unityController applicationWillTerminate:application];
}
@end
(4)UnityViewController修改
(1)
在Classes/
目錄下找到UnityAppController.h
文件钓辆,按照以下修改
將
inline UnityAppController* GetAppController()
{
return (UnityAppController*)[UIApplication sharedApplication].delegate;
}
修改成
#import "AppDelegate.h"
inline UnityAppController* GetAppController()
{
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
return delegate.unityController;
}
(2)如果有Main.storyboard就把它移除剪验。
6.啟動和隱藏Unity界面
//進入unity界面
[(AppDelegate *)[UIApplication sharedApplication].delegate showUnityWindow];
UnityPause(false);
//推出Unity界面
[(AppDelegate *)[UIApplication sharedApplication].delegate hideUnityWindow];
UnityPause(true);
7.問題收集
(1)在使用Unity攝像頭的時候黑屏
問題表現(xiàn)為,在使用Unity打包出來的項目運行是正常的前联,但是集合到現(xiàn)有項目的時候功戚,攝像頭顯示區(qū)域是黑屏。錯誤碼是:EasyAR is running on an unsupported graphics device of type -4
似嗤。
解決的方法:
1.在UnityAppController.h
中添加以下兩個方法
extern "C" void ezarUnitySetGraphicsDevice(void* device, int deviceType, int eventType);
extern "C" void ezarUnityRenderEvent(int marker);
2.在UnityAppController.mm
中添加這兩個方法
3.在UnityAppController.mm
實現(xiàn)以下方法
- (void)shouldAttachRenderDelegate
{
UnityRegisterRenderingPlugin(&ezarUnitySetGraphicsDevice, &ezarUnityRenderEvent);
}
(2)按照上文啟動Unity的窗口疫铜,后來我發(fā)現(xiàn),這個Unity的窗口其實在你主app窗口下面一直運行双谆,知道你第一次使用暫停,這里會使得手機發(fā)燙席揽,一直占用資源顽馋。
解決方法:
我在UnityAppController.mm
的- (void)startUnity:(UIApplication*)application
最后添加了UnityPause(true);
使得Unity在初始化完成之際,馬上停止界面幌羞,稍微對情況有所改善寸谜,如果有更好的方法,希望在下面留言属桦。