iOS Unity 項目解析


本文旨在記錄Unity 導出的iOS 項目筆記,另帶接入SDK的終極方案,順帶對比Android 項目

1藍色的目錄 Data 這個就是項目的數據,每個項目不一樣也就是這個目錄不一樣,是不是可以把這個目錄刪掉,

把新倒出項目Data 拷貝過來就完成項目導出(我試過了不可以了QvQ)。

2Images.xcassets 這個就是圖片目錄類似 Android Drable 項目圖片資源

3Main.mm  工程入口

4Class 黃色目錄 這個目錄類容多,也是最重要的

  PluginBase 一共四個類接入SDK 的關鍵類

  AppDelegateListener 顧名思義這個是App代理類,此代理非Java代理,更像是Java的接口,對應Android Activity而不是

  UIApplication,這一點apple和谷歌確實有區別,Apple更為嚴謹。一般sdk要接入 在適當的位置(適當的位置一定是init方法,因為一般sdk要接入app啟動的監聽,晚了就監聽不到了)

  UnityRegisterAppDelegateListener 方法傳入 實現了AppDelegateListener 代理對象

  LifeCycleListener app生命周期監聽Android 也是在UIApplication 和Activity中,這也導致了Android Activity 業務太多類寫的太復雜不易維護

  UnityRegisterLifeCycleListener 注冊聲明周期監聽,要注意的是注冊UnityRegisterAppDelegateListener 就會自動注冊生命周期監聽

  RenderPluginDelegate對應Activity controller 方法,但是Activity 不僅僅是一個view的控制器,apple就分的非常細,更加的面向對象

  - (void)mainDisplayInited:(struct UnityDisplaySurfaceBase*)surface;

  - (void)onBeforeMainDisplaySurfaceRecreate:(struct RenderingSurfaceParams*)params;

  - (void)onAfterMainDisplaySurfaceRecreate;

  - (void)onFrameResolved;--onCreat

  - (void)didBecomeActive:(NSNotification*)notification;--onStart

  - (void)willResignActive:(NSNotification*)notification;

  - (void)didEnterBackground:(NSNotification*)notification;--> Android 進入后台,apple 分的細 前后都有調用

  - (void)willEnterForeground:(NSNotification*)notification;-->

  - (void)willTerminate:(NSNotification*)notification; -->其實也挺亂的 Activity 的onFinishi 方法(我可能沒記住)

      這個不是注冊監聽的方式,是寫一個代理的實現類在main方法加載之前賦值上去的在實現類mm文件結尾加

  沒有仔細研究,先挖一坑,我后面抽空填上

  UnityViewControllerListener 這個也是Activity ,哈哈我都無語了,android activity 可以存放很多view ios 一個控制器一般

  只會控制一個view ,控制器可以有子控制器來控制多個view。

  這四個或者三個就包含了skd要的所有方法比喻。啟動,獲取 設備token,app跳轉監聽,獲取view 控制器。

  之前我的做法是找到 UnityAppController 和ViewController 中的方法挨個加,容易出錯不說,他有很多平台方法都長一樣容易出錯,

  而sdk接入是否成功有的只有發行那邊知道,發行說沒對,來回搞浪費時間,要加班的哦。

  這個方法要改unity代碼其實是不對的,就比如你拿到一個SDK,要改SDK代碼一樣,一般是實現接口,獲取數據做業務。

  UnityIos 不需要修改unity代碼 是繼承UnityAppController 在他的 mm文件加上

  IMPL_APP_CONTROLLER_SUBCLASS(SubClass),這個對象+Load()方法中告訴unity 啟動他的UnityAppController子類

  再在init方法中完成監聽注冊

  

- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"-------------");
        UnityRegisterAppDelegateListener(self);//注冊監聽
    }
    return self;
}

這樣可以不修改一句Unity 代碼完成sdk接入 Andorid 項目提供了一個UnityPlayerActivity 類供使用,我一般是在這個類的里改源碼接SDK,

這樣壞處就是Unity會升級,unity會改這里的代碼。 不能偷懶,之前我也不會。

接SDK的說完了

Classs/UI 這個就是UI業務了,我也挖個坑后面填

Classs/Unity unity的業務 調攝像頭,播放視屏啥的

Classs/下面還有10幾個類 崩潰日志,傳感器,編譯宏定義 pluginsbase 的實現類

Class/Native unity的c++代碼

UnityFramework 這個對unity的封裝了,比如你要繼承 生命周的類你要找到這些類的目錄,還有其他相關的類的頭文件都拷貝到了這個.h文件

在自己的代碼中加一句 

#import <UnityFramework/UnityFramework.h> 所有的你要想要的頭文件都幫你倒入了,看下他的代碼

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

#import "UnityAppController.h"

#include "UndefinePlatforms.h"
#include <mach-o/ldsyms.h>

 康康 UnityAppController.h

#import <QuartzCore/CADisplayLink.h>

#include "RenderPluginDelegate.h"

 好像有啥也沒有 但是對於高級應用而言已經夠了。

最后加上iOS 啟動播放視屏的方法(沒入門的都會,但是如果是天天搞Unity 確實讓人摸不到頭腦

//
//  MyApp.m
//  UnityFramework
//
//  Created by xiaolong on 2021/10/17.
//
#import <Foundation/Foundation.h>
#import "MyApp.h"
#import "AppDelegateListener.h"
#import "UnityViewControllerListener.h"
#import <AVKit/AVKit.h>
@interface MyApp()<AppDelegateListener,UnityViewControllerListener,LifeCycleListener>
@property(nonatomic,strong)AVPlayerViewController* pvc;
@property(nonatomic,assign)bool hasPaly;
@end


@implementation MyApp

- (instancetype)init
{
    self = [super init];
    if (self) {
        UnityRegisterAppDelegateListener(self);
        UnityRegisterViewControllerListener(self);
    }
    _hasPaly = FALSE;
    return self;
}

- (void)viewDidAppear:(NSNotification *)notification{
    
    if(_hasPaly == false){
        _hasPaly = true;
        NSLog(@"------------------------");
        
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"move.mov" withExtension:nil];
        self.pvc = [[AVPlayerViewController alloc] init];
        self.pvc.player = [AVPlayer playerWithURL:url];
        
        UIView* unityView = UnityGetGLViewController().view;
        CGSize s = unityView.bounds.size;
        self.pvc.view.frame = CGRectMake(0,0,s.width, s.height);
        [unityView addSubview:self.pvc.view];
        self.pvc.showsPlaybackControls = false;//關閉控制器,用戶不能操作
        [self.pvc.player play];
        //[UnityGetGLViewController() presentViewController:self.pvc animated:NO completion:nil];
        //[UnityGetGLViewController() addChildViewController:self.pvc];
        [NSTimer scheduledTimerWithTimeInterval:6 repeats:false block:^(NSTimer *time){
            [self.pvc.player pause];
            [self.pvc.view removeFromSuperview];
            [self.pvc dismissViewControllerAnimated:NO completion:nil];
            //[UnityGetGLViewController() dismissViewControllerAnimated:false completion:nullptr];
        }];
    }
}
@end

IMPL_APP_CONTROLLER_SUBCLASS(MyApp)   //代碼寫的很爛,不會。我要在視屏沒有播完把視屏給關了,各種問題啊,要么控制器不能關閉,第一次正常,關了App第二次就不行,這是我改的
最后一版,能用,慎用,unity有播放視屏的我抽空看看。

 

 這個類的結尾一定要是mm,父類有c++代碼

視屏考進來時放iPhone 項目里,不是UnityFrameWork 項目


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM