IOS原生項目集成Unity3D

一,代碼拷貝及項目配置

1,拷貝文件到原生項目
 Libraries 文件夾
 Classes 文件夾
 Data 文件夾
 MapFileParser 文件
2,刪除Libraries下的libil2cpp,注意刪除選項選擇Remove References。
3,添加Unity3D 項目所依賴動態(tài)庫(參照Unity3D 導(dǎo)出的xCode 工程),并注意Optional 選項
4BD1348B-C4DA-4E39-8E20-554F234709F2.png
4,添加 Other linker Flags 依賴:
            -weak_framework
            CoreMotion
            -weak-lSystem
            -Wl,-undefined,dynamic_lookup

特別注意:如IOS原生項目中配置了-all_load 應(yīng)刪除,否則會與Unity3D 項目中的依賴庫沖突

5, "Header Search Paths' 添加Unity3D 文件夾 Classes、Native、include 路徑(根據(jù)自己項目實際文件路徑配置)
            "$(SRCROOT)/FunGaming/3DHuntFish_lib/Classes"
            "$(SRCROOT)/FunGaming/3DHuntFish_lib/Classes/Native"
            "$(SRCROOT)/FunGaming/3DHuntFish_lib/Libraries/libil2cpp/include"
6,添加User-Defined 配置,
4BEADD41-8DC0-40EC-BBA3-05C70870920D.png
 GCC_THUMB_SUPPORT = NO
 GCC_USE_INDIRECT_FUNCTION_CALLS = NO
 UNITY_RUNTIME_VERSION = 2017.3.0f3 // 根據(jù)自己Unity 版本實際配置
 UNITY_SCRIPTING_BACKEND = il2cpp
7,添加Build Phases -> Run Script 配置(根據(jù)自己項目實際路徑配置)
"$PROJECT_DIR/MapFileParser.sh"
rm -rf "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"
cp -Rf "$PROJECT_DIR/FunGaming/3DHuntFish_lib/Data" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"

二,代碼更改

1,刪除Unity3D Class 文件夾下main.mm 文件 并合并到自己原生工程中的main.mm 文件中
#import <UIKit/UIKit.h>
#import "AppDelegate.h"

//int main(int argc, char * argv[]) {
//    @autoreleasepool {
//        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
//    }
//}


#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <csignal>

// Hack to work around iOS SDK 4.3 linker problem
// we need at least one __TEXT, __const section entry in main application .o files
// to get this section emitted at right time and so avoid LC_ENCRYPTION_INFO size miscalculation
static const int constsection = 0;

void UnityInitTrampoline();

// WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its value)
const char* AppControllerClassName = "UnityAppController";

int main(int argc, char* argv[])
{
    UnityInitStartupTime();
    @autoreleasepool
    {
        UnityInitTrampoline();
        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 UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
    
    return 0;
}

#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,UnityAppController.h 中更改
@class AppDelegate;
……
//inline UnityAppController*  GetAppController()
//{
//    return (UnityAppController*)[UIApplication sharedApplication].delegate;
//}

#import "AppDelegate.h"
inline UnityAppController*  GetAppController()
{
    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    
    return delegate.unityController;
}
3,原生 AppDelegate 中更改

AppDelegate.h:

class UnityAppController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) UIWindow *unityWindow;

@property (strong, nonatomic) UnityAppController *unityController;

//- (void)showUnityWindow;
- (void)hideUnityWindow;

/**  通用APP啟動接口  */
-(void)commonInitLaunch;

/**  檢查APP版本信息  */
-(void)checkAPPVerson;

+(AppDelegate *)sharedDelegate;

-(void)StartMyUnity3DGames; //開啟unity

@end

AppDelegate.mm:

#import <UIKit/UIKit.h>
#import "UnityAppController.h"

#import "AppDelegate.h"

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

-(void)showUnityWindow{
    //進入unity界面
    //[(AppDelegate *)[UIApplication sharedApplication].delegate showUnityWindow];
    
    UnityPause(false);
    
    [self.unityWindow makeKeyAndVisible];
}

-(void)hideUnityWindow{
    
    //推出Unity界面
    //[(AppDelegate *)[UIApplication sharedApplication].delegate hideUnityWindow];
    
    UnityPause(true);
    
    [self.window makeKeyAndVisible];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    self.unityController = [[UnityAppController alloc] init];
    [_unityController application:application didFinishLaunchingWithOptions:launchOptions];
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    
    [self commonInitLaunch]; // 原生項目啟動方法
    
    return YES;
}

+(AppDelegate *)sharedDelegate{
    
    return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    
    [_unityController applicationWillResignActive:application];
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    
    [UIApplication sharedApplication].idleTimerDisabled = NO;
    
    [_unityController applicationDidEnterBackground:application];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    
    [UIApplication sharedApplication].idleTimerDisabled = YES;
    
    [_unityController applicationWillEnterForeground:application];
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    
    [[LoginManager instance] startALightWeightHttpServer];
    
    //[_unityController applicationDidBecomeActive:application];
    
}

-(void)StartMyUnity3DGames
{
    [_unityController applicationDidBecomeActive:[UIApplication sharedApplication]];
    
    [self showUnityWindow];
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    
    [UIApplication sharedApplication].idleTimerDisabled = NO;
    
    [_unityController applicationWillTerminate:application];
}
4 UnityInterface.h 更改
#import <Foundation/Foundation.h> // 引入 objc Foundation 框架

inline char* AllocCString(NSString* value)
{
    if (value == nil)
        return 0;

    const char* str = [value UTF8String];
    return str ? strdup(str) : 0;
}
5,合并 .pch 文件
#include "Preprocessor.h"

#define printf_console printf

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

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

#ifndef TARGET_IPHONE_SIMULATOR
#define TARGET_IPHONE_SIMULATOR 0
#endif
6, Unity3D 啟動及退出

在需要啟動Unity3D 項目的地方調(diào)用 [[AppDelegate sharedDelegate] StartMyUnity3DGames];
退出Unity3D(其實是暫停) [[AppDelegate sharedDelegate] hideUnityWindow];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容