xcode 将统一应用程序集成到现有的 iOS 应用程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34714106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 08:24:51  来源:igfitidea点击:

Integrate unity app to existing iOS app

iosxcodeswiftunity3dunity5

提问by Sulo

I have an iOS app export from Unity 5 and also I used vuforia to add ar to that Unity app. Now I want to integrate the Unity app to my existing iOS app.

我有一个从 Unity 5 导出的 iOS 应用程序,我还使用 vuforia 将 ar 添加到该 Unity 应用程序。现在我想将 Unity 应用程序集成到我现有的 iOS 应用程序中。

I have followed http://www.the-nerd.be/2015/11/13/integrate-unity-5-in-a-native-ios-app-with-xcode-7/#comment-446tutorial and this is good for integrating Unity without Vuforia.

我遵循了http://www.the-nerd.be/2015/11/13/integrate-unity-5-in-a-native-ios-app-with-xcode-7/#comment-446教程和这个有利于在没有 Vuforia 的情况下集成 Unity。

So how can i do this and also its better to do this using swift

那么我如何才能做到这一点,而且最好使用 swift 做到这一点

回答by Daniel Arantes Loverde

i made a integration with Unity 5.3.8p8and Vuforia 6.0.117for iOS 8.4 and up. These tutorial is made for Objective-C, but you can do for Swift with no problem, just create a PREFIX HEADER and import all .h files there and substitute for the right code in my example bellow.

我为iOS 8.4 及更高版本Unity 5.3.8p8Vuforia 6.0.117进行了集成。这些教程是为 Objective-C 制作的,但你可以毫无问题地为 Swift 做,只需创建一个 PREFIX HEADER 并在那里导入所有 .h 文件,并在下面的示例中替换正确的代码。

After you export you Unity project for XCode, open it and create a Group Folder. Inside that folder you created, create a .mm file with the name you want ( mine is mainAppController.mm ), there is:

导出 XCode 的 Unity 项目后,打开它并创建一个组文件夹。在您创建的文件夹中,使用您想要的名称创建一个 .mm 文件(我的是 mainAppController.mm ),有:

// mainAppController.mm
//
// Import this default headers to make Unity and Vuforia works
#import <UIKit/UIKit.h>
#import "UnityAppController.h"
#import "UI/UnityView.h"
#import "UI/UnityViewControllerBase.h"
#import "VuforiaRenderDelegate.h"

// This is your MAIN VIEWCONTROLLER, that controller you want to open first when build/open your app.
#import "MainViewController.h"



// Unity native rendering callback plugin mechanism is only supported
// from version 4.5 onwards
#if UNITY_VERSION>434
// Exported methods for native rendering callback
extern "C" void UnitySetGraphicsDevice(void* device, int deviceType, int eventType);
extern "C" void UnityRenderEvent(int marker);

// This is for Vuforia Render Delegate, i copy it from VuforiaNativeRenderController.mm and add here to make it work

extern "C" void VuforiaSetGraphicsDevice(void* device, int deviceType, int eventType);
extern "C" void VuforiaRenderEvent(int marker);

#endif

@interface mainAppController : UnityAppController<UIApplicationDelegate>

// My historyboard works with NavigationController.
// If your app doenst use navigation, just open the historiboard with your main ViewController.

@property (nonatomic, strong) UINavigationController *navigationController;

- (void)willStartWithViewController:(UIViewController*)controller;
- (void)shouldAttachRenderDelegate;

@end



@implementation mainAppController


- (void)shouldAttachRenderDelegate
{

    self.renderDelegate = [[VuforiaRenderDelegate alloc] init];
    // Unity native rendering callback plugin mechanism is only supported
    // from version 4.5 onwards
#if UNITY_VERSION>434
    //
    // I comment this line bellow because Vuforia hendle it, and you see what will work with Vuforia.
    //
    //UnityRegisterRenderingPlugin(&UnitySetGraphicsDevice, &UnityRenderEvent);
    UnityRegisterRenderingPlugin(&VuforiaSetGraphicsDevice, &VuforiaRenderEvent);
#endif

}


