Flutter

flutter_unity_widgetでUnityをFlutterに埋め込む手順とバージョン対応

flutter_unity_widgetは、Unityで作ったシーンをFlutterアプリの一部として画面に埋め込むためのプラグインです。ゲームやAR、3Dビューアなどを、UI全体をFlutterで組みながらUnityの描画部分だけ差し込む、といった構成が取れます。本記事では、導入前に必ず確認したい対応バージョン・対応OS、Unityの書き出しからFlutter側の設置までの手順、双方向のデータ連携、つまずきやすい設定を実際のコードとともに整理します。あわせて、更新が止まっている現状を踏まえた代替パッケージとの使い分けまで示します。

まとめ:導入前に押さえる要点

  • 役割:UnityのシーンをFlutterのウィジェット(UnityWidget)として埋め込む。UIはFlutter、3D/ゲーム部分はUnityで分担する。
  • 対応バージョン:Unity 2019.4.3〜2022.3.x(2022.3 LTS推奨)、Flutter 3.0.0以降。最新版は2022.2.1(2023年公開)で更新が停滞している。
  • 本命はモバイル:Android/iOSが実用水準。Web・Windowsは公式READMEに記載はあるが制約が大きく、Windowsは開発中扱い。
  • 実機で確認:Graphics APIはAndroidでOpenGLES3推奨。エミュレータ/シミュレータは動作が不安定なため実機で検証する。
  • 新規採用の判断:Unity 6や比較的新しいUnityを使うなら、保守が活発なflutter_embed_unityも検討する(後述の比較表)。

flutter_unity_widgetの役割(FlutterにUnityを組み込むプラグイン)

flutter_unity_widgetは、Rex Isaac Raphael氏(発行元 xraph.com、リポジトリ juicycleff/flutter-unity-view-widget、BSD-3-Clauseライセンス)が公開しているオープンソースのFlutterプラグインです。Unityプロジェクトをネイティブライブラリとして書き出し、それをFlutterアプリに取り込んでUnityWidgetで表示します。UnityとFlutterはそれぞれ別プロセスの描画エンジンで、このプラグインが両者をつなぐブリッジの役割を担います。

「flutter vs unity」でどちらを使うか迷う場面がありますが、両者は競合ではなく分担です。画面遷移・フォーム・リスト表示などアプリのUIはFlutterが得意で、リアルタイム3Dや物理・ARはUnityが得意です。flutter_unity_widgetはFlutter製アプリの中に3D/ゲーム領域だけをUnityで持たせたいときに選ぶ、という位置づけになります。ソースやサンプルはGitHubリポジトリで確認できます。

対応バージョンと対応プラットフォーム(導入前の互換性確認)

flutter_unity_widgetは埋め込みという性質上、UnityとFlutterのバージョンがかみ合わないとビルドが通りません。導入前に次の2点を確認します。

UnityとFlutterの対応バージョン

公式が案内する下限はUnity 2019.4.3で、安定性の面から2022.3系のLTSが推奨されています。それより新しいUnity 6(6000.x)系は、このプラグインでは動作保証の対象外になりがちなので注意してください。Flutterはパッケージ2022.2.0以降がFlutter 3.0.0以降を前提とします。Flutter自体のバージョン更新点はFlutter 3.41の改善ポイントもあわせて確認しておくと、SDK側の変更に振り回されずに済みます。

対応OSと制約(Android/iOSが本命)

READMEでは Android・iOS・Web・Windows(開発中)が挙げられていますが、実運用で安定するのはAndroid と iOSです。Webはブラウザ側の制約でUnity機能の一部が使えず、Windowsは「work in progress」の位置づけです。Android・iOSでも、低スペック端末ではUnityの描画負荷が体感に直結するため、テクスチャ解像度やシーンの軽量化を前提に設計します。

UnityプロジェクトをFlutterに埋め込む手順

作業は「Unity側で書き出す」→「Flutter側で取り込む」の2段階です。

Unity側の書き出し設定

Build SettingsでターゲットOSを選び、Player SettingsのGraphics APIを設定します。AndroidはAuto Graphics APIを無効化してOpenGLES3を優先、iOSはMetalが既定です。Scripting BackendはIL2CPPを選ぶと安定します。この状態でプラグインが用意する書き出し用スクリプト(flutter/export.cs 相当のメニュー)からライブラリとして書き出し、Flutterプロジェクト直下の所定ディレクトリ(android/unityLibrary や iOSの UnityLibrary)に配置します。

Flutter側の設定とUnityWidgetの配置

pubspec.yamlに依存を追加してインストールします。

dependencies:
  flutter_unity_widget: ^2022.2.1

あとは表示したい画面でUnityWidgetを置き、生成時にコントローラを受け取ります。

import 'package:flutter/material.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';

class UnityScreen extends StatefulWidget {
  const UnityScreen({super.key});
  @override
  State<UnityScreen> createState() => _UnityScreenState();
}

class _UnityScreenState extends State<UnityScreen> {
  UnityWidgetController? _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: UnityWidget(
        onUnityCreated: (c) => _controller = c,
        onUnityMessage: (msg) => debugPrint('Unity: $msg'),
      ),
    );
  }
}

