iOS精华文章iOS技术专题

iOS项目集成unity工程

2017-10-12  本文已影响389人  野生塔塔酱

unity版本 2017.1.1f1 Xcode版本8.2.1 (8C1002)


第一步

导出unity的Xcode工程(具体导出设置可以看文章末尾的链接大多数都有讲到设置) 此时需要注意的是

第二步

将导出的unity工程中的以下四个文件导入到你的项目中 (如果是旧版unity可能还有一个MapFileParser文件)

unity文件.png
注意 千万不要选错导入方式

第三步

第四步

工程配置

  1. 关闭bitcode。(已经关闭的可以忽略)新版的Unity已经支持Bitcode但你unity项目中的某些SDK可能并不支持,不关闭无法正常编译。
  2. 添加 Build SettingsHeader Search PathsLibrary Search Paths
$(SRCROOT)/Smart_ticket_iOS/Classes
$(SRCROOT)/Smart_ticket_iOS/Classes/Native
$(SRCROOT)/Smart_ticket_iOS/Libraries/libil2cpp/include
$(SRCROOT)/Smart_ticket_iOS/Libraries
$(SRCROOT)/Smart_ticket_iOS

Library Search Paths应该添加

$(PROJECT_DIR)/Smart_ticket_iOS/Libraries
$(PROJECT_DIR)/Smart_ticket_iOS/Libraries/Plugins/iOS
$(PROJECT_DIR)/Smart_ticket_iOS/

如果unity的文件放在项目根目录 那就应该添加

$(SRCROOT)/Classes
$(SRCROOT)/Classes/Native
$(SRCROOT)/Libraries/libil2cpp/include
$(SRCROOT)/Libraries
$(SRCROOT)
$(PROJECT_DIR)/Libraries
$(PROJECT_DIR)/Libraries/Plugins/iOS
$(PROJECT_DIR)
  1. Build Settings->Other C Flags添加-DINIT_SCRIPTING_BACKEND=1 如果无效可以尝试把这个值移到最上面
  1. 添加自定义设置
UNITY_RUNTIME_VERSION -> xxx(你导出的unity项目中对应的版本号)
UNITY_SCRIPTING_BACKEND -> il2cpp

MTL_ENABLE_DEBUG_INFO -> NO (这个是本来就有的修改就行)
GCC_THUMB_SUPPORT NO 
GCC_USE_INDIRECT_FUNCTION_CALLS NO 
  1. 将iOS原生项目中的pch文件合并到Classes/Prefix.pch中,并且在Build Settings->Prefix Header中设置路径(如果没有就不做合并但是仍然要设置unity项目的pch路径)

否则放外面的话会报unknown type name 'NSString'之类的错
  1. 复制unity项目文件夹Classes中的main.mm文件中的代码(所有),删除你原生项目的main.m中的代码(除了最开始的头文件引用部分),将复制的内容粘贴到原生项目的main.m中,删除main.mm,修改main.m为main.mm(此时如果编译成功运行的时候进入的是unity页面 没有走我们原生的AppDelegate)
  1. 修改启动函数(从我们自己的AppDelegate启动)在修改后的main.mm中
找到
UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);
将之修改为
UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

此时再启动的话就是走我们原来的AppDelegate了

  1. 添加跳转unity页面的功能
    修改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中添加或修改

- (UIWindow *)unityWindow{
    
    return UnityGetMainWindow();
    
}

- (void)showUnityWindow{
    
    if (_isFirstShowUnity) {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.frame = CGRectMake(15, 25, 20, 40);
        [btn setImage:[UIImage imageNamed:@"返回"] forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(hideUnityWindow) forControlEvents:UIControlEventTouchUpInside];
        [self.unityWindow addSubview:btn];
        _isFirstShowUnity = NO;
    }
    
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    
   UnityPause(0);
    
    [self.unityWindow makeKeyAndVisible];
    
}

- (void)hideUnityWindow{
    [[UIApplication sharedApplication] setStatusBarHidden:NO];
    
    UnityPause(1);
    
    [self.window makeKeyAndVisible];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    在你的原有基础上 return YES 之前 添加
    self.unityController = [[UnityAppController alloc] init];
    [self.unityController application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)applicationWillResignActive:(UIApplication *)application {
    [self.unityController applicationWillResignActive:application];
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    [self.unityController applicationDidEnterBackground:application];
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    [self.unityController applicationWillEnterForeground:application];
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    [self.unityController applicationDidBecomeActive:application];
}


- (void)applicationWillTerminate:(UIApplication *)application {
    [self.unityController applicationWillTerminate:application];
}

在导入的unity文件夹Classes/UnityAPPController.h中找到

记得 #import "AppDelegate.h"
inline UnityAppController*  GetAppController()
{
//    return (UnityAppController*)[UIApplication sharedApplication].delegate;原有的 注释掉
    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    return delegate.unityController;
---------如果上面的报错 换下面的写法
    return (UnityAppController*)[[UIApplication sharedApplication] valueForKeyPath:@"delegate.unityController"];
}

然后在需要调用unity的地方调用方法切换成unity页面

AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate showUnityWindow];

遇到的坑

Undefined symbols for architecture arm64:
  "_glStateCacheTexEnvCombine", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheTexEnvSrc1", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheEnableTex2D", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheEnableClientStateTexCoordArray", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheTexEnvMode", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheDisableTex2D", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheEnableClientStateVertexArray", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheClientActiveTexture", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheDisableDepthTest", referenced from:
      _arglDispImage in libHiARWrapper.a(gsub_es.o)
  "_glStateCachePixelStoreUnpackAlignment", referenced from:
      _arglPixelFormatSet in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheBindTexture2D", referenced from:
      _arglPixelFormatSet in libHiARWrapper.a(gsub_es.o)
      _arglCleanup in libHiARWrapper.a(gsub_es.o)
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
      _arglPixelBufferDataUploadBiPlanar in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheDisableLighting", referenced from:
      _arglDispImage in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheTexEnvSrc0", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheDisableClientStateNormalArray", referenced from:
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
  "_glStateCacheActiveTexture", referenced from:
      _arglPixelFormatSet in libHiARWrapper.a(gsub_es.o)
      _arglCleanup in libHiARWrapper.a(gsub_es.o)
      _arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
      _arglPixelBufferDataUploadBiPlanar in libHiARWrapper.a(gsub_es.o)
ld: symbol(s) not found for architecture arm64

这种unity里面静态库的错误的话 可以尝试修改Build Settings->Enable Testability为NO 我的项目中就遇到了这个坑 无论怎么改都是报这个错(应该是因为AR的SDK) 后来才发现导出的项目中这个值是NO我的原生项目中这个是YES

duplicate symbol xxx in:

这种库冲突 可以看看你是否在Build Settings->Other Linker Flag中添加了-force_load 提及冲突的库 把冲突的项删除了

[_unityController Paused];
[_unityController setPaused:NO];//判断unity控制器的状态和改变状态
但是我的项目中就没有 取而代之的是
if (UnityIsPaused() == 1) {//判断状态 1暂停 0运行中
        UnityPause(0);//激活unity控制器 0激活 1暂停
}

参考文档
http://blog.csdn.net/dylan_lwb_/article/details/51452470
http://www.jianshu.com/p/f98bcfe09dc7
http://www.jianshu.com/p/6ddc80cfa3fc
http://www.jianshu.com/p/3d9ae5244d82
http://blog.csdn.net/qinqi376990311/article/details/72303053
http://blog.sina.com.cn/s/blog_48a8af640102vh2q.html

上一篇 下一篇

猜你喜欢

热点阅读