- (void)willStartWithViewController:(UIViewController*)controller {

    //
    // Open your historyboard with your main view.
   // In my case i use navigation controller.

    UIStoryboard *storyBoard;
    storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    _rootController         = [[UnityDefaultViewController alloc] init];
    _rootView               = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    _rootController.view    = _rootView;

    MainViewController *mainVC       = [storyBoard instantiateViewControllerWithIdentifier:@"idMainViewController"];

    self.navigationController = [[UINavigationController alloc] initWithRootViewController:mainVC];

    [_rootView addSubview:self.navigationController.view];
}

@end


//
// You have to put this line below and comment out the equal line below in file VuforiaNativeRenderController.mm
//
IMPL_APP_CONTROLLER_SUBCLASS(mainAppController)

You notice that i'm using Storyboard. So my MainViewController is the ViewController root of the Navigation Controller. Right! Inside my MainViewController, i do this:

您注意到我正在使用 Storyboard。所以我的 MainViewController 是导航控制器的 ViewController 根。对!在我的 MainViewController 中,我这样做:

//  MainViewController.h
//

#import <UIKit/UIKit.h>
#import "UnityAppController.h"
#import "UI/UnityView.h"
#import "UI/UnityViewControllerBase.h"

@interface MainViewController : UIViewController
{
    UnityDefaultViewController *unityViewController;
    UnityAppController *unityController;
}

-(IBAction) touchToLoad:(id)sender;

@end



//  MainViewController.m
//
// This is just a EXAMPLE FILE, that i use in my project.
#import "MainViewController.h"
#import "ARViewController.h"

@interface MainViewController ()

@end

@implementation MainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // My project use navigation controller just for transition animation right to left, thats why i hide it here on first view.

    [self.navigationController setNavigationBarHidden:YES];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
//- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
//{
//    if ([segue.identifier isEqualToString:@"idHomeViewController"])
//    {
////        MyViewController *controller = (MyViewController *)segue.destinationViewController;
////        controller.myProperty1 = ...;
////        controller.myProperty2 = ...;
//    }
//    
//    
//}


-(void)touchToLoad:(id)sender
{
    //
    // Open historyboard with Unity and Vuforia, see details on ARViewController.h/m

    UIStoryboard *storyBoard;
    storyBoard                      = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ARViewController *mainVC        = [storyBoard instantiateViewControllerWithIdentifier:@"idARViewController"];
    [self.navigationController pushViewController:mainVC animated:YES];
}

@end

For better knowledge, i put a button to go to Unity View inside my storyboard. So that way i can handle the native UI from xcode. Then i have the ARViewController that show Unity and Vuforia working.

为了获得更好的知识,我在我的故事板中放置了一个按钮以转到 Unity View。这样我就可以从 xcode 处理本机 UI。然后我有显示 Unity 和 Vuforia 工作的 ARViewController。

//  ARViewController.h
//
//

#import <UIKit/UIKit.h>
#import "UnityAppController.h"
#import "UI/UnityView.h"
#import "UI/UnityViewControllerBase.h"


@interface ARViewController : UIViewController
{
    IBOutlet UIView     *viewToUnity;
    UnityDefaultViewController *unityViewController;
    UnityAppController *unityController;
}

-(IBAction) goBack:(id)sender;

@end



//  ARViewController.m
//
//

#import "ARViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ARViewController ()

@end

@implementation ARViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Just setting Unity delegates and view to add it as subview for my main view.
    // This allow me to add a UIButton above the UnityView to popViewController or anything i want to make native in iOS.

    unityViewController         = [[UnityDefaultViewController alloc] init];
    unityController             = (UnityAppController*)[[UIApplication sharedApplication] delegate];
    unityViewController.view    = (UIView*)unityController.unityView;

    [viewToUnity addSubview:unityViewController.view];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

#pragma MARK -- Methods
-(void)goBack:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

@end

I made a repo for download a project working.
https://bitbucket.org/Hyman_loverde/unity-5-vuforia-6-and-ios-native-integrationin case you want to test this version working.

我做了一个 repo 来下载一个正在运行的项目。
https://bitbucket.org/Hyman_loverde/unity-5-vuforia-6-and-ios-native-integration以防您想测试此版本是否有效。

Hope it help you.

希望对你有帮助。

Thanks

谢谢