将Unity3d集成到iOS UITabbarController / UINavigationController中

时间:2015-06-12 11:23:09

标签: ios objective-c xcode unity3d

我已经设法用Unity编译我的iOS项目。如果它是第一个视图,则经过测试和统一项目在我的iOS项目中运行。

但是我试图在另一个子视图中初始化它。 最初我的应用程序AppDelegate将处理self.window.rootViewController 好像我必须在Plugin / iOS文件夹中传递“UnityAppController”的处理,覆盖(void)willStartWithViewController:(UIViewController*)controller方法。

- (void)willStartWithViewController:(UIViewController*)controller {
    _rootController = [[UIViewController alloc] init];
    _rootView       = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    _rootController.view = _rootView;

    LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:nil bundle:nil];

    [_rootView addSubview:loginViewController.view];
}

应用程序编译并构建,但视图始终为空。 我看到它确实加载了我的LoginViewController背景颜色,但没有最初在屏幕上显示的标签或文本字段。

我不确定Unity的View是否已经创建并且在我的LoginViewController之上,因为我没有看到我在Unity中创建的场景。

tl;博士 将Unity3D项目集成到iOS现有项目后,查看不显示按钮,标签等。

我正在使用Unity 5.0.0f4和Xcode 6.3.1。

任何帮助表示赞赏!谢谢!

更新
所以我设法以某种方式解决了它。我将实现文件类型从.m更改为.mm并且它有效。我不确定为什么但它有效。任何人都可以解释一下吗?

我在设置rootViewController时仍遇到问题。我的main.mm文件看起来像这样。

int main(int argc, char* argv[])
{
    @autoreleasepool
    {
        UnityInitTrampoline();
        UnityParseCommandLine(argc, argv);

#if INIT_SCRIPTING_BACKEND
        InitializeScriptingBackend();
#endif

        RegisterMonoModules();
        NSLog(@"-> registered mono modules %p\n", &constsection);
        RegisterFeatures();

        // iOS terminates open sockets when an application enters background mode.
        // The next write to any of such socket causes SIGPIPE signal being raised,
        // even if the request has been done from scripting side. This disables the
        // signal and allows Mono to throw a proper C# exception.
        std::signal(SIGPIPE, SIG_IGN);

        UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]);
        //UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }

    return 0;
}

我正在尝试设置UITabBarController,但我似乎无法做到。我有一个ViewController,它是UnityAppController的子类,我在其中覆盖方法willStartWithViewController

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

    if(_unityController == nil)
    {
        _unityController = [[UnityAppController alloc] init];
        NSLog(@"Unity Controller set");
    }

    _rootController = [[UIViewController alloc] init];
    _rootView       = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    UITabBarController *tabVC = [[UITabBarController alloc] init];

    LoginViewController *c = [[LoginViewController alloc] init];
    [tabVC addChildViewController:c];
    [[UIApplication sharedApplication] keyWindow].rootViewController = tabVC;

}

视图加载但屏幕上没有任何内容。

1 个答案:

答案 0 :(得分:3)

因此,经过多天的研究和测试,希望我的回答可以帮助那些面临这个问题的人。

假设您与项目集成在一起并且没有编译错误。您需要修改3个文件才能使其正常工作。我正在使用Unity v5.0.0f4和XCode 6.3.1。 Unity的v5和v4有很多变化。一个主要的变化是不推荐使用createHierarchy,你必须使用willStartWithViewController。

<强> [main.mm]

在main.mm文件中的main函数中,使用扩展的“UnityAppController”类进行编辑。

UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]);

[YourUnityAppController.mm]

这是您在Plugin / iOS / YourUnityAppController.mm下以单位创建的文件

初始化Unity使用的rootController和rootView。我们在这里不会做任何其他事情。

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

   _rootController = [[UIViewController alloc] init];
   _rootView       = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

}

didFinishLaunchingWithOptions 方法中创建一个观察者。完全创建Unity时我们需要使用它来监听,然后用我们想要的任何东西设置 window.rootView

我注意到Unity如何创建其视图的过程如下

didFinishLaunchingWithOptions 将调用其超类,它将调用“ willStartWithViewController ”。这意味着在“ willStartWithViewController ”完成后,将调用超类构造函数之下的任何内容。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUnityReady) name:@“UnityReady” object:self];

   [super application:application didFinishLaunchingWithOptions:launchOptions]
}

我们处理观察者的方法。

- (void)handleUnityReady {
   _window.rootViewController = yourTabBarController;
}

这可以防止Unity在应用启动时使用其视图覆盖您的视图。

<强> [UnityAppController.mm]

在此文件中找到 startUnity 功能。我们需要在那里添加回调。确保在[ self showGameUI ]

之后添加
 [[NSNotificationCenter defaultCenter] postNotificationName:@“UnityReady” object:self];

就是这样! Unity视图正在创建,但不在您的应用程序之上。然后,您可以使用 GetAppController()。unityView 获取Unity视图,并将其分配给您想要的任何视图。

参考文献:

http://forum.unity3d.com/threads/tabbar-controller.156868/ http://answers.unity3d.com/questions/299550/combine-unity-and-native-opengl-in-ios-sparrow.html?sort=oldest http://www.taidous.com/thread-11147-1-1.html https://github.com/bzgeb/pd-for-unity/blob/master/iOS/Classes/iPhone_View.mm