iOS與Unity3D交互

最近游戲組讓配合開發一個 “在Unity中點擊按鈕彈出原生二維碼掃碼頁面 -> 再把獲取到的二維碼信息傳回給Unity” 的功能,于是我就開始了學習iOS與Unity3d交互的不歸路~。

由于對Unity不熟,導出的Xcode工程跟平時用的Xcode也有些差異,遇到了很多沒遇到過的問題,只能慢慢摸索,慢慢解決。

剛開始在網上下載下來的Xcode Demo無法在真機上運行(在模擬器上正常)、添加不了Pod,只好自己新建一個干凈的Unity工程,仿照Unity Demo編寫交互代碼再重新導出Xcode工程,沒有問題了再對接二維碼掃碼的功能。

在Unity中點擊按鈕“跳轉iOS” -> 在App中掃描二維碼并把結果返回給Unity -> 在Unity中顯示“二維碼內容


一、代碼實現:


1、Unity代碼:

添加一個C#文件,添加實現代碼。

// Unity代碼

using UnityEngine;

using System.Collections;

using System.Runtime.InteropServices;

public class Test : MonoBehaviour {

? ? public GameObject cube;

? ? // DllImport這個方法相當于是告訴Unity,有一個unityToIOS函數在外部會實現。

? ? // 使用這個方法必須要導入System.Runtime.InteropServices;

? ? [DllImport("__Internal")]

? ? private static extern void unityToIOS ( string str );

? ? public string scanStatus;//二維碼掃描結果

? ? void OnGUI(){

?????????// 當點擊按鈕后,調用外部方法

?????????if (GUI.Button (new Rect (100, 100, 200, 60), "跳轉IOS")) {

?? ????????? // Unity調用ios函數,同時傳遞數據

?? ? ????????unityToIOS ("Hello IOS");

?????????}

? ? ? ? //控件要寫在GUI里面 可以設置一個全局str,賦值,OnGUI是每秒都會自動刷新。

? ? ? ?GUI.Label (new Rect (100, 200, 400, 60), scanStatus);?

? ? }

? ? // 用戶取消了掃碼

? ? void cancelScan(string str){

?????????scanStatus = str;

? ? }

? ? // 獲取二維碼成功

? ? void getQRSuccess(string str){

?????????scanStatus = @"二維碼內容:" + str;

? ? }

? ? // 向右轉函數接口

? ? void turnRight(string num){

?????????float f;

?????????if (float.TryParse (num, out f)) {// 將string轉換為float,數據之間的傳遞只能以string類型

?? ? ????????Vector3 r = new Vector3 (cube.transform.rotation.x, cube.transform.rotation.y - 10f, cube.transform.rotation.z);

?? ? ????????cube.transform.Rotate (r);

?????????}?

}}


2、iOS代碼:

iOS端主要在UnityAppController.mm文件中編寫代碼 (創建一個LARManager.h文件并創建一些交互方法)。

// MARK: - 直接加載unity頁面

- (void)startUnity:(UIApplication*)application{

? ? //新增代碼

? ? [self showUnityPage];

? ? /* 隱藏了一些Unity代碼 */

}

// MARK: - 展示Unity頁面

- (void)showUnityPage {

? ? if ([LARManager sharedInstance].unityIsPaused) {

? ? ? ? UnityPause(false);//打開Unity

? ? ? ? [LARManager sharedInstance].unityIsPaused = NO;

? ? ? ? //設置rootView為Unity界面

? ? ? ? self.window.rootViewController = self.rootViewController;

?}}


iOS調用Unity:通過UnitySendMessage方法實現。

UnitySendMessage("gameobject", "Method", msg);

參數一為unity腳本掛載的gameobject

參數二為unity腳本中要調用的方法名

參數三為傳遞的數據,*注意:傳遞的數據只能是char 類型

// MARK: - iOS傳遞事件給Unity ScanDelegate

//取消掃描

- (void)cancelScan {

? ? [self showUnityPage];

? ? UnitySendMessage("Main Camera", "cancelScan", [@"取消掃描" UTF8String]);

}

//獲取二維碼信息成功

- (void)getQRSuccess:(NSString *)str{

? ? [self showUnityPage];

? ? UnitySendMessage("Main Camera", "getQRSuccess", [str UTF8String]);

}

- (void)turnRight{//右轉

? ? const char* str = [[NSString stringWithFormat:@"10"] UTF8String];

? ? UnitySendMessage("Main Camera", "turnRight", str);//IOS調用Unity的方法,通過UnitySendMessage方法實現。

}

- (void)turnLeft{//左轉

? ? const char* str = [[NSString stringWithFormat:@"10"] UTF8String];

? ? UnitySendMessage("Main Camera", "turnLeft", str);

}


Unity調用iOS:實現Unity的調用方法

// MARK: - Unity傳遞事件給iOS (跳轉到iOS界面,Unity界面暫停)

