iOSとunityを統合

2013年2月15日

Unityで生成されたiOSソースコードを自作アプリに統合する方法

1:必要なソースファイルの移行

Unityより生成されたソースファイルの中のClassesはLibrariesフォルダの中をすべてXcodeでimport
このときmain.mmは除去(あとで参照する)
Tagets -> appTaget -> Build Phasesで Add Build Phaseをクリック. Add Run Scriptクリック後Unityで生成されたXcodeのBuild Phasesにあるscriptsをこぴぺー
Compile Sourcesで Unity Library fileがすべてリンクされたかを確認. ARCを使用している場合は下記を追加(.m .mmのファイルのCompiler FlagsにARCを利用しないflag)
-fno-objc-arc

2:Unityのpchファイルとmain.mmファイルを自分のものと統合

UnityのiPhone_target_Prefix.pchを自分のアプリの.pchファイルと統合。自分で改良を行った場合には独自でマージすること

unityのmain.mmソースをprojectのmain.mにコピー
ただし以下のソースはそのまま活用 (もとのprojectのmain.mソース)
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
projectのmain.m をmain.mmに変更

projectのAppDelegateを修正しUnityのwindowを取得可能に

AppDelegate.h

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

AppDelegate.m
#import “AppController.h”

AppController.h //Unity source
@property (strong, nonatomic) UIWindow *window;

- (UIWindow *) window;

AppController.mm
- (UIWindow *)window
{
return _window;
}

(-fno-objc-arc をflagに追加したにも関わらずARCエラーが発生したためbuild settings Apple LLVM compiler 4.1 – Language のObjective-C Automatic Reference Counting を Yes -> NO -> Yesをためした)

application didFinishLaunchingWithOptionsを修正

didFinishLaunchingWithOptions部分でunity windowを追加
- (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;

}

Delegate を修正

- (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];
}

Pause and resume Unity.

AppController.hとAppController.mmに下記ソースを追加

AppController.h
- (void)unityPause:(BOOL)pause

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

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.

[Compile Error]

1: Undefined symbols for architecture armv7:
“std::string::find_last_of(char const*, unsigned long) const”, referenced from:
tesseract::WordSizeModel::Init(std::string const&, std::string const&) in

My problem was an xcode setting. Under “Apple LLVM Compiler 4.2 – Language” there is a setting for “C++ standard library”. Its value need to be change to “compilar default”.

2: Undefined symbols for architecture i386:
“_mono_aot_module_Assembly_CSharp_info”, referenced from:

Build Settings
Apple LLVM compiler 4.1 -Language
-DTARGET_IPHONE_SIMULATOR=1
-DTARGET_IPHONE_SIMULATOR=1

cp: /Users/IMCMAC2/Desktop/NewUnityTest – Xcode/Data: No such file or directory
>> 元のUNITYのデータフォルダを移行

cp: /Users/IMCMAC2/Desktop/NewUnityTest – Xcode/*.png: No such file or directory
>>
if [ "$PLATFORM_NAME" == "iphonesimulator" ]
then cp -f “$PROJECT_DIR”/*.png “$TARGET_BUILD_DIR/$PRODUCT_NAME.app/”
fi
を削除

viewを追加
unityより表現中のviewを取得後追加させる
[[_unityController view]addSubview:self.viewController.view];

Have your say