目次
はじめに
10ANTZではゲーム開発だけではなく、アプリケーションサービスの開発を行っており、配信サービス、マイクロサービスも提供しています。ゲーム開発ではクライアントは主にUnityを使用し、アプリケーション側は主にFlutterを使用しています。
背景
アプリケーションサービスでリッチな動画表現、ゲーム要素を簡単に実現できないか検討中下記の二つ検証行いました。
- Flutterゲームエンジン flame
 - Flutter + Unity
 
Flutterゲームエンジンflameの場合、2Dの基本要件の実現が簡単で、Web対応も簡単でした。ただしコードベースで実装していかなければならないのと、実装と機能の面でUnityより使いにくいところもありまして、今回はFlutter + Unityを紹介します。
Unity as a library
Unity 2019.3からUnityのUnity as a libraryの提供によりUnityを他のNativeアプリゲーション側で実行することが可能になりました。
Unity 2019.3 以降、コンテンツと Unity ランタイムコンポーネントをネイティブプラットフォームのプロジェクトに統合することで、Unity を他のアプリケーションのライブラリとして使用できます。これにより、AR 体験、3D モデルとの相互作用、2D ミニゲームなど、3D または 2D リアルタイムレンダリングを使用するコンテンツを埋め込むことができます。Unity ランタイムライブラリは、ネイティブアプリケーション内でのロード、アクティベート、アンロードを管理する方法を公開しています。
現在、以下のプラットフォームが Unity as a Library をサポートしています。
- Android
 - iOS
 - Windows とユニバーサル Windows プラットフォーム (UWP)
 
制限
別のアプリケーションによってホストされている場合 、Unity はランタイムの ライフサイクルを制御しないため、すべてのシナリオで機能するわけではありません。既知の制限は以下のとおりです。
- Android と iOS
 - フル画面レンダリングのみがサポートされています。画面の一部のみにレンダリングすることはできません。
 - Unity がアンロード状態にあるときは (
Application.Unloadの呼び出し後)、同じプロセスで即座に切り替えて再度実行できるように、ある程度のメモリ (100Mb 以下) を維持します。 - iOS で Unity ランタイムが完全に終了した場合 (
Application.Quitの呼び出し後)、同じアプリケーションセッションで再度 Unity を再起動ことはできません。 - Unity ランタイムの複数のインスタンスを読み込んだり、複数の Unity ランタイムを統合したりすることはできません。
 - 正しく動作させるために ネイティブ プラグインと マネージ プラグインの調整が必要な場合があります。
 
Flutter
10ANTZでメインで使っているFlutter について簡単に紹介したいと思います。
Flutter は Google 社が開発しているオープンソースのアプリケーションフレームワークです。
クロスプラットフォームに対応しており、ワンソースで複数のプラットフォーム(iOS、Android、Web、Windows、Mac、Linux)に対応したアプリを開発することができます。
マテリアルデザインによる美しい UI を利用することができます。
10ANTZのFlutter 製のアプリSKE48 SHAKEリリースしてます。
プロジェクト構造
android、iosと同じ場所にunityフォルダーを作成し、UnityのDemoプロジェクトを作成します。

Unity設定
UnityにFlutterUnityIntegration-v4.1.0.unitypackageをImportするとFlutter Toolsが表示されます。

File > Build Settings > Player Settings
- Scripting Backend: IL2CPP
 - Target Architectures: ARMv7 and ARM64
 
に設定

UnityMessageManagerをGameObjectに追加
UnityとFlutter 間でメッセージ送信受信するManagerです。

または
| 
					 1 2 3 4 5  | 
						void Start()     {         gameObject.AddComponent<UnityMessageManager>();     }  | 
					
Flutter 設定
Unityと連携するためのWidgetはUnityWidgetを使用します。
| 
					 1 2 3 4 5  | 
						              UnityWidget(                 onUnityCreated: _onUnityCreated,                 onUnityMessage: onUnityMessage,                 onUnitySceneLoaded: onUnitySceneLoaded,               ),  | 
					
Unityにメッセージを送信
| 
					 1 2 3 4 5  | 
						_unityWidgetController.postMessage(       'Cube',       'SetRotationSpeed',       speed,     );  | 
					
ビルド
Assets/FlutterUnityIntegration/Editor/Build.csを修正
| 
					 1 2 3 4 5 6 7 8  | 
						Android - var options = BuildOptions.AcceptExternalModificationsToPlayer; + var options = BuildOptions.AllowDebugging; + EditorUserBuildSettings.exportAsGoogleAndroidProject = true; iOS -    var options = BuildOptions.AcceptExternalModificationsToPlayer; +    var options = BuildOptions.AllowDebugging;  | 
					
UnityとFlutterのAndroid minSDKとtargetSDKを同じバージョンに設定、
![]()
Flutter android/app/build.gradle
| 
					 1 2 3 4  | 
						defaultConfig {     minSdkVersion 24     targetSdkVersion 30 }  | 
					
android/gradle.propertiesにunityStreamingAssetsを追加
| 
					 1  | 
						unityStreamingAssets=.unity3d, google-services-desktop.json, google-services.json, GoogleService-Info.plist  | 
					
Export Androidを実行するとandroid/unityLibratyフォルダーが生成される


android/unityLibrary/build.gradleのBuildIl2Cpp関数修正
| 
					 1 2  | 
						- "--tool-chain-path=" + android.ndkDirectory, + "--tool-chain-path=" + "/Applications/Unity/Hub/Editor/2020.3.17f1/PlaybackEngines/AndroidPlayer/NDK",  | 
					
以上でflutter側ビルドを行うとFlutter + Unityのサンプルが動きます。
AR使用する場合
gradle 5.6.4以上が必須になりますので下記ように修正
gradle-wrapper.propertiesをgradle-5.6.4を使うように修正
| 
					 1  | 
						distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip  | 
					
android/build.gradleを3.6.0に修正
| 
					 1  | 
						classpath 'com.android.tools.build:gradle:3.6.0'  | 
					
unity.DemoApp/Builds.flutterunitywidgets.apk/build.gradleの修正
| 
					 1  | 
						classpath 'com.android.tools.build:gradle:5.6.4'  | 
					
まとめ
Unity as a libraryの提供により、これからは、Unityが単純にゲームのみではなく、アプリケーションと簡単に連動できるようになり、色々幅広く使えそうでした。
現時点では色々制限がありますが、しっかり設計すれば使うのには充分な機能だと思います。
Flutter Unity Widgetはまだ色々Issueが残っていますが、現時点ではバージョン4.0.0になり開発も順調に進んでおります。
flutter unity arkitもサンプルなどありますので、興味ある方はこちらを参考してください