最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)


0

  1. xCode9.0才支持swift4.0,但是9.0有一个bug,拖入的第三方库不会自动编译,详见XCode9 拖入文件 不自动添加 compile sources 所以使用9.1beta版本
    2.beta版每次添加framework要选两次才有用,暂时没有解决方法,官方也没有版本更新
    3.准备好一个xCode9.1和一个正常导出的Unity工程

Unity 工程导出时区分模拟器和真机,只能在对应设备运行,如果使用了AR,只能在真机上运行。
先单独运行下unity项目,模拟器版本会报UnityMetalSupport.h中有重复定义,直接注释报错代码即可,真机运行不报这个错误,然后能正常运行即可进行整合工作

1、新建工程

> 1.1 xCode9新建工程都是面向iOS11的,如果要兼容低版本系统,比如8.0,需要手动选择。
并且在LaunchScreen和main storyboard设置中去掉“Use Safe Area Layout Guides”(safe area 只支持9.0以后)
02safeArea.png

> 1.2 将Unity目录和工程目录放在同一文件夹内


01目录结构.png

> 1.3 右键——>创建Group without floder
(xCode9创建group新增了同时建立文件夹的选项,这里选择不建立文件夹)
命名为Unity(任意命名)

2、拖入Unity相关文件 放在新建的Unity Group下

classes和libraries  不copy 创建group
data    不copy 创建reference
raw 下的Vuforia和qcar也要放在根目录 同样选择reference
拖入交接文件和配置文件(也可以手动创建) 
最终目录见第四点添加配置图   

3、 桥接文件和配置文件

3.1 配置文件MyUnity.xcconfig
//
//  Created by 空橙记 on 2017/9/30.

GCC_THUMB_SUPPORT = NO
GCC_USE_INDIRECT_FUNCTION_CALLS = NO
// 版本号要改成对应
UNITY_RUNTIME_VERSION = 5.3.4f1
UNITY_SCRIPTING_BACKEND = il2cpp

CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES
CLANG_WARN_OBJC_ROOT_CLASS = YES

CLANG_CXX_LANGUAGE_STANDARD = c++0x
CLANG_CXX_LIBRARY = libc++
GCC_ENABLE_CPP_EXCEPTIONS = YES
GCC_C_LANGUAGE_STANDARD = c99
OTHER_CFLAGS = -DINIT_SCRIPTING_BACKEND=1
GCC_DYNAMIC_NO_PIC = NO
OTHER_LDFLAGS = -weak_framework CoreMotion -weak-lSystem
ENABLE_BITCODE = NO

// 要手动添加framework  头文件路径  库文件路径
//GCC_PREFIX_HEADER = $(UNITY_IOS_EXPORT_PATH)/Classes/Prefix.pch;

//改成自己对应的路径 导出的Unity路径
UNITY_IOS_EXPORT_PATH = /Users/xhvr/SWIFT/UnityMonis

a.事实上所有的setting都可以在这里设置,比如framework,也可以手动添加到OTHER_LDFLAGS中,头文件、库文件路径类似,但不是很推荐这么做
b.之前将所有framework都写在OTHER_LDFLAGS中,报了个错,Stack Overflow上说,又时候顺序也会造成link问题
c.另一个原因是不直观,例如再要引入地图、分享或者其他功能时,不知道哪些已经添加过,哪些没有添加
d.而像头文件路径、库文件路径,不同的Unity项目导出时文件夹有所不同,有些有plugins文件夹有些没有,手动加会直观些
f.如果觉得麻烦,自己的一些内容又是固定的,可以在Build Setting中设置好,直接command+c复制,command+v粘贴在config文件中,自己保存起来重复使用。

如果之前已经对某些配置做了修改,再配置config文件的话,并不会覆盖,所以比如使用百度地图, other linker flags 添加了-ObjC,那么config文件里配置不生效,需要删除-ObjC,此时配置会生效,再在最后加上-ObjC
如果出现RegisterAllClasses() in RegisterMonoModules.o 的报错,看看other c flags是不是添加了 -DINIT_SCRIPTING_BACKEND=1

3.2 UnityBridge.h 文件
#ifndef UnityBridge_h
#define UnityBridge_h

#import <UIKit/UIKit.h>
#import "UnityUtils.h"
#import "UnityAppController.h"
#import "UnityInterface.h"
#endif /* UnityBridge_h */
3.3 UnityUtils.h 文件 (添加了一个初始化方法)
#ifndef UnityUtils_h
#define UnityUtils_h
void unity_init(int argc, char* argv[]);
#endif /* UnityUtils_h */
3.4 UnityUtils.mm 文件
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <csignal>
#import <UIKit/UIKit.h>

