iOS - 將Unity匯出的Xcode工程匯入到另一個Xcode專案, 及常見報錯的解決方法
demo下載地址 http://pan.baidu.com/s/1pLcpKpl
1.Unity匯出工程時設定bundle id要與專案一致
2.修改bit code為NO
3.刪除Main.storyboard,程式碼設定控制器(方便切換window)
4.將Classes,Libraries,MapFileParser.sh拖入到專案(選中Copy items if needed, 選中Create groups)
將Data拖入到專案(選中Copy items if needed, 選中Create folder references)
5.新增framework(最下邊三個是HiAR UnitySDK裡邊的)
6.新增 Header Search Paths 和 Library Search Paths
7.other C Flags -> -DINIT_SCRIPTING_BACKEND=1
8.新增User-Defined (UNITY_RUNTIME_VERSION版本號與匯出工程的Unity版本號一致)
9.Unity/Classes/Prefix.pch 的程式碼複製到新建的pch檔案, 設定pch檔案路徑
10.將Classes/main.mm全部內容複製到main.m 並把副檔名改為.mm, 修改如下程式碼
11.新增Run Script
12. 修改UnityAppController.h如下程式碼
13.在AppDelegate.h .m中新增如下程式碼
在整合過程中可能遇到的問題
1.
UnityViewControllerBase報錯, 把它改成UIViewController
2. Unknown type name 'AppDelegate'
在新建的專案裡邊不會報錯, 但是我整合到公司專案的時候報這個錯, 於是改成如下程式碼, 目前沒有出現問題, 如果有人知道原因, 請在評論區告訴我
3. Undefined symbols for architecture armv7
遇到這個錯的同學請新增AssetsLibrary.framework和Accelerate.framework
4.編譯時遇到Permission denied錯誤的是因為當前開發賬號對專案目錄沒有許可權執行MapFileParser.sh
解決辦法: 在終端執行命令 sudo chmod -R 777 所在的目錄
5. Functions that differ only in their return type cannot be overloaded
解決辦法: 把Enable Strict Checking of objc_msgSend Calls 改為NO
6. Control reaches end of non-void function
解決辦法: 把Mismatched Return Type 改為NO
C++混編需要設定的地方
7.刪除unity自帶的.pch和main.mm檔案
8.linker command failed with exit code 1
duplicate symbol __Z32RegisterAllStrippedInternalCallsv in:
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/UnityICallRegistration.o
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/RegisterMonoModules.o
duplicate symbol __Z18RegisterAllClassesv in:
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/UnityClassRegistration.o
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/RegisterMonoModules.o
duplicate symbol __Z43InvokeRegisterStaticallyLinkedModuleClassesv in:
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/UnityClassRegistration.o
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/RegisterMonoModules.o
duplicate symbol __Z39RegisterStaticallyLinkedModulesGranularv in:
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/UnityClassRegistration.o
/Users/xinshang/Library/Developer/Xcode/DerivedData/App3.0-hidvomkzbvfqvibtxzyzngoflknc/Build/Intermediates/App3.0.build/Debug-iphoneos/App3.0.build/Objects-normal/arm64/RegisterMonoModules.o
ld: 4 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1(use -v to see invocation)
解決辦法:
找到對應的RegisterMonoModules.cpp檔案,註釋掉重複的方法:
#if !INIT_SCRIPTING_BACKEND
extern void RegisterAllClassesGranular();
//void RegisterAllClasses()
//{
// // Register classes for unit tests
// RegisterAllClassesGranular();
//}
//
//void RegisterAllStrippedInternalCalls() {}
//
//void InvokeRegisterStaticallyLinkedModuleClasses() {}
//void RegisterStaticallyLinkedModulesGranular() {}
#endif // INIT_SCRIPTING_BACKEND
void RegisterMonoModules() {}
9.[DYMTLInitPlatform] platform initialization successful啟動報錯,
解決:修改main.m檔案
// main.m
// App3.0
//
// Created by mac on 17/2/16.
// Copyright © 2017年 mac. All rights reserved.
//
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <mach/mach_time.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";
const char* AppControllerClassName = "AppDelegate";
int main(int argc, char* argv[])
{
signed long long startTime = mach_absolute_time();
@autoreleasepool
{
UnitySetStartupTime(startTime);
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 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
// 可能有的步驟忘記了, 有疑問的可以在評論區留言