1. 程式人生 > >iOS和Unity互動之介面跳轉

iOS和Unity互動之介面跳轉

本文介紹了iOS和Unity互動,主要涉及兩個介面之間的跳轉.

如果對iOS和Unity互動傳參方法不熟悉的朋友,可以參考我的另一篇文章
iOS和Unity互動之引數傳遞

一.程式啟動入口.

  • main.mm

瞭解OC或者C的朋友一定知道main方法,這是整個程式的入口.以下是Unity轉iOS工程後的main檔案中的部分程式碼.

const char* AppControllerClassName = "UnityAppController";
int main(int argc, char* argv[])
{
    @autoreleasepool
    {
        UnityInitTrampoline();
        UnityParseCommandLine(argc, argv);

        RegisterMonoModules();
        NSLog
(@"-> registered mono modules %p\n", &constsection); RegisterFeatures(); std::signal(SIGPIPE, SIG_IGN); // 程式啟動入口 UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]); } return 0; }

根據程式碼得知,程式需要建立UnityAppController物件.那麼,程式就來到了UnityAppController檔案.
在UnityAppController.mm檔案中的以下方法中新增列印:NSLog(@"%s",__func__);

- (id)init
- (void)startUnity:(UIApplication*)application
- (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
- (void)applicationDidBecomeActive:(UIApplication
*)
application

列印結果為:

2017-05-24 04:50:09.597338+0800 ProductName[5622:1888712] [DYMTLInitPlatform] platform initialization successful
2017-05-24 04:50:09.693476+0800 ProductName[5622:1888655] -> registered mono modules 0x100df3fa0
2017-05-24 04:50:09.714814+0800 ProductName[5622:1888655](標記) -[UnityAppController init]
2017-05-24 04:50:09.930542+0800 ProductName[5622:1888655] -[UnityAppController application:willFinishLaunchingWithOptions:]
2017-05-24 04:50:09.931002+0800 ProductName[5622:1888655](標記) -[UnityAppController application:didFinishLaunchingWithOptions:]
-> applicationDidFinishLaunching()
2017-05-24 04:50:10.013760+0800 ProductName[5622:1888655] Metal GPU Frame Capture Enabled
2017-05-24 04:50:10.014789+0800 ProductName[5622:1888655] Metal API Validation Enabled
2017-05-24 04:50:10.178127+0800 ProductName[5622:1888655](標記) -[UnityAppController applicationDidBecomeActive:]
-> applicationDidBecomeActive()
2017-05-24 04:50:10.190176+0800 ProductName[5622:1888655](標記) -[UnityAppController startUnity:]
Init: screen size 640x1136
Initializing Metal device caps: Apple A7 GPU
Initialize engine version: 5.3.5f1 (960ebf59018a)
UnloadTime: 2.714958 ms
Setting up 1 worker threads for Enlighten.
Thread -> id: 16ea3b000 -> priority: 1 

根據帶(標記)的列印結果得知

1.程式會先呼叫- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions方法,進行Unity介面初始化並佈局UI.

2.準備啟用Unity,已啟用程式則呼叫- (void)applicationDidBecomeActive:(UIApplication*)application方法,方法中設定了UnityPause(0);表示Unity為啟動狀態,在方法最後,執行[self performSelector:@selector(startUnity:) withObject:application afterDelay:0];.

3.呼叫- (void)startUnity:(UIApplication*)application方法,展示Unity介面.

二.Unity跳轉iOS介面.

  • 程式啟動為Unity介面,通過點選跳轉iOS按鈕,呼叫unityToIOS方法建立iOS介面並將iOS建立的控制器設定為視窗的跟控制器.以實現跳轉iOS介面.
    .cs程式碼
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
using SClassLibrary;

  public class Test : MonoBehaviour
{
    public GameObject cube;

    // DllImport這個方法相當於是告訴Unity,有一個unityToIOS函式在外部會實現。
    // 使用這個方法必須要匯入System.Runtime.InteropServices;
    [DllImport("__Internal")]
    private static extern void unityToIOS(string str);

    // 向右轉函式介面
    public void turnRight(string num)
    {
        float f;
        if (float.TryParse(num, out f))
        {// 將string轉換為float,IOS傳遞資料只能用以string型別
            Vector3 r = new Vector3(cube.transform.rotation.x, cube.transform.rotation.y + f, cube.transform.rotation.z);
            cube.transform.Rotate(r);
        }
    }
    // 向左轉函式介面
    public void turnLeft(string num)
    {
        float f;
        if (float.TryParse(num, out f))
        {// 將string轉換為float,IOS傳遞資料只能用以string型別
            Vector3 r = new Vector3(cube.transform.rotation.x, cube.transform.rotation.y - f, cube.transform.rotation.z);
            cube.transform.Rotate(r);
        }
    }

    public void DllTest()
    {
        var user = new User
        {
            Id = 1,
            Name = "張三"
        };
  #if UNITY_IPHONE && !UNITY_EDITOR
        unityToIOS(user.ToString());
  #else
        Debug.Log(user.ToString());
  #endif
    }
  }
  • 新增屬性,該屬性用來儲存建立的iOS控制器(儘量設定為私有屬性)
@interface UnityAppController ()
@property (nonatomic, strong) UIViewController *vc;
@end
  • Unity會呼叫unityToIOS方法,跳轉iOS介面之前,先暫停Unity,即UnityPause(true);方法.因為在C語言中,不能直接使用self呼叫物件方法.所以需要通過GetAppController()呼叫setupIOS方法.GetAppController()即UnityAppController型別的物件.在setupIOS方法中,讓
    UnityAppController物件持有vc後,再將vc直接設定為視窗的跟控制器.GetAppController().window.rootViewController = GetAppController().vc;

  • unityToIOS方法

// 跳轉iOS介面
 extern "C" void unityToIOS(char *str)
 {
     // Unity傳遞過來的引數
     NSLog(@"%s",str);
     UnityPause(true);

     // GetAppController()獲取appController,相當於self
     // 設定iOS介面,GetAppController()獲取appController,相當於self
     [GetAppController() setupIOS];

     // 點選按鈕後跳轉到IOS介面,設定視窗的跟控制器為iOS的控制
     GetAppController().window.rootViewController = GetAppController().vc;
 }
  • setupIOS 方法
// 設定iOS介面
  - (void)setupIOS
 {
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view.backgroundColor = [UIColor greenColor];
    vc.view.frame = [UIScreen mainScreen].bounds;

    UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(70, 530, 180, 30)];
    btn.backgroundColor = [UIColor whiteColor];
    [btn setTitle:@"跳轉到Unity介面" forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(setupUnity) forControlEvents:UIControlEventTouchUpInside];

    [vc.view addSubview:btn];

     self.vc = vc;
     NSLog(@"設定介面為IOS介面");
     self.window.rootViewController = vc;
 }

說明:
1.GetAppController()
跳轉到GetAppController()方法內部,實現如下,可以看出,該方法獲取到UIApplication的單例類,而它的代理,則為UnityAppController物件,最後再使用(UnityAppController*)進行強制轉換.所以,在UnityAppController.mm檔案中使用GetAppController()相當於self.

inline UnityAppController *GetAppController()
{
    return (UnityAppController*)[UIApplication sharedApplication].delegate;
}

2.UnityGetGLViewController()
返回Unity的根控制器,根控制器上的檢視是Unity的檢視.,如果將視窗的根控制器設定為UnityGetGLViewController(),其實就是將Unity介面顯示在手機上.

extern "C" UIViewController *UnityGetGLViewController()
{
     return GetAppController().rootViewController; 
}

3.UnityGetGLView()
返回Unity檢視,這個檢視其實就是顯示在UnityGetGLViewController()上的.

extern "C" UIView *UnityGetGLView()
{
    return GetAppController().unityView; 
}

三.iOS跳轉Unity介面.

  • 實現iOS介面中的按鈕的方法.來跳轉到Unity介面.self.rootViewController的作用相當於GetAppController().rootViewController,然後設定window的rootViewController為Unity的跟控制器
  • setupUnity 方法
// 設定Unity介面
 - (void)setupUnity
 {
     // 設定Unity狀態為開啟狀態
     UnityPause(false);

     // 設定rootViewController為Unity的跟控制器
     self.window.rootViewController = self.rootViewController;
     // 等同於
     // self.window.rootViewController = UnityGetGLViewController();
     NSLog(@"設定rootView為Unity介面");
 }

四.封裝介面跳轉程式碼.

檢視UnityAppController.mm檔案,發現其中程式碼太多,為了減少程式碼以及便於我們管理和維護,我們要建立一個單例類來管理Unity和iOS介面互相跳轉的操作.之前在UnityAppController.mm檔案中寫的程式碼全部刪除.

1.需要建立一個自定義類,如:BYJumpEachOther,繼承至NSObject.

2.新增屬性

// 儲存的iOS控制器
@property (nonatomic, strong) UIViewController *vc;

3.入口:unityToIOS,與之前不同的是,呼叫setupIOS方法,改為單例物件去呼叫[[BYJumpEachOther sharedInstance] setupIOS];獲取vc也通過單例物件去獲取.

// 跳轉iOS介面
extern "C" void unityToIOS(char *str)
{
    // Unity傳遞過來的引數
    NSLog(@"%s",str);

    // 跳轉到IOS介面,Unity介面暫停
    UnityPause(true);

    // GetAppController()獲取UnityAppController物件
    // UnityGetGLView()獲取UnityView物件,相當於_window

    [[BYJumpEachOther sharedInstance] setupIOS];

    // 點選按鈕後跳轉到IOS介面,設定介面為IOS介面
    GetAppController().window.rootViewController = [BYJumpEachOther sharedInstance].vc;
}

4.新增BYJumpEachOther建立單例的方法

+ (instancetype)sharedInstance
{
    static BYJumpEachOther *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[BYJumpEachOther alloc] init];
    });
    return instance;
}

