相关文章推荐
大气的伏特加  ·  python - How to ...·  1 年前    · 
冷静的树叶  ·  流粼 - 知乎·  1 年前    · 
从容的饭卡  ·  用户对问题“Spring ...·  1 年前    · 

在上一篇文章中,已经将unity框架嵌入到我们的xcode项目中了 传送门
接下来,就要在项目中跑起来Unity里面的东西了。其实,如果交互不多的话,我们需要做的东西很少,基本上Unity已经全部做好了,但是安装包会增大很多,如果长期嵌入的话,需要再对安装包做一下处理,让安装包小一些。

正题(添加Unity的代码):

在AppDelegate.h里添加

// Unity文件
#import "UnityAppController.h"
//----------------- 以下参数仅仅用于Unity -----------------//
/// Unity 的 AppDelegate
@property (strong, nonatomic) UnityAppController *unityController;
/// Unity 显示视图
@property (strong, nonatomic) UIWindow *unityWindow;
- (void)showUnityWindow;
- (void)hideUnityWindow;
//----------------- 以上参数仅仅用于Unity -----------------//

在AppDelegate.m里添加

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Unity
    _unityController = [[UnityAppController alloc] init];
    [_unityController application:application didFinishLaunchingWithOptions:launchOptions];
//程序进入前台并处于活动状态时调用
- (void)applicationDidBecomeActive:(UIApplication *)application {
	 [self.unityController applicationDidBecomeActive:application];
// APP从后台进入前台
- (void)applicationWillEnterForeground:(UIApplication *)application{
	[self.unityController applicationWillEnterForeground:application];
	APP从前台进入后台
-(void)applicationDidEnterBackground:(UIApplication *)application {
  	[self.unityController applicationDidEnterBackground:application];
	#pragma mark 应用终止
-(void)applicationWillTerminate:(UIApplication *)application {
	[self.unityController applicationWillTerminate:application];
		#pragma mark =================== Unity ===================
-(void)applicationWillResignActive:(UIApplication *)application {
	[_unityController applicationWillResignActive:application];
/// 显示AR页面
-(void)showUnityWindow{
	[self.unityWindow makeKeyAndVisible];
-(void)hideUnityWindow{
	[self.window makeKeyAndVisible];
-(UIWindow *)unityWindow{
 return  UnityGetMainWindow();

调用方法,进入和退出Unity Windows

-(void)go {
	//进入unity界面
	[(AppDelegate *)[UIApplication sharedApplication].delegate showUnityWindow];
	UnityPause(false);
- (void)quit{
    //退出unity界面
    UnityPause(true);
    [(AppDelegate *)[UIApplication sharedApplication].delegate hideUnityWindow];

Unity调用iOS方法

RegisterMonoModules.h 文件里填写相应的方法

void getLevelAndCoin();

如果需要调用传递返回值的方法,也需要写成void类型 RegisterMonoModules.mm 不需要写对一个的方法

UnityAppController.mm里边填写对应的方法实现

extern "C"
    const char* getLevelAndCoin(){
        // do something
        return strdup([@"Test" UTF8String]);
复制代码

返回类型要通过strdup封装一下,直接return “Test” 会运行时崩溃

iOS调用Unity方法 iOS调用Unity方法,比较简单,直接让他们提供相应的方法即可
如果通过Swift调用,需要在桥接文件里导入一下#import <Classes/Unity/UnityInterface.h>

接入Unity后,SSZipArchive会在解压时崩溃

现象是会在解压时,这个方法会报内存错误:
unzOpenCurrentFile

Thread 39: EXC_BAD_ACCESS (code=1, address=0x1177140)

找了一些资料,和很多种解决办法,都无法解决,原因应该和负责Unity同事的说法差不多

因为引入的多个库中都有结构体unz_file_info,但是他们的定义不一样(一个库是ZipArchive一个是Zip,还有是引入的.a中也存在这个结构体,我们在继续看为啥没报符号表冲突的问题)。在实际运行的时候,变量directoriesModificationDates被污染了。找了一下原因,是因为实际使用的unz_file_info的定义不是ZipArchive库中的,而是其他的。在Runtime时unz_file_info与ZipArchive中的定义的内部布局不一致。于是污染了堆栈,于是directoriesModificationDates指针就意外的被换成了脏数据。这也就是为什么,在调用之前加了一个没有啥用的fileInfoFake,就能正常使用的原因。 fileInfoFake所在的内部被污染了,防止了其他变量被污染。 造成这个问题的原因,是库冲突导致的。看了一下Zip、ZipArchive都直接源码引用了minizip的代码。为了避免这种冲突的问题,还是建议要么直接把minizip抽成一个库。要么重命名一下使用到的minizip符号。避免这种隐藏极深的问题。

我将ZipArchive封装成一个framework或者.a的静态库都会造成崩
最后不得不换了一个解压框架 ——_—— ZipZap

如果有人知道这个框架冲突的问题怎么解决,劳烦解惑一下

分类:
iOS
  •