- 创建空白Unity工程,导出iOS项目(UnityiOSDemo)
- 创建空白iOS项目(iOSUnityDemo)
- 打开Xcode,新建xcworkspace(iOS&&Unity)
- 把UnityiOSDemo和iOSUnityDemo导入iOS&&Unity
- 选择UnityiOSDemo scheme 进行编译,这一步是为了获得UnityFramework.framework
- 选中UnityiOSDemo工程中的Data目录,将Target Membership更改为UnityFramework
- 选中iOSUnityDemo工程,在General-Frameworks,Libraries,and Embedded Content 添加UnityFramework.framework
- 选中iOSUnityDemo工程,在Build-Phases-Link Binary With Libraries 中删除UnityFramework.framework
- 此时准备工作已就绪
如何切换iOS原生页面和Unity页面
#import <UIKit/UIKit.h>
#include <UnityFramework/UnityFramework.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, UnityFrameworkListener>
@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, strong) UnityFramework *ufw;
- (void)initUnity;
- (void)showUnityMainWindow;
- (void)showNativeMainWindow;
@end
#import "AppDelegate.h"
#import "ViewController.h"
#import <UnityFramework/UnityFramework.h>
UIKIT_STATIC_INLINE UnityFramework* UnityFrameworkLoad() {
NSString* bundlePath = nil;
bundlePath = [[NSBundle mainBundle] bundlePath];
bundlePath = [bundlePath stringByAppendingString: @"/Frameworks/UnityFramework.framework"];
NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
if ([bundle isLoaded] == false) [bundle load];
UnityFramework* ufw = [bundle.principalClass getInstance];
if (![ufw appController]) {
[ufw setExecuteHeader: &_mh_execute_header];
}
return ufw;
}
@interface AppDelegate ()
@property (nonatomic, strong) UIViewController *nativeRootVC;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSUserDefaults standardUserDefaults] setValue:launchOptions forKey:@"launchOptions"];
[[NSUserDefaults standardUserDefaults] synchronize];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
self.nativeRootVC = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
self.window.rootViewController = self.nativeRootVC;
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
[[[self ufw] appController] applicationWillResignActive: application];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[[[self ufw] appController] applicationDidEnterBackground: application];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[[[self ufw] appController] applicationWillEnterForeground: application];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[[self ufw] appController] applicationDidBecomeActive: application];
}
- (void)applicationWillTerminate:(UIApplication *)application {
[[[self ufw] appController] applicationWillTerminate: application];
}
#pragma mark - Unity
- (BOOL)unityIsInitialized {
return [self ufw] && [[self ufw] appController];
}
- (void)initUnity {
if ([self unityIsInitialized]) return;
self.ufw = UnityFrameworkLoad();
[self.ufw setDataBundleId:"com.unity3d.framework"];
[self.ufw registerFrameworkListener:self];
NSString *argvStr = [[NSUserDefaults standardUserDefaults] valueForKey:@"argv"];
char **argv;
sscanf([argvStr cStringUsingEncoding:NSUTF8StringEncoding], "%p",&argv);
int argc = [[[NSUserDefaults standardUserDefaults] valueForKey:@"argc"] intValue];
NSDictionary *launchOptions = [[NSUserDefaults standardUserDefaults] valueForKey:@"launchOptions"];
[self.ufw runEmbeddedWithArgc:argc argv:argv appLaunchOpts:launchOptions];
}
- (void)unityRootVCAddNavgationController {
UIViewController *rootVC = [[self ufw] appController].rootViewController;
[[self ufw] appController].window.rootViewController = nil;
[[self ufw] appController].window.rootViewController = [[UINavigationController alloc] initWithRootViewController:rootVC];
[rootVC.navigationController setNavigationBarHidden:true];
}
- (void)showUnityMainWindow {
self.window.hidden = YES;
[self.ufw appController].window.hidden = NO;
if (![self unityIsInitialized]){
NSLog(@"Unity 还未初始化");
return;
}
[self.ufw showUnityWindow];
[self.ufw pause:false];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self unityRootVCAddNavgationController];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.ufw sendMessageToGOWithName:"Canvas" functionName:"outputStr" message:"Hello, Message from iOS Native."];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self unityRootVCPushVC];
});
}
- (void)showNativeMainWindow {
self.window.hidden = NO;
[self.ufw appController].window.hidden = YES;
self.window.rootViewController = self.nativeRootVC;
[self.window makeKeyAndVisible];
}
- (void)unityRootVCPushVC {
UIViewController *foo = [[UIViewController alloc] init];
foo.view.backgroundColor = [UIColor whiteColor];
[[[self ufw] appController].rootViewController.navigationController pushViewController:foo animated:YES];
}
#pragma mark - UnityFrameworkListener
- (void)unityDidUnload:(NSNotification *)notification {
NSLog(@"========== %s ============",__func__);
[self.ufw unregisterFrameworkListener:self];
[self setUfw:nil];
[self.window makeKeyAndVisible];
}
- (void)unityDidQuit:(NSNotification *)notification {
NSLog(@"========== %s ============",__func__);
}
@end
iOS调用Unity方法
void UnitySendMessage(const char* obj, const char* method, const char* msg);
Unity调用iOS方法
1、在Unity项目Plugins中添加插件文件,例如Test.mm
#import <Foundation/Foundation.h>
extern "C" {
void iOSLog(const char * message);
}
void iOSLog(const char * message) {
NSLog(@"%@", [NSString stringWithUTF8String:message]);
}
2、在Unity项目脚本中,调用iOS方法,例如
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
public class CallObjC : MonoBehaviour
{
public InputField input;
#if UNITY_IPHONE
[DllImport("__Internal")]
static extern void iOSLog(string message);
[DllImport("__Internal")]
static extern void iOSLog2(string message);
#endif
public void onButtonClick()
{
outputStr("test");
iOSLog(input.text);
iOSLog2(input.text);
}
public void outputStr(string resultStr)
{
Debug.LogFormat("result string = {0}", resultStr);
}
}