本文主要讲述 iOS原生项目集成Unity3D项目的关键点说明
- 集成环境
Unity 版本2019.4.13f1c1
Xcode 版本12.5.1
- 新建workspace管理 原生工程 和 Unity3D 导出的工程,目录结构如下
- 设置 Unity 工程
Data
文件夹 target ,勾选UnityFramework
,并编译工程
- iOS原生工程 添加
UnityFramework
添加
- iOS 原生工程
Build Phases
中 移除UnityFramework
此处移除
以上 ,第一部分完成,接下来介绍如何调用Unity工程
-
main.m
文件中缓存启动参数,供其他地方初始化 Unity使用
-
AppDelegate.h
文件导入头文件,并新增属性方法,如下图
-
Appdelegate.m
文件实现代码如下
#import "AppDelegate.h"
#import "ViewController.h"
#import "YBHandler.h"
/* UnityFrameworkLoad */
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])
{
// unity is not initialized
[ufw setExecuteHeader: &_mh_execute_header];
}
return ufw;
}
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
/* 保存参数 */
[[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];
UINavigationController *mainNav = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
self.window.rootViewController = mainNav;
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
{
/* 判断Unity 是否已经初始化 */
if ([self unityIsInitialized]) return;
/* 初始化Unity */
self.ufw = UnityFrameworkLoad();
[self.ufw setDataBundleId:"com.unity3d.framework"];
[self.ufw registerFrameworkListener:self];
[NSClassFromString(@"FrameworkLibAPI") registerAPIforNativeCalls: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];
[self.ufw sendMessageToGOWithName:"MainPageCanvas" functionName:"native2unity" message:"Hello, Message from iOS Native."];
}
- (void)showUnityMainWindow
{
if (![self unityIsInitialized]){
NSLog(@"Unity 还未初始化");
}
[self.ufw showUnityWindow];
}
#pragma mark - UnityFrameworkListener
- (void)unityDidUnload:(NSNotification *)notification
{
NSLog(@"========== %s ============",__func__);
[self.window makeKeyAndVisible];
}
- (void)unityDidQuit:(NSNotification *)notification
{
NSLog(@"========== %s ============",__func__);
}
- (void)funciton1
{
NSLog(@"funciton1 被调用");
// [self.ufw unloadApplication];
[self.window makeKeyAndVisible];
}
- (void)funciton2:(NSString *)message
{
NSLog(@"hello ========= %@",message);
}
- (void)funciton3
{
NSLog(@" funciton3 ======");
}
@end
-
ViewController.m
文件新增两个按钮,测试调用Unity功能,代码如下
#import "ViewController.h"
#import "AppDelegate.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
self.navigationItem.title = @"Unity Demo";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"初始化" style:UIBarButtonItemStylePlain target:self action:@selector(initUnityAction)];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"主界面" style:UIBarButtonItemStylePlain target:self action:@selector(showUnityAction)];
}
- (void)initUnityAction
{
/* 初始化 Unity并展示 Unity 界面 */
AppDelegate *appDelegate = (AppDelegate *)([UIApplication sharedApplication].delegate);
[appDelegate initUnity];
}
- (void)showUnityAction
{
/* 展示Unity 界面 */
AppDelegate *appDelegate = (AppDelegate *)([UIApplication sharedApplication].delegate);
[appDelegate showUnityMainWindow];
}
@end
至此,第二部分完成,已经可以完成在原生项目中启动Unity工程,展示Unity界面,接下来讲解如何实现 iOS与Unity 交互
- iOS 调用 Unity 方法,直接使用 UnityFramework中的
sendMessageToGOWithName
方法即可
- (void)sendMessageToGOWithName:(const char*)goName functionName:(const char*)name message:(const char*)msg;
image.png
image.png
- Unity 调用 iOS方法
(1)Unity 开发人员在 Unity 工程中就添加好Plugins文件夹,并添加好两个文件,可👉参考视频
NativeCallProxy.h
文件
#import <Foundation/Foundation.h>
// NativeCallsProtocol defines protocol with methods you want to be called from managed
@protocol NativeCallsProtocol
@required
- (void)funciton1;
- (void)funciton2:(NSString *)message;
- (void)funciton3;
@end
__attribute__ ((visibility("default")))
@interface FrameworkLibAPI : NSObject
// call it any time after UnityFrameworkLoad to set object implementing NativeCallsProtocol methods
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi;
@end
NativeCallProxy.mm
文件
#import <Foundation/Foundation.h>
#import "NativeCallProxy.h"
@implementation FrameworkLibAPI
id<NativeCallsProtocol> api = NULL;
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi
{
api = aApi;
}
@end
extern "C" {
void fun1() {
return [api funciton1];
};
void fun2(const char * message){
return [api funciton2:[NSString stringWithUTF8String:message]];
};
void fun3(){
return [api funciton3];
};
}
(2) 原生工程需要在Build Settings
> Header Search Paths
中设置 Unity 工程路径,这样才可以在AppDelegate.h
文件中引入 👆的NativeCallProxy
文件
(3)在AppDelegate.h
文件中引入 👆的NativeCallProxy
文件
(4)在AppDelegate.m
文件注册下 协议,并实现协议中的方法
按照以上步骤,基本上可以完成 iOS原生项目集成Unity3D项目
附官方集成说明:
Unity iOS设置
将 Unity 集成到原生 iOS 应用程序中
Unity github 说明文档
网友评论