voshk

Unity3D导出iOS项目编译Framework踩坑之旅

2019/06/24 Share

业务需求需要把Unity3D制作的3D效果与现有native iOS项目结合实现3D效果。

实现方案

将Unity3D生成的iOS项目与现有native项目融合

调研了目前主流都使用这种方式,各种教程也都千篇一律,都是无脑拷贝,一大堆的导这导那,改这改那,然而目前的native项目复杂度比较高,项目也做了好久了,功能比较多,这种做法对现有项目侵入性太高,看着就难受,放弃。

将Unity3D生成的iOS项目制作Framework

其实一开始就想用这种方式,只是用Unity导出iOS项目之后,看到里面有.main文件还有.pch等有了退缩,就又想了上面的方案,还好及时回头是岸。

直观上来讲这种方案优势很明显:非常友好,一次配置,以后Unity项目有更新,只需要更新把Unity生成的文件放到已经配置好的framework项目,重新build下,另外更新下Unity对应的Data即可,省时省力,一些改动对Native项目也没什么感知。

制作Unity Framework

首先确保Unity导出的iOS项目是可以正常编译的

制作framework也分两种方式:1.直接新建个framework把Unity导出的iOS项目中的Classes和Libraries、Data文件对应拖入新建的framework project,再进行接下来的配置;2.直接在Unity导出的iOS项目中操作,新建个framwork类型的target,在target基础上进行操作。

File - new - target - cocoa touch framework - unity framework

各种设置为了让target可以编译成功

这部分的配置,网上一搜一大把,简单列举下:

1
2
3
4
5
6
7
8
Build Settings -> Header Search Paths: $(inherited) "$(SRCROOT)/Classes" "$(SRCROOT)" $(SRCROOT)/Classes/Native $(SRCROOT)/Libraries/bdwgc/include $(SRCROOT)/Libraries/libil2cpp/include
Build Settings -> Library Search Paths: $(inherited) "$(SRCROOT)" "$(SRCROOT)/Libraries"
Build Settings -> Prefix Header: Classes/Prefix.pch
Build Settings -> Mismatched Return Type: Yes
Build Settings -> Enable C++ Exceptions: Yes
Build Settings -> Other Linker Flags: $(inherited) -weak_framework CoreMotion -weak-lSystem
Build Settings -> Mach-O Type: Static Library
Build Settings -> Other C Flags 添加 -DINIT_SCRIPTING_BACKEND=1 -fno-strict-overflow -DRUNTIME_IL2CPP=1

但是Unity工具更新了,以及Unity和Xcode的版本不同,新版本打包导出的工程不一样了,会出现各种各样的报错。

以下列举本人在踩坑过程中遇到的报错信息及解决方式:

  • 出现多处”nomember xxx in xxx”类似的系统线程错误

顺着报错的点一路追踪到cpp代码,发现共同点都是在一个判断.net 4.0版本的宏定义,联想到c flag的设置可以设置多种参数是不是有.net相关的?

这是因为.net升级为4.0版本,导致的。

打开项目build setting 搜索 other C flags 看看是不是少加了这个 -DNET_4_0

问题解决。

  • “Please include Preprocessor.h before other includes”

提示Preprocessor.h的定义应该在最前面,但是明明已经是最前面了,不明所以,直接注释掉这三行代码,问题解决。

1
2
3
4
5
6
7
// "Please include Preprocessor.h before other includes"

#if defined(CABASE_H)
#error "Please include Preprocessor.h before other includes"
#endif

直接把这三行代码注释掉啊
  • Undefined symbols for architecture armv7:

    1
    2
    3
    4
    5
     Undefined symbols for architecture armv7:
    "_OBJC_CLASS_$_AVPlayerViewController", referenced from:
    objc-class-ref in UnityFramework(FullScreenVideoPlayer.o)
    ld: symbol(s) not found for architecture armv7
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

targets - build phase - Link Binary 添加AVKit.framework 问题解决。

总结

Unity这东西坑还是很多的,网上很多的资料都是Unity以及Xcode比较老的版本,之前可以成功实现的方案,在目前来看可能会有各种各样莫名奇怪的问题,针对每个报错的点,耐心去查找相关资料,总是会解决的。

我用的Unity版本目前是最新的2019.2.1(Unity 2019.2.1f1) Xcode对应版本为10.3。

后续

  1. 把各种繁琐的配置形成脚本,自动化去处理
  2. 接下来会进行oc与unity互调交互的研究

大家在实现过程如果有什么问题可以评论提出来,我们集思广益,共同去解决。