extern "C"{

? ? void unityToIOS(char* str){// 對Unity中的unityToIOS方法進行實現

? ? ? ? NSLog(@"*************%s",str);// Unity傳遞過來的參數

? ? ? ? UnityPause(true);//暫停Unity

? ? ? ? [LARManager sharedInstance].unityIsPaused = YES;


? ? ? ? //掃碼頁面

? ? ? ? ScanController *vc = [ScanController new];

? ? ? ? vc.delegate = GetAppController().self;//添加代理

? ? ? ? GetAppController().scanVC = vc;

? ? ? ? // GetAppController()獲取appController,相當于self; UnityGetGLView()獲取UnityView,相當于_window; 點擊按鈕后跳轉到IOS界面,設置界面為IOS界面

? ? ? ? GetAppController().window.rootViewController = GetAppController().scanVC;

}}


二、遇到的問題:


1、在Unity中: C#腳本Test和控件Cube要建立好綁定關系,不然無效.

2、(巨坑:浪費了我不少時間~.~)

Xcode:打包出來沒有在IOS中實現Unity定義的交互函數,運行Xcode就報錯,還以為是在網上下載的demo代碼有問題。

原因:

沒有實現Unity定義的交互函數_unityToIOS

解決:

在?extern "C”{中實現相關函數

3、把IOS代碼拖入工程后運行__weak typeof(self) wSelf = self聲明報錯:

a parameter list without types is only allowed in a function definition。

原因:

可能是編譯器識別不了typeof關鍵字

解決:

Apple LLVM 6.1 - Language設置C Language Dialect為Compiler Default或者GNU99[-std=gnu99]

4、繼續報錯

Undefined symbols for architecture arm64: "_kCGImagePropertyExifDictionary", referenced from: -[SGQRCodeObtain captureOutput:didOutputSampleBuffer:fromConnection:] in SGQRCodeObtain.o

原因:

引用第三方庫時是直接把代碼拖進工程的,可能漏了某些文件.

解決:

直接用pod導入第三方庫.

5、用到了相機、相冊或其他功能忘記添加訪問權限配置,導致閃退

解決:

要在info.plist中添加訪問權限配置


三、拓展:


1、Unity導出Xcode工程:

下載好Unity項目并打開?-> File -> Building Setting -> iOS-> Switch Platform -> Add Open Scenes -> Player Setting -> .NET 2.0 -> Build

a、首先在File->Build Settings

b、選擇iOS,第一次裝的時候需要先下載一個iOS支持文件,下載完成后安裝。

重啟unity->Build(release)

這樣就創建成功一個蘋果工程了

選擇iOS后要點擊Switch Platform,不然打不了iOS包

點擊player settings->Target SDK可以選擇映射出來的蘋果項目是運行于模擬器的還是真機的。

2、打包上架遇坑:

在給游戲打蘋果包的時候,發現在最后一步一直顯示Compiling bitcode超時

原因:

Enable Bitcode設置的YES,工程進行了Bitcode編譯很耗時。我查看了其他工程都是設置的NO

解決:

Build Settings->Enable Bitcode設置為NO


3、探索:(待完善)

游戲端的代碼更新了,可不可以做到直接在原有的Xcode工程上替換unity相關文件,而不需要每次都重新生成Xcode工程,再在新工程上重新寫一遍IOS代碼;

如果必須每次都寫一遍的話,那就把代碼封裝到工具類中,每次只需要拖入工具并改少量的代碼就行。把iOS代碼復用性做到最高,耦合性降到最低。

掃碼相關的內容就不細說了,可以下載我的代碼?MyUnityToIOS了解 提取碼:feeg。里面有Unity和Xcode兩端的代碼,感興趣的可以自己下載下來慢慢看~.~

資料

iOS與Unity3d交互

Unity里調用iOS原生

Unity3D與iOS的交互

swift-unity

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 最近在實驗室做了一個項目,用到了藍牙通訊和U3D的交互,都有很多坑,如:IOS與Unity3D界面之間的跳轉...
    Larrycal閱讀 23,706評論 34 53
  • 一.小記 最近公司有個需求,需要用unity3D建立3D模型,并且實現切換功能,由于做開發時間不算長,又沒有接觸過...
    矯炎圻閱讀 12,853評論 20 19
  • Unity3D 簡介 Unity3D是由Unity Technologies開發的一個讓玩家輕松創建諸如三維視頻游...
    ProgramDouglas閱讀 1,150評論 0 0
  • 1. 關于Unity3D Unity3D(以下簡稱U3D)是由Unity Technologies開發的一個讓玩家...
    杰嗒嗒的阿杰閱讀 37,957評論 17 53
  • 前言 關于Unity和iOS的交互,在網上看了很多文章后發現,其他作者都有一個共同點,描述不完整,作者們以為大家都...
    Teun丶閱讀 2,720評論 5 6