最近公司需要开发AR项目,在网上找来Unity项目研究了一下,用Unity生成iOS项目后需要导入到自己已有的项目中,步骤如下:
导入Unity项目文件
我们之前生成的Unity项目是这样的,我们需要导入的文件如下图标注
项目目录
-
1.将Classes和Libraries文件以及Frameworks里面的Vuforia.framework 导入到我们项目,导入方式如下
-
2 将Data文件导入,导入方式如下
-
3.将 Data / Raw 文件夹内的Vuforia文件夹按步骤二添加到如下位置
-
4.将Classes目录下的main.mm 内容复制到自己项目中的 main.m 中,然后把main.m后缀改为.mm变成main.mm,删除导入Classes文件下的main.mm,修改后main.mm文件代码如下
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <csignal>
static const int constsection = 0;
void UnityInitTrampoline();
// WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its value)
const char* AppControllerClassName = "ViewController";
int main(int argc, char * argv[]) {
UnityInitStartupTime();
@autoreleasepool {
UnityInitTrampoline();
UnityInitRuntime(argc, argv);
RegisterMonoModules();
// NSLog(@"-> registered mono modules %p\n", &constsection);
RegisterFeatures();
// iOS terminates open sockets when an application enters background mode.
// The next write to any of such socket causes SIGPIPE signal being raised,
// even if the request has been done from scripting side. This disables the
// signal and allows Mono to throw a proper C# exception.
std::signal(SIGPIPE, SIG_IGN);
// return UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
-
5.在build Setting --> other Link Flags 做如下修改:
-weak_framework
CoreMotion
-weak-lSystem
-
6.在build Setting --> Header Search Paths 下做如下修改:
//具体根据文件目录而定
"$(SRCROOT)/BuddhaARDemo"
"$(SRCROOT)/BuddhaARDemo/Classes"
"$(SRCROOT)/BuddhaARDemo/Classes/Native"
"$(SRCROOT)/BuddhaARDemo/Libraries"
"$(SRCROOT)/BuddhaARDemo/Libraries/libil2cpp/include"
-
7.在build Setting --> Other C Flags 做如下修改:
-DINIT_SCRIPTING_BACKEND=1
-fno-strict-overflow
-DRUNTIME_IL2CPP=1
-
8.在build Setting --> Precompile Prefix Header 做如下修改(这里使用的是Unity项目中的pch文件,如BuddhaARDemo已有pch文件,需合并pch文件):
Precompile Prefix Header
-
9.在build Setting 中做如下操作
GCC_THUMB_SUPPORT:NO
GCC_USE_INDIRECT_FUNCTION_CALLS:NO
UNITY_RUNTIME_VERSION:2018.2.9f1 <--这个值根据自己unity-demo来
UNITY_SCRIPTING_BACKEND: il2cpp
效果如下
-
10. build Setting --> bitcode关闭
-
11. 添加Unity项目相关依赖库,如下两处需选择Optional,否则编译会报不必要的错误(具体根据你自己的Unity项目来)
-
12.在BuddhaARDemo的AppDelegate项目中写入以下代码
AppDelegate.h:
#import <UIKit/UIKit.h>
@class VTUnityController;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic , strong)UIWindow *unityWindow;
@property (nonatomic, strong) VTUnityController *unityController;
- (void)showUnityWindow;
- (void)hideUnityWindow;
@end
AppDelegate.mm:
#import "AppDelegate.h"
#import "VTUnityController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if (_unityController == nil) {
_unityController = [[VTUnityController alloc]init];
}
return YES;
}
- (UIWindow *)unityWindow
{
if (!_unityWindow) {
if (!UnityGetMainWindow()) {
_unityWindow = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
}else{
_unityWindow = UnityGetMainWindow();
}
}
return _unityWindow;
}
- (void)showUnityWindow
{
[self.unityWindow makeKeyAndVisible];
}
- (void)hideUnityWindow
{
[self.window makeKeyAndVisible];
[self.unityController pauseUnity];
}
@end
-
13. 新建VTUnityController类,继承自UnityAppController
VTUnityController.h
#import "UnityAppController.h"
NS_ASSUME_NONNULL_BEGIN
@interface VTUnityController : UnityAppController
+ (instancetype)instance;
- (void)initUnity;
- (void)pauseUnity;
- (void)startUnity1;
- (BOOL)isPaused;
@end
NS_ASSUME_NONNULL_END
VTUnityController.m
#import "VTUnityController.h"
//#import "UnityAppController.h"
#import "UnityAppController+ViewHandling.h"
#import "UnityAppController+Rendering.h"
#import "DisplayManager.h"
#import "UnityView.h"
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
//#include <csignal>
#import "AppDelegate.h"
@interface VTUnityController()
@property (nonatomic, assign) BOOL isInitUnity;
@end
@implementation VTUnityController
+ (instancetype)instance {
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
return delegate.unityController;
}
- (instancetype)init
{
self = [super init];
if (self) {
self.isInitUnity = NO;
// 注册Unity
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
}
return self;
}
void UnityInitTrampoline();
- (void)initUnity {
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
if (!self.isInitUnity) {
[super applicationDidBecomeActive:[UIApplication sharedApplication]];
UnityInitApplicationNoGraphics([[[NSBundle mainBundle] bundlePath] UTF8String]);
[self selectRenderingAPI];
[UnityRenderingView InitializeForAPI: self.renderingAPI];
_window = delegate.unityWindow;
_unityView = [self createUnityView];
[DisplayManager Initialize];
_mainDisplay = [DisplayManager Instance].mainDisplay;
[_mainDisplay createWithWindow: _window andView: _unityView];
[self createUI];
[self preStartUnity];
self.isInitUnity = YES;
_unityView.back = ^{
[delegate hideUnityWindow];
};
}else{
[self startUnity1];
}
[delegate showUnityWindow];
}
- (void)pauseUnity {
UnitySendMessage("ARCamera", "Exit", ""); // 调Unity方法 退出模型 (与unity交互)
UnityPause(1);
}
- (void)startUnity1 {
UnityPause(0);
}
- (BOOL)isPaused {
if (UnityIsPaused() == 1) {
return YES;
}
else {
return NO;
}
}
-(void)applicationDidFinishLaunching:(UIApplication *)application{
}
- (void)appWillEnterForeground:(NSNotification *)notification {
[super applicationWillEnterForeground:[UIApplication sharedApplication]];
}
- (void)appDidBecomeActive:(NSNotification *)notification {
if (nil == self.unityView) {
return;
}
[super applicationDidBecomeActive:[UIApplication sharedApplication]];
}
- (void)appWillResignActive:(NSNotification *)notification {
[super applicationWillResignActive:[UIApplication sharedApplication]];
}
- (void)appWillTerminate:(NSNotification *)notification {
[super applicationWillTerminate:[UIApplication sharedApplication]];
}
- (void)appDidReceiveMemoryWarning:(NSNotification *)notification {
[super applicationDidReceiveMemoryWarning:[UIApplication sharedApplication]];
}
@end
-
14. 在需要的地方开启UnityAR
- (void)startAR {
VTUnityController *vc = [VTUnityController instance];
[vc initUnity];
}
网友评论