1. 程式人生 > >IOS原生專案整合Unity3D

IOS原生專案整合Unity3D

第1步 unity3D匯出Xcode專案

123

第2步  將專案匯入到ios原生專案

1.將Classes,Libraries,MapFileParser.sh拖入到專案(選中Copy items if needed,選中Create groups)

2.將Data拖入到專案(選中Copy items if needed,選中Create folder references)

1

*拖入方式

如果選擇了Create groups方式添加了一個檔案,我們會發現被新增進來的檔案,資料夾是黃色的,groups下的cpp檔案是會被編譯的

選擇了 Create folder references方式新增進來的檔案的資料夾是藍色的, 只是將檔案單純的建立了引用,這些檔案不會被編譯,所以在使用的時候需要加入其路徑

3.修改ios原生專案的bit code為NO

4.新增framework

*由於每個Unity 3D專案不同,導致所需要framework也不同,開啟Unity 3DXcode專案,把所有的framework在原生專案中新增,如果有第三方的庫,把庫從Unity 3DXcode專案中匯出到原生專案,並且在Framework Search Paths新增路徑

*Unity 3DXcode專案中有個別庫的Status 選擇的Optional,如圖

2

5.在Header Search Paths和Library Search Paths 新增Unity3D 資料夾 Classes、Native、include 路徑(根據自己專案實際檔案路徑配置)

*$(SRCROOT) 代表的是專案根目錄下  $(PROJECT_DIR)代表的是整個專案

13

4

6.修改Build Settings 下     other C Flags -> -DINIT_SCRIPTING_BACKEND=1

5

7.新增User-Defined   將Unity 3D專案中的User-Defined裡的配置項新增到原生專案中

6

8.新增Run Script

*MapFileParser.sh  路徑根據實際專案路徑新增

7

第3步  修改原生程式碼

1.將Classes/main.mm內容複製到main.m 並把副檔名改為.mm,刪除Unity3D Class 資料夾下main.mm 檔案,刪除操作選擇Remove Reference

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#include "RegisterFeatures.h"
#include "RegisterMonoModules.h"
#include <csignal>

static const int constsection = 0;

void UnityInitTrampoline();

const char* AppControllerClassName = "AppDelegate";

int main(int argc, char * argv[]) {

    @autoreleasepool {
        UnityInitTrampoline();
        UnityInitRuntime(argc, argv);
        RegisterMonoModules();
        NSLog(@"-> registered mono modules %p\n", &constsection);
        RegisterFeatures();
        
        std::signal(SIGPIPE, SIG_IGN);
        
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

#if TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR

#include <pthread.h>

extern "C" int pthread_cond_init$UNIX2003(pthread_cond_t *cond, const pthread_condattr_t *attr)
{ return pthread_cond_init(cond, attr); }
extern "C" int pthread_cond_destroy$UNIX2003(pthread_cond_t *cond)
{ return pthread_cond_destroy(cond); }
extern "C" int pthread_cond_wait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex)
{ return pthread_cond_wait(cond, mutex); }
extern "C" int pthread_cond_timedwait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex,
                                               const struct timespec *abstime)
{ return pthread_cond_timedwait(cond, mutex, abstime); }

#endif // TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR

2 修改AppDelegate.h

#import <UIKit/UIKit.h>

@class UnityAppController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UnityAppController * unityController;

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) UIWindow *unityWindow;

-(void)showUnityWindow;

-(void)hideUnityWindow;

@end

3 修改AppDelegate.m  新增如下程式碼

*核心就是切換window

#import "UnityAppController.h"

@implementation AppDelegate

-(UIWindow *)unityWindow{
    return UnityGetMainWindow();
}

-(void)showUnityWindow{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    button.frame = CGRectMake(0, 0, 44, 44);
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"返回" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(hideUnityWindow) forControlEvents:UIControlEventTouchUpInside];
    [self.unityWindow addSubview:button];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [self.unityWindow makeKeyAndVisible];
}

-(void)hideUnityWindow{
    [[UIApplication sharedApplication] setStatusBarHidden:NO];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
    [self.window makeKeyAndVisible];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    
    ViewController * vc = [[ViewController alloc]init];
    self.window.rootViewController = vc;
    
    self.unityController = [[UnityAppController alloc]init];
    [self.unityController application:application didFinishLaunchingWithOptions:launchOptions];
    
    [self.window makeKeyAndVisible];
   
    
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    [self.unityController applicationWillResignActive:application];
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [self.unityController applicationDidEnterBackground:application];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [self.unityController applicationWillEnterForeground:application];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [self.unityController applicationDidBecomeActive:application];
}

- (void)applicationWillTerminate:(UIApplication *)application {
    [self.unityController applicationWillTerminate:application];
}

@end

4 合併 .pch 檔案,如果之前沒有建立一個,刪除Unity/Classes/Prefix.pch,刪除操作選擇Remove Reference

#ifndef PrefixHeader_pch
#define PrefixHeader_pch

// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.



#ifdef __OBJC__
#import <Foundation/Foundation.h>
#include "UnityAppController.h"
#import <UIKit/UIKit.h>
#endif

#include "Preprocessor.h"

#include "UnityTrampolineConfigure.h"
#include "UnityInterface.h"

#ifndef __OBJC__
#if USE_IL2CPP_PCH
#include "il2cpp_precompiled_header.h"
#endif
#endif

#ifndef TARGET_IPHONE_SIMULATOR
#define TARGET_IPHONE_SIMULATOR 0
#endif

#define printf_console printf


#endif /* PrefixHeader_pch */

5.修改UnityAppController.mm

#import "AppDelegate.h"





inline UnityAppController*  GetAppController()
{
    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    return delegate.unityController;
//    return (UnityAppController*)[UIApplication sharedApplication].delegate;
//    return (UnityAppController*)[[UIApplication sharedApplication] valueForKeyPath:@"delegate.unityAppController"];
}

第4步   有可能遇到的問題收集來的,也有自己遇到的

1 Unity 3D不支援豎屏,原生專案支援豎屏

#pragma mark    -       橫豎屏處理
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    //根據自己專案架構獲取當前顯示的ViewController
    UIViewController *currentVC = [NavigationManager getCurrentViewController];
    if (currentVC) {//獲取原生viewController的轉屏方向
        return currentVC.supportedInterfaceOrientations;
    }
    return UIInterfaceOrientationMaskAll;
}

2.Unknown type name 'UnityViewControllerBase'

解決辦法就是把它改成UIViewController

3.iOS本地應用跳轉unity的時候出現黑屏

原因是你的u3d工程集成了EasyAR外掛,而這個外掛下有個Assets/Plugins/iOS/EasyARAppController.mm,

@interface EasyARAppController : UnityAppController,這是整個app啟動時的第一個controller,自己修改合併這個controller就OK了

或者是將EasyARAppController.mm的內容複製到你的自定義的子類中去,然後刪除引用也是OK的

在UnityAppController.mm裡這個方法中寫