Swift 3.0 项目集成EasyAR Unity 2.0 SDK

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第1张图片

前言
公司需要在原先Swift 3.0项目中引入EasyAR 的Unity SDK。这篇文章记录了集成过程和遇到的问题。
开发环境:macOS 10.12.5, iOS 8,Xcode 8.3.3,Unity 5.6.1f1

准备工作

1.导出Unity工程

导出Unity工程时的设置

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第2张图片
导出Unity工程时的设置

2.新建空的Swift项目

新建一个空的Swift项目,再建立一个UnityFix文件夹,用于存放Unity文件。

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第3张图片
建立UnityFix文件夹

项目设置

1.将下载得到的Unity.xconfig、UnityBridge.h、UnityUtils.h和UnityUtils.mm这4个文件复制到UnityFix中。点这里下载

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第4张图片
导入Unity配置文件

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第5张图片
导入Unity配置文件

导入过程中,Xcode会讯问是否生成桥接文件。这里我们选择不生成桥接文件
2.设置使用Unity的配置
Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第6张图片
设置使用Unity的配置

3.修改BuildSetting配置,Unity路径和Unity版本号
Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第7张图片
BuildSetting配置

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第8张图片
设置路径

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第9张图片
设置路径

4.在BuildPhases中添加运行脚本

rm -rf "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data";
cp -Rf "$UNITY_IOS_EXPORT_PATH/Data" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data";
Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第10张图片
设置运行脚本

代码整合

1.修改UnityUtils.mm中的代码

//用下列代码替换原代码
extern "C" int custom_unity_init(int argc, char* argv[])
{
    @autoreleasepool
    {
        UnityInitTrampoline();
        //这行代码不注释,可能会报错
        //        UnityParseCommandLine(argc, argv);
        UnityInitRuntime(argc, argv);
        
        RegisterMonoModules();
        NSLog(@"-> registered mono modules %p\n", &constsection);
        RegisterFeatures();
        
        // iOS terminates open sockets when an application enters background mode.
        // The next write to any of such socket causes SIGPIPE signal being raised,
        // even if the request has been done from scripting side. This disables the
        // signal and allows Mono to throw a proper C# exception.
        std::signal(SIGPIPE, SIG_IGN);
        
        //        UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:"AppControllerClassName"]);
    }
    
    return 0;
}

2.把Unity工程中的Classes、Data、Libraries文件按照如下方式添加到Unity文件夹中

  • Classes和Libraries需要选择copy if needs、create groups


    这里直接盗图了
  • Data需要选择Create folder references


    这里直接盗图了

    Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第11张图片
    完成后的截图

删除libraries里面的libil2cpp文件夹的引用,然后再删除Classes里面的Native文件夹里面的所有.h文件的引用.

3.在Classes中找到main.mm文件

//替换原来的代码
int main_unity_default(int argc, char* argv[])
{
    @autoreleasepool
    {
        UnityInitTrampoline();
        //        UnityParseCommandLine(argc, argv);
        UnityInitRuntime(argc, argv);
        RegisterMonoModules();
        NSLog(@"-> registered mono modules %p\n", &constsection);
        RegisterFeatures();
        
        // iOS terminates open sockets when an application enters background mode.
        // The next write to any of such socket causes SIGPIPE signal being raised,
        // even if the request has been done from scripting side. This disables the
        // signal and allows Mono to throw a proper C# exception.
        std::signal(SIGPIPE, SIG_IGN);
        
        //UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]);
        //        UIApplicationMain(argc, argv, nil, NSStringFromClass([UnitySubAppDelegate class]));
        UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]);
    }
    
    return 0;
}

4.在Classes中找到UnityAppController.h做如下修改

//添加如下代码
#import 
//若没有@class UnityViewControllerBase;
//还需要添加@class UnityViewControllerBase;
//inline UnityAppController*  GetAppController()
//{
//    return (UnityAppController*)[UIApplication sharedApplication].delegate;
//}
NS_INLINE UnityAppController* GetAppController()
{
    NSObject* delegate = [UIApplication sharedApplication].delegate;
    UnityAppController* currentUnityController = (UnityAppController *)[delegate valueForKey:@"currentUnityController"];
    return currentUnityController;
}

5.修改Swift工程
新建一个main.swift文件,添加如下代码

import Foundation
import UIKit
// overriding @UIApplicationMain
custom_unity_init(CommandLine.argc, CommandLine.unsafeArgv)
UIApplicationMain(
    CommandLine.argc,
    UnsafeMutableRawPointer(CommandLine.unsafeArgv)
        .bindMemory(
            to: UnsafeMutablePointer.self,
            capacity: Int(CommandLine.argc)),
    nil,
    NSStringFromClass(AppDelegate.self)
)

