最新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以后)
最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第1张图片
02safeArea.png

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


最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第2张图片
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 
#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文件

最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第3张图片
06桥接bridge.png

4、修改配置

info处添加MyUnity.xcconfig

最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第4张图片
03添加配置.png

设置Unity文件夹路径
最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第5张图片
04Unity文件夹路径.png

设置prefix文件路径
最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第6张图片
07prefix.png

添加头文件路径和库文件路径
最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第7张图片
08头文件.png

最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第8张图片
09库文件.png

添加framework

最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第9张图片
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.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* 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教程
对照一下,可以理解得更清楚一些。

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


最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4)_第10张图片
.png

你可能感兴趣的:(最新iOS 整合Unity(xCode9.1 Swift4.0 Unity5.4))