本文摘自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
一.程序启动入口.
了解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
打印结果为:
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("__Internal")] private static extern void unityToIOS(string str); public void turnRight(string num) { float f; if (float.TryParse(num, out f)) { 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)) { 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
Unity会调用unityToIOS
方法,跳转iOS界面之前,先暂停Unity,即UnityPause(true);
方法.因为在C语言中,不能直接使用self调用对象方法.所以需要通过GetAppController()
调用setupIOS
方法.GetAppController()
即UnityAppController类型的对象.在setupIOS
方法中,让
UnityAppController对象持有vc后,再将vc直接设置为窗口的跟控制器.GetAppController().window.rootViewController = GetAppController().vc;
unityToIOS方法
extern "C" void unityToIOS(char *str) { NSLog(@"%s",str); UnityPause(true); [GetAppController() setupIOS]; GetAppController().window.rootViewController = GetAppController().vc; }
- (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;}
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 方法
- (void)setupUnity { UnityPause(false); self.window.rootViewController = self.rootViewController; NSLog(@"设置rootView为Unity界面"); }
四.封装界面跳转代码.
查看UnityAppController.mm
文件,发现其中代码太多,为了减少代码以及便于我们管理和维护,我们要创建一个单例类来管理Unity和iOS界面互相跳转的操作.之前在UnityAppController.mm
文件中写的代码全部删除.
1.需要创建一个自定义类,如:BYJumpEachOther
,继承至NSObject
.
2.添加属性
@property (nonatomic, strong) UIViewController *vc;
3.入口:unityToIOS,与之前不同的是,调用setupIOS
方法,改为单例对象去调用[[BYJumpEachOther sharedInstance] setupIOS];
获取vc也通过单例对象去获取.
extern "C" void unityToIOS(char *str){ NSLog(@"%s",str); UnityPause(true); [[BYJumpEachOther sharedInstance] setupIOS]; 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;}
5.跳转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界面代码
- (void)setupUnity{ UnityPause(false); GetAppController().window.rootViewController = UnityGetGLViewController(); NSLog(@"设置rootView为Unity界面");}