5.跳轉iOS介面程式碼

// 設定iOS介面
  - (void)setupIOS
{
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view.backgroundColor = [UIColor greenColor];
    vc.view.frame = [UIScreen mainScreen].bounds;

    UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(70, 530, 180, 30)];
    btn.backgroundColor = [UIColor whiteColor];
    [btn setTitle:@"跳轉到Unity介面" forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(setupUnity) forControlEvents:UIControlEventTouchUpInside];

    [vc.view addSubview:btn];

    self.vc = vc;
    NSLog(@"設定介面為IOS介面");

    GetAppController().window.rootViewController = vc;
}

6.跳轉Unity介面程式碼

// 設定Unity介面
  - (void)setupUnity
{
    UnityPause(false);

    GetAppController().window.rootViewController = UnityGetGLViewController();
    // 等同於
    // GetAppController().window.rootViewController = GetAppController().rootViewController;
    NSLog(@"設定rootView為Unity介面");
}

簡書

個人部落格

GitHub

相關推薦

iOSUnity互動介面

本文介紹了iOS和Unity互動,主要涉及兩個介面之間的跳轉. 如果對iOS和Unity互動傳參方法不熟悉的朋友,可以參考我的另一篇文章 iOS和Unity互動之引數傳遞 一.程式啟動入口. main.mm 瞭解OC或者C的朋友一定