Gradle(Android)やPodfile(iOS)にUnityライブラリを組み込む設定が別途必要です。ここはUnity・Flutterのバージョン差で手順が変わりやすいので、書き出したライブラリ名とパスが実際の配置と一致しているかを一つずつ確認します。

FlutterとUnity間でデータをやり取りする(双方向通信)

埋め込んだだけでは飾りなので、実用ではFlutterのボタン操作でUnityのオブジェクトを動かす、Unity内のイベントをFlutterで受ける、といった双方向通信を組みます。Flutterから送るときはコントローラのpostMessageで、対象GameObject名・メソッド名・引数を渡します。Unityから受けるときは、先ほどのonUnityMessageコールバックで受信します。

// Flutter → Unity:Cubeオブジェクトの RotateObject(10) を呼ぶ
_controller?.postMessage('Cube', 'RotateObject', '10');

// Unity → Flutter:Unity側で UnityMessageManager.Instance.SendMessageToFlutter(...) を呼ぶと
// 上の onUnityMessage(msg) に文字列が届く

引数は文字列で渡すのが基本なので、複雑なデータはJSON文字列にしてやり取りします。Flutter側でネイティブとデータを橋渡しする考え方はFlutterのネイティブ連携(Native Assets)と共通する部分があり、境界をまたぐ通信は疎結合に保つのが安定運用のコツです。

つまずきやすいポイントと対処

統合で詰まる原因はほぼ決まっています。

  • Graphics APIの不一致:AndroidでOpenGLES3以外が有効だと表示崩れやクラッシュが起きやすい。Auto Graphics APIを切って明示指定する。
  • エミュレータで動かない:Unityの描画はエミュレータ/シミュレータでは不安定。実機で検証する。
  • バージョン不整合:Unityが2022.3系より新しい、またはFlutterがパッケージ要件を満たさないとビルドが失敗する。対応レンジ内に揃える。
  • ビルドサイズの肥大:Unityライブラリを取り込むぶんアプリが重くなる。不要アセットを削り、テクスチャ圧縮とカリングで軽量化する。

問題の切り分けには、UnityのProfiler/Frame DebuggerとFlutterのDevToolsを併用し、描画のボトルネックがどちら側かを先に特定します。設計段階での責務分担はFlutterのアーキテクチャ設計の基本も参考になります。

flutter_unity_widgetは今も選ぶべきか:代替とのすみ分け

導入判断で最も重要なのに、多くの解説記事が触れていない点があります。flutter_unity_widgetの最新版は2022.2.1で、公開は約2年前(2023年ごろ)から更新が止まっています。Unity 6が普及した現在、新規プロジェクトでこのパッケージだけを前提に組むのはリスクがあります。

実務では、より新しく保守も活発なflutter_embed_unityという選択肢があります。federatedプラグインとして設計され、Unity 6にも対応します。

項目 flutter_unity_widget flutter_embed_unity
最新版 2022.2.1(2023年) 2.0.0(2026年)
保守状況 更新停滞 活発
対応Unity 2019.4.3〜2022.3.x 2022.3 LTS/Unity 6000.x LTS
対応Flutter 3.0.0以降 3.3.x以降
対応OS Android/iOS/Web/Win(WIP) Android/iOS
ライセンス BSD-3-Clause MIT

判断の目安ははっきりしています。Unity 6や比較的新しいUnityで新規に作る、モバイル(Android/iOS)だけで足りるなら、保守が続くflutter_embed_unityが有利です。逆に、Unity 2019.4.3〜2022.3.xの既存プロジェクトを流用する、あるいはWeb/Windowsを含めたい場合は、対応レンジの広いflutter_unity_widgetが依然として現実的な選択肢になります。どちらもUnity側の準備(書き出し・Graphics API設定)の考え方は共通なので、まずは対応Unityバージョンを軸に選ぶ。Unityエンジン側の準備はUnityの日本語化とUnity 6の新機能もあわせて確認してください。

よくある質問

flutter_unity_widgetはWebで使えますか?

公式READMEにはWeb対応の記載がありますが、ブラウザの制約でUnity機能の一部が動作せず、実用面ではAndroid/iOSが本命です。Webを重視するなら要件を先に検証してください。

対応するUnityのバージョンは?

Unity 2019.4.3以降で、2022.3系のLTSが推奨です。Unity 6(6000.x)で新規に作るなら、Unity 6対応のflutter_embed_unityの利用も検討します。

エミュレータやシミュレータで動作確認できますか?

Unityの描画はエミュレータ/シミュレータでは不安定になりやすいため、実機での確認を前提にしてください。

FlutterとUnityはどう使い分けますか(flutter vs unity)?

UI・画面遷移・データ表示はFlutter、リアルタイム3D・物理・ARはUnityが得意です。flutter_unity_widgetはFlutter製アプリ内にUnityの3D領域だけを埋め込む用途に使います。

ソースコードはどこで確認できますか?

GitHubのjuicycleff/flutter-unity-view-widget(発行元 xraph.com)で公開されています。サンプルや最新のissueもそこで確認できます。

関連記事

資料請求

RELATED POSTS 関連記事