0
- 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以后)
> 1.2 将Unity目录和工程目录放在同一文件夹内
> 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
#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
#import
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文件
4、修改配置
info处添加MyUnity.xcconfig
设置Unity文件夹路径
设置prefix文件路径
添加头文件路径和库文件路径
添加framework
路径都是可以直接拖的
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.self,
capacity: Int(CommandLine.argc)),
nil,
NSStringFromClass(AppDelegate.self)
)
注释Appdelegate.swift中的 @UIApplicationMain
6、其他文件修改
- 找到Unity中的main.mm文件,注释main方法
- 在UnityAppController.h中替换inline方法
//替换为此方法
NS_INLINE UnityAppController* GetAppController()
{
NSObject* delegate = [UIApplication sharedApplication].delegate;
// 这里的@字符串 要和Appdelegate.swift中的变量名一致
UnityAppController* currentUnityController = (UnityAppController *)[delegate valueForKey:@"unityController"];
return currentUnityController;
}
- 修改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教程
对照一下,可以理解得更清楚一些。
如果文章有所帮助,欢迎打赏