6.对AppDelegate.swift文件做如下修改

import UIKit

//这里需要注释
//@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var currentUnityController: UnityAppController!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.backgroundColor = UIColor.white
        let vc: ViewController = ViewController()
        let nav: UINavigationController = UINavigationController(rootViewController: vc)
        window?.rootViewController = nav

        currentUnityController = UnityAppController()
        currentUnityController.application(application,didFinishLaunchingWithOptions: launchOptions)
        
        window?.makeKeyAndVisible()
        
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        currentUnityController.applicationWillResignActive(application)
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        currentUnityController.applicationDidEnterBackground(application)
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        currentUnityController.applicationWillEnterForeground(application)
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        currentUnityController.applicationDidBecomeActive(application)
    }

    func applicationWillTerminate(_ application: UIApplication) {
        currentUnityController.applicationWillTerminate(application)
    }
}

7.添加依赖库
在Build Phase中添加依赖库

Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第12张图片
添加依赖库

依赖库的组成参考你导出的原Unity项目的依赖库组成。.dylib用.tbd代替也是可以的
8.Unity.xcconfig修改

SWIFT_OBJC_BRIDGING_HEADER = UnityFix/UnityBridge.h;

8.编译器修改
我用Xcode 8.3.3 生成的项目默认就是这样的配置,所以这里没有做更改


Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第13张图片
编译器修改

收尾

  1. 针对iOS 10添加摄像头权限
    在Info.plist文件中添加申请摄像头权限,否则会闪退。


    申请摄像头权限
  2. 如果遇到如下问题


    Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第14张图片
    Control may reach end of non-void function

    添加一行代码


    Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第15张图片
    返回 NULL

    3.解决黑屏问题
    在Libraries->Plugins->iOS 中找到EasyARAppController.mm,将其代码迁移到我们自己生成的一个UnityAppController子类中

ZTARController.h

#import 
#import "UnityAppController.h"

@interface ZTARController : UnityAppController
{
}
- (void)shouldAttachRenderDelegate;
@end

ZTARController.mm

#import "ZTARController.h"

extern "C" void ezarUnitySetGraphicsDevice(void* device, int deviceType, int eventType);
extern "C" void ezarUnityRenderEvent(int marker);

@implementation ZTARController

- (void)shouldAttachRenderDelegate;
{
    UnityRegisterRenderingPlugin(&ezarUnitySetGraphicsDevice, &ezarUnityRenderEvent);
}
@end


IMPL_APP_CONTROLLER_SUBCLASS(ZTARController)

记得在AppDelegate中做如下修改

//var currentUnityController: UnityAppController!
var currentUnityController: ZTARController!

初始化Unity视图

import UIKit

class AViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //初始化Unity视图
        let unityview = UnityGetGLView()!
        unityview.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(unityview)
        unityview.frame = view.bounds
        
        //退出的按钮
        let button = UIButton(frame: CGRect(x: 200, y: 100, width: 100, height: 100))
        button.backgroundColor = UIColor.blue
        view.addSubview(button)
        button.addTarget(self, action: #selector(dismissSelf), for: UIControlEvents.touchUpInside)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        //开启Unity
        UnityPause(0)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        //关闭Unity
        UnityPause(1)
    }
    
    //MARK: 退出视图
    func dismissSelf(){
        self.presentingViewController?.dismiss(animated: true, completion: nil)
    }
}

最后,在真机上运行一下你的工程吧

为了方便调试,楼主在视图上添加了两个按钮
录了一段小视频

更新集成CocoaPods

cd到工程根目录

pod init

添加

pod 'Alamofire'

最后运行

pod install

安装完成之后做如下更改


Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第16张图片
更改

更改BuildSetting里的设置


Swift 3.0 项目集成EasyAR Unity 2.0 SDK_第17张图片
更改BuildSetting设置

Clean一下你的工程,然后重新编译。

遇到找不到头文件


遇到找不到头文件

在Header Search Paths 中添加

"$(PODS_ROOT)/Headers/Public"
"$(PODS_ROOT)/Headers/Public/JPush"

到此,成功集成CocoaPods

参考

swift3.0融合Unity
unity 整合到原生iOS项目(swift 2.3)
Unity嵌入Swift3.0
unity3D与iOS原生工程项目合并以及合并过程中的问题
下载Unity.xcconfig,由blitzagency提供

Demo 地址

https://github.com/WenslowZhu/UnityTest

你可能感兴趣的:(Swift 3.0 项目集成EasyAR Unity 2.0 SDK)