h5頁面喚起app(iOSAndroid),沒有安裝則下載頁面

由於研究了之後,和同事溝通,找到一個地址進入,分別測試不同手機,機型,安卓進入安卓應用商店,ios進入app store ;所以直接貼了一個連結,即可。 下面方法,暫時沒用到,分享給需要的盆友。 COPY的方法如下,參考:------------------------

ios -UIbutton(按鈕)之間的介面

[self.navigationController pushViewController:nextVC animated:YES];//從當前介面到nextVC這個介面 [self.navigationController popViewControl

介面

本文摘自cherish_joy :http://blog.csdn.net/cherish_joy/article/details/72770624 本文介紹了iOS和Unity互動,主要涉及兩個介面之間的跳轉. http://www.jianshu.com/p/8

iOS介面過程中導航欄tabBar的隱藏與顯示

一、當A頁面要push到B頁面,需要將B頁面的導航欄隱藏時,我們只需要在A頁面中重寫以下兩個方法: override func viewWillAppear(animated: Bool) {

python學習網站的編寫(HTML,CSS,JS)(五)----------a標籤,用於實現網頁的頁面具體位置的

 a標籤既可以實現頁面的跳轉也可以實現具體位置的跳轉,見如下程式碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <tit

iOS介面的一些優化方案

App應用程式開發, 介面跳轉是基礎中的基礎, 幾乎沒有一個App是用不到介面跳轉的, 那麼怎麼樣去書寫介面跳轉程式碼才是比較合理的呢? 大家可能在想跳轉無非就2種方式, 能有什麼內容? 其實並不是這樣子的, 對於研發老手來說, 大型應用幾乎都是利用URLSc

android 仿 ios 搜尋介面效果

最新寫專案的時候,看到搜尋介面的跳轉基本都是點選搜尋然後跳轉到下個頁面,android 微信上則是 類似toolbar的效果,而ios 上則是一個搜尋框上移然後顯示新介面的一個效果。仔細研究了下發現和android 的 共享元素的過渡實現 的效果很像,所以在此模

iOS開發中ViewController的頁面彈出模態

ViewController 頁面跳轉 從一個Controller跳轉到另一個Controller時,一般有以下2種:  1、利用UINavigationController,呼叫pushViewController,進行跳轉;這種採用壓棧和出棧的方式,進行Control

iOS開發-使用Storyboard進行介面及傳值

前言:蘋果官方是推薦我們將所有的UI都使用Storyboard去搭建,Storyboard也是一個很成熟的工具了。使用Storyboard去搭建所有介面,我們可以很迅捷地搭建出複雜的介面,也就是說能為我們節省大量的時間。我們還可以很直觀地看出各個介面之間的關係,修改起來也很方便。將來如果遇到需要作修改的地

iOS介面與返回程式碼實現(Objective-C)

       我們知道,現在的介面設計與跳轉都可以使用storyboard和segue來實現。但是有些專案組或者boss不喜歡這樣簡單視覺化的形式,非要用程式碼來實現整個UI的設計,與介面跳轉的邏輯,當然原因有各種。所以,現在我來為大家來簡單實現如何使用程式碼來構建UI控制

Android開發Intent到系統應用中的撥號介面、聯絡人介面、簡訊介面

現在開發中的功能需要直接跳轉到撥號、聯絡人、簡訊介面等等,查找了很多資料,自己整理了一下。          首先,我們先看撥號介面,程式碼如下: Intent intent =new Intent();                 intent.setAction("an

WPF Page 介面簡單框架DoubleAnimation動畫介面

介面顯示 public enum PageType { Index, Error, Copy, Wait, None } public class UICont

ios導航控制器UINavigationController,控制器a(push)到b後,b(push)到c,但c後退(pop)進入a

data- object tracking not another target eas com targe 參考:StackOverflow ios導航控制器UINavigationController,控制器a跳轉(push)到b後,b跳轉(push)到c。但c後退

js href點擊事件處理

js href和點擊事件處理跳轉<a class="yykf11" href="{:U(‘House/yuyue‘,array(‘esfid‘=>$house[‘esfid‘]))}" datatitle="預約看房">預約看房</a>$().((e){ userte

微信小程序頁面

spa 今天 style color log code body 微信 navigate 如今 微信小程序已經充滿的我們的生活,那麽今天我就來說一說微信小程序中的最基礎的 頁面跳轉 1. wx.navigateTo(保留當前頁面,跳轉到應用內的某個頁面,使用wx.nav

Metronic5.1 mDatatable插入記錄編輯記錄後的簡單實現

spa load() page fun metronic 記錄 app cti last 插入記錄: datatable.reload(); $(‘.m_datatable .m-datatable__pager-nav .m-datatable__pager-link-

Java逆向基礎條件位運算循環

java分支循環位運算本文參考:http://www.vuln.cn/7117 條件跳轉的例子,絕對值public class abs { public static int abs(int a) { if (a<0) return -a;

返回 字符串的 formjs組合讓頁面

back ucc mes reac mount new eth ons result router.get("/wy/jhy").handler(ctx->{ ctx.request().response().setChunk

PYQT5登入介面介面方法

該問題,有很多種方法,但是很多方法要麼這個有問題,要麼那個有問題,最後終於找到一種沒問題的方法。記錄一下: 參考地址:https://www.jianshu.com/p/d18ff36a78d6?from=singlemessage   Login.py(登入視窗)檔案 import