[转]Building a iOS Unity + UIView / UIViewController / Interface Builder App

转自:http://alexanderwong.me/post/29949258838/building-a-ios-unity-uiview-uiviewcontroller

 

 

Building a iOS Unity + UIView / UIViewController / Interface Builder App

When you build your Unity 3D project for the iPhone/iPad, Unity will generate a new Xcode project for you from scratch. It will even overwrite most files on subsequent builds. The design pattern assumes you’ll only want to run Unity in the app and nothing else (no custom UIViews or UIViewControllers, etc).

However, there are a number of cases where you might want to integrate Unity into your app and be able to show custom UIViews. Perhaps, you want to use Unity only for a portion of your application flow. Configuring your Xcode project to allow you to do this is possible, albeit quite tricky.

Before we get started, you should note:

  1. Unity cannot be completely stopped and then started on demand (as of the writing of this post). The best you’ll be able to do is pause Unity, change to a blank scene to free up some of Unity’s memory use, and then load a new scene and resume. (In AppController.mm might notice the UnityCleanup method and wrongly assume you can call it and callapplicationDidFinishLaunchingWithOptions to stop and start Unity, but you can’t. If you try, your app will crash.)
  2. Building everything in Unity makes it simple to build your application across platforms (iPhone + Android). Conversely, integrating Unity with your Xcode project means you’ll have to port over your Objective-C.
  3. There is no official support (currently) for writing your application this way, and so it will rest solely on your shoulders to ensure your application continues to function in the future.

Here’s the game plan for how to integrate Unity:

  1. Use your own AppDelegate (from now on referred to as YourAppDelegate) and forward all UIApplicationDelegate methods toAppController, which you instantiate in applicationDidFinishLaunchingWithOptions in yourYourAppDelegate.
  2. Set YourAppDelegate’s window property to keep track of the window returned byAppController. Instantiate your UIViewControllers or UIViews and add them as a subview to the aforementioned window. Your views are basically overlaid on top of Unity’s view.
  3. Expose methods to play and pause Unity.

Let’s get started:

0. Import, link, and copy all files and libraries needed by Unity into your app.

Start by copying all files in the folders named “Classes” and ”Libraries” from Unity into your app. Under “Classes”, movemain.mm out of your project so you can reference it later. Also copy ”Data” but do not subversion this folder as it is generated each time your build your Unity application.

Now, under Targets > YourAppTarget > Build Phases, click “Add Build Phase” and select “Run Script”. Paste the contents of the Run Script from the Xcode project generated by Unity here. Mine looks like:

rm -rf "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"
cp -Rf "$PROJECT_DIR/Data" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"

Under “Compile Sources”, check that the Unity Library files are linked. If you are using ARC in your project, add:

-fno-objc-arc

to the “Compiler Flags” next to any of Unity’s .m or .mm files.

Under “Link Binary With Libraries”, add any missing libraries from the Unity Xcode app and set the required/optional field accordingly.

1. Merge Unity’s .pch and main.mm file with your own.

For the .pch file, you can just about copy and paste its contents and overwrite your own. If you have custom code in your own file, you’ll have to merge by hand.

To merge the main.mm files, copy and paste Unity’s code into your file, but replace theirUIApplicationMain call with your own:

    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([YourAppDelegate class]));
    }

You’ll likely have to change the extension on your main.m file to.mm. Again, if you have any custom code, merge it by hand.

2. Configure your application delegate files.

In YourAppDelegate create the following properties as applicable:

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navigationController;
@property (strong, nonatomic) AppController *unityController; // unity

In AppController.h and AppController.mm create a getting method to return the window created by Unity.

- (UIWindow *)window
{
    return _window;
}

In application didFinishedLaunchingWithOptions instantiateAppController and store the window, also keep track of any UINavigation controllers you need.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // unity
    BOOL returnBOOL;
    if (_unityController == nil) {
        _unityController = [[AppController alloc] init];
    }
    returnBOOL = [_unityController application:application didFinishLaunchingWithOptions:launchOptions];

    //... your code here...

    // unity, set window
    _window = [_unityController window];
    
    // navigation controller
    _navigationController = [[UINavigationController alloc] initWithRootViewController:...];
    [_window addSubview:_navigationController.view];

    //... your code here...

    // unity, return
    return returnBOOL;

