上篇博客我说了集成,这里我说一下交互
一、Unity 使用
直接上代码
AppDelegate.h
#import <UIKit/UIKit.h>
#include <UnityFramework/UnityFramework.h>
#include <UnityFramework/NativeCallProxy.h>
@interface AppDelegate : UIResponder<UIApplicationDelegate, UnityFrameworkListener, NativeCallsProtocol>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, strong) UIButton *showUnityOffButton;
@property (nonatomic, strong) UIButton *btnSendMsg;
@property (nonatomic, strong) UINavigationController *navVC;
@property (nonatomic, strong) UIButton *unloadBtn;
@property (nonatomic,strong) NSDictionary * appLaunchOpts;
@property UnityFramework* ufw;
- (void)initUnity;
- (void)ShowMainView;
- (void)didFinishLaunching:(NSNotification*)notification;
- (void)didBecomeActive:(NSNotification*)notification;
- (void)willResignActive:(NSNotification*)notification;
- (void)didEnterBackground:(NSNotification*)notification;
- (void)willEnterForeground:(NSNotification*)notification;
- (void)willTerminate:(NSNotification*)notification;
- (void)unityDidUnloaded:(NSNotification*)notification;
@end
Appdelegate.m
#import "AppDelegate.h"
#import "INUnityDefault.h"
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;
}
void showAlert(NSString* title, NSString* msg) {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
AppDelegate * delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.window.rootViewController presentViewController:alert animated:YES completion:nil];
}
@implementation AppDelegate
- (bool)unityIsInitialized { return [self ufw] && [[self ufw] appController]; }
- (void)ShowMainView
{
if(![self unityIsInitialized]) {
showAlert(@"Unity is not initialized", @"Initialize Unity first");
} else {
[[self ufw] showUnityWindow];
}
}
- (void)showHostMainWindow
{
[self showHostMainWindow:@""];
}
- (void)showHostMainWindow:(NSString*)color
{
[self.window makeKeyAndVisible];
}
- (void)sendMsgToUnity{
[[self ufw] sendMessageToGOWithName: "Scene" functionName: "turnRight" message: "3"];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// hostDelegate = self;
self.appLaunchOpts = launchOptions;
self.window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
INLoginViewController * root = [[INLoginViewController alloc] init];
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:root];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
/// 打开Unity
- (void)initUnity
{
if([self unityIsInitialized]) {
showAlert(@"Unity already initialized", @"Unload Unity first");
return;
}
[self setUfw: UnityFrameworkLoad()];
// Set UnityFramework target for Unity-iPhone/Data folder to make Data part of a UnityFramework.framework and uncomment call to setDataBundleId
// ODR is not supported in this case, ( if you need embedded and ODR you need to copy data )
[[self ufw] setDataBundleId: "com.unity3d.framework"];
[[self ufw] registerFrameworkListener: self];
[NSClassFromString(@"FrameworkLibAPI") registerAPIforNativeCalls:self];
[[self ufw] runEmbeddedWithArgc: [INUnityDefault shareUnity].gArgc argv: [INUnityDefault shareUnity].gArgv appLaunchOpts: self.appLaunchOpts];
UIView * view = [[[self ufw] appController] rootView];
}
/// 退出Unity
- (void)unloadButtonTouched:(UIButton *)sender
{
if(![self unityIsInitialized]) {
showAlert(@"Unity is not initialized", @"Initialize Unity first");
} else {
[UnityFrameworkLoad() unloadApplication];
}
}
/// 退出Unity
- (void)unityDidUnload:(NSNotification*)notification
{
NSLog(@"unityDidUnloaded called");
[[self ufw] unregisterFrameworkListener: self];
[self setUfw: nil];
[self showHostMainWindow:@""];
}
- (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]; }
@end
main.m
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "INUnityDefault.h"
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
appDelegateClassName = NSStringFromClass([AppDelegate class]);
}
///记录 argc argv 参数 在appdelegate 中使用
[INUnityDefault shareUnity].gArgc = argc;
[INUnityDefault shareUnity].gArgv = argv;
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
二、原生向Unity发消息
[[self ufw] sendMessageToGOWithName: "Scene" functionName: "turnRight" message: "3"];
scene 是与Unity 同学约定好的参数
turnRight 是调用 Unity项目的某个方法
3 是要给该方法中传的参数,当有多个参数时建议传json串
三、Unity调用原生方法
这时候就要用到 NativeCallProxy.h桥接文件了
NativeCallProxy.h
#import <Foundation/Foundation.h>
// NativeCallsProtocol defines protocol with methods you want to be called from managed
@protocol NativeCallsProtocol
@required
/**
将要调用的Unity中的方法 该代理方法应该在Appdelegate 文件中实现
当然也可以在该代理中 添加其他方法
*/
- (void) showHostMainWindow:(NSString*)color;
// other methods
@end
__attribute__ ((visibility("default")))
@interface FrameworkLibAPI : NSObject
// call it any time after UnityFrameworkLoad to set object implementing NativeCallsProtocol methods
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi;
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 showHostMainWindow(const char* color) { return [api showHostMainWindow:[NSString stringWithUTF8String:color]]; }
}
这样就可以相互调用了
我是磊怀 2849765859 QQ 如有疑问我们一起探讨