Unity项目集成到现有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,两个库之间的文件、文件内容可能有重复,这时候就会出现duplicate symbol
的警报后来我找到了篇文章去解决。iOS 解决一个因三方静态库冲突产生的duplicate symbol的问题
(4)C,C++,ObjC环境设置
这里的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项目中参照着修改配置!!!
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摄像头的时候黑屏
问题表现为,在使用Unity打包出来的项目运行是正常的,但是集合到现有项目的时候,摄像头显示区域是黑屏。错误码是: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
实现以下方法
- (void)shouldAttachRenderDelegate
{
UnityRegisterRenderingPlugin(&ezarUnitySetGraphicsDevice, &ezarUnityRenderEvent);
}
(2)按照上文启动Unity的窗口,后来我发现,这个Unity的窗口其实在你主app窗口下面一直运行,知道你第一次使用暂停,这里会使得手机发烫,一直占用资源。
解决方法:
我在UnityAppController.mm
的- (void)startUnity:(UIApplication*)application
最后添加了UnityPause(true);
使得Unity在初始化完成之际,马上停止界面,稍微对情况有所改善,如果有更好的方法,希望在下面留言。