この記事では、FlutterUnityWidgetを使ってUaaL(Flutter)をビルドするまでの手順をまとめています。
今回は、iOSでのビルドについてまとめています。
UaaLはUnityドキュメントに明記ある通り、多少難易度の高い実装方法となります。
また、Xcodeでアプリをビルドする為の詳細な手順(iOS端末を開発者モードにする手順など)については省略をしています。
UaaLとは
UaaL (Unity as a Library)は、UnityプロジェクトをLibraryとして扱えるようにすることができるプラグインです。これにより、UnityプロジェクトをFlutterプロジェクトに統合できます。
https://unity.com/ja/features/unity-as-a-library
Flutterとは
Flutterは、Googleが開発しているオープンソースのモバイルアプリケーション開発フレームワークです。Flutterの最大の特徴は、高速な開発スピードと美しいUIの作成が可能であることです。Flutterは、Dartというオブジェクト指向のプログラミング言語を使用しています。Dartは、JavaScriptと似た構文を持ち、TypeScriptのような静的型付けの機能も備えています。
FlutterUnityWidgetとは
flutter_unity_widgetは、FlutterとUnityを統合するためのプラグインです。具体的には、UaaL (Unity as a Library)を利用して、UnityプロジェクトをFlutterアプリ内で実行できます。これにより、Flutterで作成したUIとUnityで作成したゲームやAR/VRコンテンツを組み合わせたアプリを開発できます。
https://github.com/juicycleff/flutter-unity-view-widget
開発環境
macOS: 13.3.1
Flutter: Channel stable, 3.7.11
Dart: version 2.19.6
Java: OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
Xcode: 14.2
CocoaPods: version 1.11.3
Android Studio: version 2022.2
VS Code version 1.77.3
Flutterの開発環境セットアップ
詳細な手順は公式サイトに記載があるので割愛しますが、基本的にflutter doctor
ですべての項目に✅チェックがつくことでセットアップは完了します。
- 公式サイトからFlutter SDKをダウンロードしてインストールします。
-
flutter/bin
のpathを通す。 - インストール後、
flutter doctor
コマンドを実行して、Flutterの動作環境を確認します。必要なパッケージやライブラリがインストールされているか確認しましょう。
Xcodeのインストールはバージョン管理を行えるように、xcodes
からインストールすることをオススメします。
% flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.7.11, on macOS 13.3.1 22E261 darwin-arm64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] VS Code (version 1.77.3)
[✓] Connected device (3 available)
[✓] HTTP Host Availability
• No issues found!
🔨サンプルをビルドする
リポジトリのclone
flutter_unity_widgetのリポジトリをclone
git clone https://github.com/juicycleff/flutter-unity-view-widget.git
UnityProjectをビルド
- Unity Hubから以下のディレクトリにあるUnityProjectを開きます
flutter-unity-view-widget-master/example/unity/DemoApp
- Flutterのメニューから
Export IOS (Debug)
を選択してUnityプロジェクトのビルドを行います
Unityプロジェクトの成果物 -> flutter-unity-view-widget-master/example/ios/UnityLibrary
flutter パッケージのインストール
ターミナルでflutter-unity-view-widget-master/example
に移動後、同じディレクトリで flutter pub get
を実行します。
実行ログ
% flutter pub get
Running "flutter pub get" in example...
Resolving dependencies... (2.8s)
+ async 2.10.0 (2.11.0 available)
+ boolean_selector 2.1.1
+ characters 1.2.1 (1.3.0 available)
+ clock 1.1.1
+ collection 1.17.0 (1.17.1 available)
+ cupertino_icons 1.0.5
+ fake_async 1.3.1
+ flutter 0.0.0 from sdk flutter
+ flutter_plugin_android_lifecycle 2.0.13
+ flutter_test 0.0.0 from sdk flutter
+ flutter_unity_widget 2022.2.0 from path ..
+ flutter_web_plugins 0.0.0 from sdk flutter
+ js 0.6.5 (0.6.7 available)
+ matcher 0.12.13 (0.12.15 available)
+ material_color_utilities 0.2.0 (0.3.0 available)
+ meta 1.8.0 (1.9.1 available)
+ path 1.8.2 (1.8.3 available)
+ plugin_platform_interface 2.1.4
+ pointer_interceptor 0.9.3+4
+ sky_engine 0.0.99 from sdk flutter
+ source_span 1.9.1 (1.10.0 available)
+ stack_trace 1.11.0
+ stream_channel 2.1.1
+ stream_transform 2.1.0
+ string_scanner 1.2.0
+ term_glyph 1.2.1
+ test_api 0.4.16 (0.5.2 available)
+ vector_math 2.1.4
+ webview_flutter 4.2.0
+ webview_flutter_android 3.6.2
+ webview_flutter_platform_interface 2.3.0
+ webview_flutter_web 0.2.2+1
+ webview_flutter_wkwebview 3.4.0
Changed 33 dependencies!
UnityAppControllerの修正
Editorで以下のファイルを開き以下に記載するissue通りに変更を加えてください。
- UnityAppController.mm
- UnityAppController.h
このissue通りに変更する
Podfileのインストール
-
Editorで
flutter-unity-view-widget-master/example/ios/Podfile
を開き以下の項目を変更します2行目を変更
- # platform :ios, '11.0' //変更前 + platform :ios, '12.0' //変更後
-
ターミナルで
flutter-unity-view-widget-master/example/ios
に移動してpod install
を実行します実行ログ
% pod install Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring json-1.8.6 because its extensions are not built. Try: gem pristine json --version 1.8.6 Ignoring unf_ext-0.0.8.2 because its extensions are not built. Try: gem pristine unf_ext --version 0.0.8.2 Analyzing dependencies Downloading dependencies Generating Pods project Integrating client project Pod installation complete! There are 3 dependencies from the Podfile and 3 total pods installed. [!] CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all, please either set the base configurations of the target `Runner` to `Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig` or include the `Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig` in your build configuration (`Flutter/Release.xcconfig`).
Xcodeでプロジェクトのワークスペースを開き一部項目の変更をする
flutter-unity-view-widget-master/example/ios/Runner.xcworkspace
をXcodeで開きます。
Runner.xcodeproj
ではなく、Runner.xcworkspace
を開く
-
minimum deploymentを11→12に変更
Unity-iPhone
Runner
ともに、MinimumDeploymentsを12.0以降に変更する
flutter_unity_widget
の最低動作環境がiOS 12.0以上の為 -
Build Configurationの変更
⌘
+shift
+,
のショートカットキーでメニューを開き以下の項目を変更する
flutter run
を実行
iOS端末をmacに接続してflutter run
を実行します。
% flutter run
Launching lib/main.dart on KouheiのiPhone in debug mode...
Warning: Missing build name (CFBundleShortVersionString).
Warning: Missing build number (CFBundleVersion).
Action Required: You must set a build name and number in the pubspec.yaml file version
field before submitting to the App Store.
Automatically signing iOS for device deployment using specified development team in Xcode
project: ******
Running pod install... 787ms
Running Xcode build...
└─Compiling, linking and signing... 6.1s
Xcode build done. 40.9s
Installing and launching... 25.9s
Connecting to the VM Service is taking longer than expected...
Built from '2021.3/staging' branch, Version '2021.3.16f1 (4016570cf34f)', Build type 'Development', Scripting Backend 'il2cpp'
MemoryManager: Using 'Default' Allocator.
[UnityMemory] Configuration Parameters - Can be set up in boot.config
"memorysetup-bucket-allocator-granularity=16"
"memorysetup-bucket-allocator-bucket-count=8"
"memorysetup-bucket-allocator-block-size=4194304"
"memorysetup-bucket-allocator-block-count=1"
"memorysetup-main-allocator-block-size=16777216"
"memorysetup-thread-allocator-block-size=16777216"
"memorysetup-gfx-main-allocator-block-size=16777216"
"memorysetup-gfx-thread-allocator-block-size=16777216"
"memorysetup-cache-allocator-block-size=4194304"
"memorysetup-typetree-allocator-block-size=2097152"
"memorysetup-profiler-bucket-allocator-granularity=16"
"memorysetup-profiler-bucket-allocator-bucket-count=8"
"memorysetup-profiler-bucket-allocator-block-size=4194304"
"memorysetup-profiler-bucket-allocator-block-count=1"
"memorysetup-profiler-allocator-block-size=16777216"
"memorysetup-profiler-editor-allocator-block-size=1048576"
"memorysetup-temp-allocator-size-main=4194304"
"memorysetup-job-temp-allocator-block-size=2097152"
"memorysetup-job-temp-allocator-block-size-background=1048576"
"memorysetup-job-temp-allocator-reduction-small-platforms=262144"
"memorysetup-temp-allocator-size-background-worker=32768"
"memorysetup-temp-allocator-size-job-worker=262144"
"memorysetup-temp-allocator-size-preload-manager=262144"
"memorysetup-temp-allocator-size-nav-mesh-worker=65536"
"memorysetup-temp-allocator-size-audio-worker=65536"
"memorysetup-temp-allocator-size-cloud-worker=32768"
"memorysetup-temp-allocator-size-gfx=262144"
-> applicationDidFinishLaunching()
Found 3 interfaces on host : 0) 10.129.211.16 1) 169.254.37.193 2) 172.20.10.1
Multi-casting "[IP] 10.129.***.*** [Port] ****** [Flags] 2 [Guid] ****** [EditorId] ****** [Version] 1048832 [Id] iPhonePlayer(8,KouheinoiPhone):**** [Debug] 1 [PackageName] iPhonePlayer [ProjectName] flutterunitywidgets" to [225.0.***.***:****]...
Starting managed debugger on port 56000
//TODO: 動画のサイズ変える
何かエラーが発生した場合は、Runner.xcworkspace
を開いてXcodeから手動でビルドするとエラー解消を行いやすいです。
終わりに
UaaLは初期の学習コストが高いですが、一度乗り切ってしまうとUnityの可能性が大きく広がります!
とくに、Flutterは多くのライブラリとパッケージが用意されており、UIの実装に必要な機能やデザイン要素を簡単に追加できます。
UnityのUIをFlutterに置き換える選択肢、なかなかありなのはないでしょうか?
何か解決できないエラーが発生したら本記事のコメントか、Twitterまでどうぞ🙌
参考サイト