iOS與Unity3D交互

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

因爲對Unity不熟,導出的Xcode工程跟平時用的Xcode也有些差別,遇到了不少沒遇到過的問題,只能慢慢摸索,慢慢解決。git

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

1、代碼實現:

一、Unity代碼:

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

// 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);
	} 
    }
}

複製代碼

二、iOS代碼:

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

// 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 類型app

// 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;
    }
}
 
複製代碼

2、遇到的問題:

一、在Unity中: C#腳本Test和控件Cube要創建好綁定關係,否則無效.

二、巨坑:浪費了我很多時間🙈

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

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

解決:
extern "C」{ 中實現相關函數工具

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

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

緣由:
多是編譯器識別不了typeof關鍵字ui

解決:
Apple LLVM 6.1 - Language設置C Language Dialect爲Compiler Default或者GNU99[-std=gnu99]

四、繼續報錯

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

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

解決:
直接用pod導入第三方庫.

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

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

.

3、拓展:

unity 打包:

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

一、首先在File->Build Settings

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

重啓unity->Build(release)
這樣就建立成功一個蘋果工程了
選擇iOS後要點擊Switch Platform,否則打不了iOS包

點擊player settings->Target SDK能夠選擇映射出來的蘋果項目是運行於模擬器的仍是真機的。

.

探索:(待完善)

遊戲端的代碼更新了,可不能夠作到直接在原有的Xcode工程上替換unity相關文件,而不須要每次都從新生成Xcode工程,再在新工程上從新寫一遍IOS代碼;
若是必須每次都寫一遍的話,那就把代碼封裝到工具類中,每次只須要拖入工具並改少許的代碼就行。把iOS代碼複用性作到最高,耦合性降到最低。

掃碼相關的內容就不細說了,能夠下載個人代碼 MyUnityDemo 瞭解,提取密碼:feeg。裏面有Unity和Xcode兩端的代碼,感興趣的能夠本身下載下來慢慢看~.~

資料

iOS與Unity3d交互
Unity裏調用iOS原生
Unity3D與iOS的交互
swift-unity

相關文章
相關標籤/搜索