static const int constsection = 0;
void UnityInitTrampoline();

extern "C" void unity_init(int argc, char* argv[])
{
    @autoreleasepool
    {
        UnityInitTrampoline();
// Unity版本不同,有些可能要选UnityInitRuntime的方法
//        UnityInitRuntime(argc, argv);
        UnityParseCommandLine(argc, argv);
        
        RegisterMonoModules();
        NSLog(@"-> registered mono modules %p\n", &constsection);
        RegisterFeatures();
        std::signal(SIGPIPE, SIG_IGN);
    }
}

以上有报错不用管,先放着
设置Objective-C Bridging Header 为UnityBridge.h文件

06桥接bridge.png

4、修改配置

info处添加MyUnity.xcconfig

03添加配置.png

设置Unity文件夹路径
04Unity文件夹路径.png

设置prefix文件路径
07prefix.png

添加头文件路径和库文件路径
08头文件.png

09库文件.png

添加framework

10framework.png

路径都是可以直接拖的
framework的bug上面说过,就是要选两次

5、创建main.swift

内容如下

import Foundation
import UIKit
// 这个方法名要和UnityUtils中的相同
unity_init(CommandLine.argc, CommandLine.unsafeArgv)
UIApplicationMain(
    CommandLine.argc,
    UnsafeMutableRawPointer(CommandLine.unsafeArgv)
        .bindMemory(
            to: UnsafeMutablePointer<Int8>.self,
            capacity: Int(CommandLine.argc)),
    nil,
    NSStringFromClass(AppDelegate.self)
)

注释Appdelegate.swift中的 @UIApplicationMain

6、其他文件修改

  1. 找到Unity中的main.mm文件,注释main方法
  1. 在UnityAppController.h中替换inline方法
//替换为此方法
NS_INLINE UnityAppController* GetAppController()
{
    NSObject<UIApplicationDelegate>* delegate = [UIApplication sharedApplication].delegate;
    // 这里的@字符串 要和Appdelegate.swift中的变量名一致
    UnityAppController* currentUnityController = (UnityAppController *)[delegate valueForKey:@"unityController"];
    return currentUnityController;
}
  1. 修改AppDelegate
//@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    var unityController: UnityAppController?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        unityController = UnityAppController()
        unityController?.application(application, didFinishLaunchingWithOptions: launchOptions)
        return true
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
        unityController?.applicationWillResignActive(application)
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
        unityController?.applicationDidEnterBackground(application)
    }
    
    func applicationWillEnterForeground(_ application: UIApplication) {
        unityController?.applicationWillEnterForeground(application)
    }
    
    func applicationDidBecomeActive(_ application: UIApplication) {
        unityController?.applicationDidBecomeActive(application)
    }
    
    func applicationWillTerminate(_ application: UIApplication) {
        unityController?.applicationWillTerminate(application)
    }
}

7.使用

创建一个新的ViewController 或者在ViewController中也可以
使用AR需要添加相机权限
在viewDidLoad()中直接添加
self.view.addSubView(UnityGetGLView())
如果不要全屏,可以手动设置frame

8.bug

在buildSetting中设置swift版本如果是3.2,能正常运行没有任何问题,如果设置4.0会报
valueForUndefinedKey的错误。解决很简单,在appdelegate中加上@objc 即可
    @objc var unityController: UnityAppController?

如果Unity版本比较低,可能会遇到xxx was compiled with optimization - stepping may behave oddly; variables may not be available的问题,请在building setting-> Other C Flags 中添加:-DRUNTIME_IL2CPP=1,前面加的也要保留。然后把Optimization Level ,debug的部分都改成none。
参考: https://stackoverflow.com/questions/45078851/optimization-stepping-may-behave-oddly-ios-unity

参考:童冀的2.3融合教程
swift3.0融合Unity
的一部分内容,不过还是得说一下,原文中很多步骤是不需要的,例如添加脚本、例如main.mm中main方法的替换(直接注释即可,参见下面matt_eaton博客内容)。而有些方法已经不适用,例如main.swift中的UIApplicationMain方法,原文中的会报错。
blitzagency的教程以及一些文件
matt_eaton 的一篇博客
swift4.0 整合Unity报错问题

内容不算很难,但是xCode9的坑有点多,尤其不能自动编译第三方库,测试了好久。然后9.1的framework添加两次。。。以及safe area设置等等,在整合前花了太多时间处理IDE的问题。

参照阅读之前写的xCode8.3 + OC +Unity教程
对照一下,可以理解得更清楚一些。

如果文章有所帮助,欢迎打赏😄


😄.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容