<iOS和Unity交互>之界面跳转

来源:互联网 发布:正规淘宝刷销量平台 编辑:程序博客网 时间:2024/06/11 10:57

本文摘自cherish_joy :http://blog.csdn.net/cherish_joy/article/details/72770624

本文介绍了iOS和Unity交互,主要涉及两个界面之间的跳转.

如果对iOS和Unity交互传参方法不熟悉的朋友,可以参考cherish_joy的另一篇文章 
iOS和Unity交互之参数传递

http://www.jianshu.com/p/86c4d9c9dafe

一.程序启动入口.

  • 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;   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

根据代码得知,程序需要创建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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

打印结果为:

2017-05-24 04:50:09.597338+0800 ProductName[5622:1888712] [DYMTLInitPlatform] platform initialization successful2017-05-24 04:50:09.693476+0800 ProductName[5622:1888655] -> registered mono modules 0x100df3fa02017-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 Enabled2017-05-24 04:50:10.014789+0800 ProductName[5622:1888655] Metal API Validation Enabled2017-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 640x1136Initializing Metal device caps: Apple A7 GPUInitialize engine version: 5.3.5f1 (960ebf59018a)UnloadTime: 2.714958 msSetting up 1 worker threads for Enlighten.Thread -> id: 16ea3b000 -> priority: 1 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

根据带(标记)的打印结果得知

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    }  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 添加属性,该属性用来保存创建的iOS控制器(尽量设置为私有属性)
@interface UnityAppController ()@property (nonatomic, strong) UIViewController *vc;@end
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
  • 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; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

说明: 
1.GetAppController() 
跳转到GetAppController()方法内部,实现如下,可以看出,该方法获取到UIApplication的单例类,而它的代理,则为UnityAppController对象,最后再使用(UnityAppController*)进行强制转换.所以,在UnityAppController.mm文件中使用GetAppController()相当于self.

inline UnityAppController *GetAppController(){    return (UnityAppController*)[UIApplication sharedApplication].delegate;}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2.UnityGetGLViewController() 
返回Unity的根控制器,根控制器上的视图是Unity的视图.,如果将窗口的根控制器设置为UnityGetGLViewController(),其实就是将Unity界面显示在手机上.

extern "C" UIViewController *UnityGetGLViewController(){     return GetAppController().rootViewController; }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

3.UnityGetGLView() 
返回Unity视图,这个视图其实就是显示在UnityGetGLViewController()上的.

extern "C" UIView *UnityGetGLView(){    return GetAppController().unityView; }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

三.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界面"); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

四.封装界面跳转代码.

查看UnityAppController.mm文件,发现其中代码太多,为了减少代码以及便于我们管理和维护,我们要创建一个单例类来管理Unity和iOS界面互相跳转的操作.之前在UnityAppController.mm文件中写的代码全部删除.

1.需要创建一个自定义类,如:BYJumpEachOther,继承至NSObject.

2.添加属性

// 存储的iOS控制器@property (nonatomic, strong) UIViewController *vc;
  • 1
  • 2
  • 1
  • 2

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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

4.添加BYJumpEachOther创建单例的方法

+ (instancetype)sharedInstance{    static BYJumpEachOther *instance;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        instance = [[BYJumpEachOther alloc] init];    });    return instance;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

6.跳转Unity界面代码

// 设置Unity界面  - (void)setupUnity{    UnityPause(false);    GetAppController().window.rootViewController = UnityGetGLViewController();    // 等同于    // GetAppController().window.rootViewController = GetAppController().rootViewController;    NSLog(@"设置rootView为Unity界面");}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10