Lastly, forward all remaining UIApplicationDelegate methods like so…

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    ...
    // unity
    [_unityController applicationDidReceiveMemoryWarning:application];
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    ...
    // unity
    [_unityController applicationWillResignActive:application];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    ...
    // unity
    [_unityController applicationDidEnterBackground:application];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    ...
    // unity
    [_unityController applicationWillEnterForeground:application];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    ...
    // unity
    [_unityController applicationDidBecomeActive:application];
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    ...
    // unity
    [_unityController applicationWillTerminate:application];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    ...
    // unity
    [_unityController application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    ...
    // unity
    [_unityController application:application didFailToRegisterForRemoteNotificationsWithError:error];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    ...
    // unity
    [_unityController application:application didReceiveRemoteNotification:userInfo];
}

- (void)application:(UIApplication*)application didReceiveLocalNotification:(UILocalNotification*)notification
{
    ...
    // unity
    [_unityController application:application didReceiveLocalNotification:notification];
}

Now Unity will be launched when your application launches but your application flow should be unchanged. Since your UINavigationController is added to the window after Unity, it will cover Unity. To handle switching back and forth between Unity and your views a little better, let’s add the ability to pause and resume Unity.

3. Pause and resume Unity.

Again in AppController.h and AppController.mm, create the following pause method:

- (void)unityPause:(BOOL)pause
{
    UnityPause(pause);
}

In YourAppDelegate, create the corresponding methods:

// Unity

- (void)playUnity
{
    [_unityController unityPause:NO];
}

- (void)pauseUnity
{
    [_unityController unityPause:YES];
}

4. Swap between Unity and your UIViews.

As previously mentioned, Unity will always be running in the background. To display your own views, simply add them to the window above Unity’s view and be sure to pause / resume and clear the scene as appropriate to help alleviate the overhead of running Unity in the background.

5. Configure “Build Settings” under targets before your build.

Unity is particularly finicky about your build settings and target. In fact, you’ll need to rebuild your Unity project to switch between an iOS device target and a simulator target. The target’s “Build Settings” will also have to be configured according to your intended device. The best way to set up “Build Settings” is to simply copy and merge settings line by line from the “Build Settings” generated by Unity’s Xcode project.

Create two targets in your project, one for simulator builds and one for device builds so you don’t have to modify settings each time. Then in Unity, build the Xcode project for the simulator and then your actual device. In between builds, copy over your build settings to your Xcode project’s respective targets.

Some things to note here: Be sure to set the TARGET_IPHONE_SIMULATOR=1 preprocessor macro on your simulator build. And, if you have any-all_load linker flags, you’ll have to remove them.

6. Build your Unity + UIView app.

First build your Unity project. Then in the generate Xcode files, copy the contents of the “Data” folder into your project’s “Data” folder. Ensure that your build settings in Unity match the iOS version and device type you intend to build your Xcode project for. If you build your Unity project for your iPhone and try to run your Xcode project in the simulator it will not work, and vice-versa.

If all goes well, you might see a few warnings but no errors, and your app should start right up.

If you need more control, you can communicate with your Unity scripts from your Objective-C by following the directions in this post:

http://alexanderwong.me/post/29861010648/call-objective-c-from-unity-call-unity-from

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!针对您的问题,这里提供一些相关的信息供您参考。 首先,Unity是一款跨平台的游戏开发引擎,可以支持在多个平台上进行游戏开发。而Android和iOS是其中比较常见的移动平台。 在Android和iOS平台上嵌入Unity的开发示例,可以参考官方文档中的相关内容。具体步骤如下: 1. 创建Unity项目并设置相关参数,例如选择Android或iOS平台,设置屏幕分辨率等。 2. 在Unity项目中添加所需的场景和游戏对象,并设置相应的脚本和材质等。 3. 将Unity项目导出为Android或iOS平台所需的文件格式,例如APK或IPA文件。 4. 在Android或iOS项目中嵌入Unity文件,并通过相关代码进行调用和交互。 需要注意的是,Android和iOS平台上嵌入Unity的具体实现方式可能会有所不同,需要根据具体情况进行调整和修改。 另外,关于在Unity中开发Android或iOS应用的示例,也可以参考官方文档中的相关内容。具体步骤如下: 1. 创建Unity项目并设置相关参数,例如选择Android或iOS平台,设置屏幕分辨率等。 2. 在Unity项目中添加所需的场景和游戏对象,并设置相应的脚本和材质等。 3. 使用Unity提供的Android或iOS插件进行开发,例如调用相机或GPS等硬件功能,或者进行网络通信等。 4. 将Unity项目导出为Android或iOS应用程序,并进行相关的测试和调试。 需要注意的是,开发Android或iOS应用程序需要遵循相应的规范和标准,例如Android应用程序需要满足Google Play的要求,iOS应用程序需要通过苹果的审核。因此,在开发过程中需要谨慎处理相关问题。 希望以上信息对您有所帮助,如有任何疑问,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值