美文网首页程序员
UnityAppController的定制以及Unity引擎的I

UnityAppController的定制以及Unity引擎的I

作者: lumic000 | 来源:发表于2020-03-09 15:46 被阅读0次

    开发 Unity3d 手机游戏的时候,不免要和第三方 SDK 打交道。于是总是需要实现自己的 AppController 来维护 SDK 的生命周期。

    Unity3d 提供了一套插件机制,可以很方便地在项目中使用自己的 CustomAppController 继承并重写默认的 UnityAppController 的方法。

    CustomAppController

    在 Unity 插件目录下创建以下文件:

    ​/path/to/unity/project/Assets/Plugins/iOS/CustomAppController.mm​

    注意:

    文件名必须是 ___AppController,前缀可自选,但不能省略;否则在 Build 项目的时候,会被移动到错误的目录中去。

    下面是集成BBase的入口,也是程序的入口

    `//`
    
    `//  CustomAppController.m`
    
    `// `
    
    `#import  "UnityAppController.h"`
    
    `#import <BBase/BBaseManager.h>`
    
    `@interface CustomAppController : UnityAppController`
    
    `@end`
    
    `IMPL_APP_CONTROLLER_SUBCLASS (CustomAppController)`
    
    `@implementation CustomAppController`
    
    `- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions`
    
    `{`
    
    `    [super application:application didFinishLaunchingWithOptions:launchOptions];`
    
    `    [BBaseManager.sharedManager loadConfigureWithApplication:application registerPushNotificationLater:YES itunesConnectSharedSecret:@"" needReceiptVerification:YES gdprAppName:@"" gdprAgreementLink:@"" gdprPolicyLink:@"" ezalterDiversions:nil defaultEzalterParams:nil activateSuccessHandler:^(NSDictionary * _Nonnull json, NSString * _Nullable token) {`
    
    `    } activateFailureHandler:^(NSError * _Nonnull error) {`
    
    `    } activeSuccessHandler:^(NSDictionary * _Nonnull json) {`
    
    `    } activeFailureHandler:^(NSError * _Nonnull error) {   `
    
    `    }];`
    
     `return YES;`
    
    `}`
    
    `@end`
    

    在 Build iOS Project 的时候,Unity 会自动把 CustomAppController.mm 复制到 ​/path/to/project/Libraries/CustomAppController.mm​

    而原来的 UnityAppController.mm 则在 ​/path/to/project/Classes/UnityAppController.mm​

    Unity 通过 ** IMPL_APP_CONTROLLER_SUBCLASS **知道要使用我们定制的 CustomAppController 而不是使用默认的 UnityAppController

    IMPL_APP_CONTROLLER_SUBCLASS

    UnityAppController.h 里面有这样一个宏:

    `#define IMPL_APP_CONTROLLER_SUBCLASS(ClassName) \`
    
    `@interface ClassName(OverrideAppDelegate)       \`
    
    `{                                               \`
    
    `}                                               \`
    
    `+(void)load;                                    \`
    
    `@end                                            \`
    
    `@implementation ClassName(OverrideAppDelegate)  \`
    
    `+(void)load                                     \`
    
    `{                                               \`
    
    `    extern const char* AppControllerClassName;  \`
    
    `AppControllerClassName = #ClassName;        \`
    
    `}                                               \`
    
    `@end`
    
    

    将这个宏加到 CustomAppController.mm 中,即可实现自动设置 AppControllerClassName :

    `IMPL_APP_CONTROLLER_SUBCLASS (CustomAppController)`
    

    IMPL_APP_CONTROLLER_SUBCLASS 使用了两个 Objective-C 的特性,一是 ​category​ ,用来给已有的类扩展新的方法;二是 ​+(void)load​ 静态方法,它会在运行时 CustomAppController 类被加载到内存中时触发,这个时间点比 ​int main()​ 函数还要早,所以能够提前“篡改” ​AppControllerClassName​,达到我们的目的。

    • 程序入口
      程序的入口为main.mm文件,通过IMPL_APP_CONTROLLER_SUBCLASS 调用了自定义继承UnityAppController的 CustomAppController文件,在该文件的 下面这个方法- (BOOL)application:(UIApplication)application didFinishLaunchingWithOptions:(NSDictionary)launchOptions; 中注册了BBase,调用父类UnityAppController中的方法,实现UI的创建

    iOS平台Unity引擎的IL2CPP机制

    实现原理

    Unity引擎作为目前最为主流的3D游戏开发引擎,游戏平台移植性非常好,Unity引擎4.6.2之后的版本采用了IL2CPP机制支持IOS平台64位游戏编译,针对IL2CPP机制进行深入分析之后有利于评估IOS平台的Unity游戏安全性。

    image

    Unity引擎采用IL2CPP机制在Mac平台成功编译之后,会生成一个完整的XCode工程,Unity游戏逻辑代码采用C#编写,游戏开发方的C#代码最终会生成在/Classes/Native目录中,对应文件结构如下图所示:

    image

    UI显示机制

         Unity导出的iOS工程里面的结构大致是这样的,有一个Window,Window上有一个UnityView,但是并没有控制器,也没有根控制器,虽然在导出的iOS工程中Classes文件夹下的UnityAppController中有rootController的属性,但是上面也标注为空~ 直接在window上显示Unity界面的
    
    image

    导出xcode项目后,会产生DisplayManager 这样的一个显示管理器文件, 该文件中会辅助UnityView,Keyboard等等Unity转成iOS的View的显示,在DisplayManager 这个类中,引入了EAGLContext,通过OpenGL 去实现UI 的绘制

    注释:

    1. CAEAGLLayer 支持在iOS和tvOS应用程序中绘制OpenGL内容的图层。

    2.​EAGLContext​对象管理一个OpenGL ES 渲染上下文 状态信息,命令和使用OpenGL ES绘制所需要的资源。要执行OpenGL ES命令,您需要当前的渲染上下文。

    补充:

    Unity中的ViewController

    Unity中没有viewcontroller的概念,页面之间的切换其实就是在同一个viewcontroller上重绘不同的view,一个叫做UnityView的UIView来显示绘制的页面。

    但既然要在iOS上显示界面,就必须要有一个viewcontroller的载体。Unity中没有,所以Unity中有一个_viewControllerForOrientation[5]的数组来维持屏幕4个方向的viewcontroller+autorotate的viewcontroller,也就是说Unity中从始至终最多只有5个viewcontroller。

    viewcontroller如何切换

    如果现在要显示竖屏页面,就从数组中取出竖屏的viewcontroller,如果没有就创建一个,然后将_unityView赋值给竖屏的viewcontroller.view,如果现在要进入横屏页面,就从数据中取出横屏的viewcontroller,然后将_unityView赋值给横屏的viewcontroller.view。

    createDisplayLink

    那么手机从竖屏变成横屏后什么时候重绘呢,什么时候显示呢?这个时候就需要createDisplayLink函数,它会创建一个60Hz的timer,为什么是60,因为iPhone的屏幕刷新率就是60Hz,每次的timer执行函数中会去检查当前要显示哪个viewcontroller,以及是否需要重绘,然后显示

    相关文章

      网友评论

        本文标题:UnityAppController的定制以及Unity引擎的I

        本文链接:https://www.haomeiwen.com/subject/kgypdhtx.html