之介面跳轉
本文摘自cherish_joy :http://blog.csdn.net/cherish_joy/article/details/72770624
本文介紹了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 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
- 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