Unity + Flutter 混合开发全指南:在 Flutter 中嵌入 3D 游戏的完整流程
·
目录
Unity + Flutter 混合开发全指南:在 Flutter 中嵌入 3D 游戏的完整流程
3. iOS 编译错误 “Undefined symbols for architecture arm64”
在移动开发中,Flutter 以其跨平台 UI 一致性和高效开发著称,但在复杂 3D 游戏开发方面并非专长;而 Unity 作为专业 3D 引擎,在渲染、物理系统和动画方面优势显著。将两者结合,既能利用 Flutter 快速构建美观的跨平台 UI,又能借助 Unity 实现高质量 3D 游戏场景。本文将带你从零开始,完成 Unity 3D 游戏嵌入 Flutter 应用的全流程,包括环境搭建、双向通信、打包发布等关键步骤。
一、为什么选择 Unity + Flutter 混合开发?
这种组合的核心价值在于优势互补:
- Unity:负责 3D 场景渲染、物理碰撞、骨骼动画等核心游戏逻辑,提供专业级 3D 开发能力;
- Flutter:负责应用 UI 界面、业务逻辑、网络请求等,实现跨平台一致性体验;
- 适用场景:3D 游戏(如角色冒险、虚拟漫游)、高保真交互场景(如 AR 看房、3D 教育)。
相比纯 Unity 或纯 Flutter 方案,混合开发能兼顾3D 性能和UI 灵活性,同时降低跨平台适配成本。
二、环境准备与工具链
1. 必备开发工具
| 工具 | 版本要求 | 作用 |
|---|---|---|
| Unity | 2020.3 LTS 或 2021.3 LTS | 开发 3D 游戏核心场景 |
| Flutter | 3.0+ | 构建跨平台应用 UI |
| Android Studio | 4.0+ | Android 平台编译与调试 |
| Xcode | 13.0+(Mac) | iOS 平台编译与调试 |
| 插件 | flutter_unity_widget | 实现 Flutter 与 Unity 通信 |
2. 版本兼容性注意
- Unity 2019 及以下版本可能不支持最新插件,建议使用 2020+ LTS 版本;
- Flutter 需 3.0+ 以支持
flutter_unity_widget 4.0+; - Android 端:Unity 与 Flutter 的 Gradle 版本需一致(推荐 7.0+);
- iOS 端:需 Xcode 13+ 支持 Unity 导出的工程格式。
三、Step 1:Unity 端开发与配置
1. 创建 Unity 3D 项目
- 打开 Unity Hub,新建 3D 模板项目(示例命名为
Unity3DGame); - 导入基础资源:添加一个简单的 3D 房间模型和可移动的人物模型(可从 Unity Asset Store 下载免费资源)。
2. 导入 Unity-Flutter 通信插件
- 打开 Unity 项目,进入 Window > Package Manager;
- 点击 + > Add package from git URL,输入插件地址:
https://github.com/juicycleff/flutter-unity-view-widget.git?path=/packages/unity_bridge
(若无法访问 Git,可手动下载源码并导入unity_bridge目录)。
3. 编写 3D 逻辑与通信脚本
以 “人物移动控制” 为例,创建 C# 脚本 PlayerController.cs,实现 3D 人物控制并与 Flutter 通信:
using UnityEngine;
using FlutterUnityIntegration; // 引入通信库
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 5f; // 移动速度
private Rigidbody rb; // 刚体组件(用于物理移动)
void Start()
{
// 获取人物刚体组件(需在编辑器中手动添加)
rb = GetComponent<Rigidbody>();
// 禁用重力与旋转锁定(避免人物倾倒)
rb.useGravity = false;
rb.freezeRotation = true;
}
// 接收 Flutter 发送的移动指令
public void Move(string direction)
{
// 根据指令计算移动方向
Vector3 movement = Vector3.zero;
switch (direction)
{
case "forward": movement = Vector3.forward; break;
case "back": movement = Vector3.back; break;
case "left": movement = Vector3.left; break;
case "right": movement = Vector3.right; break;
}
// 应用移动(通过刚体实现平滑物理移动)
rb.velocity = movement * moveSpeed;
// 向 Flutter 发送当前位置(可选)
UnityMessageManager.Instance.SendMessageToFlutter(
"player_position",
$"X: {transform.position.x:0.0}, Y: {transform.position.y:0.0}, Z: {transform.position.z:0.0}"
);
}
}
- 在 Unity 编辑器中,将脚本挂载到人物模型上;
- 给人物模型添加
Rigidbody组件(在 Inspector 面板点击 Add Component > Rigidbody)。
4. 配置 Unity 导出设置
(1)Android 平台配置
- 进入 File > Build Settings,切换平台为 Android;
- 点击 Player Settings,设置关键参数:
- Company Name:与 Flutter 项目一致(如
com.example); - Product Name:自定义名称(如
Unity3DGame); - Minimum API Level:Android 19+(与 Flutter 兼容);
- Scripting Backend:选择 IL2CPP(支持 64 位,性能更好);
- Target Architectures:勾选 ARM64 和 ARMv7。
- Company Name:与 Flutter 项目一致(如
(2)iOS 平台配置
- 进入 File > Build Settings,切换平台为 iOS;
- 点击 Player Settings,设置:
- Bundle Identifier:与 Flutter 项目前缀一致(如
com.example.unitygame); - Minimum iOS Version:11.0+。
- Bundle Identifier:与 Flutter 项目前缀一致(如
四、Step 2:Flutter 端项目创建与集成
1. 新建 Flutter 项目
flutter create unity_flutter_demo
cd unity_flutter_demo
2. 添加 Unity 集成插件
在 pubspec.yaml 中添加依赖:
dependencies:
flutter:
sdk: flutter
flutter_unity_widget: ^4.0.2 # 最新版本可在 pub.dev 查询
执行 flutter pub get 安装插件。
3. 编写 Flutter 界面与通信逻辑
创建 unity_game_page.dart,实现包含 Unity 3D 视图和控制按钮的页面:
import 'package:flutter/material.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';
class UnityGamePage extends StatefulWidget {
const UnityGamePage({super.key});
@override
State<UnityGamePage> createState() => _UnityGamePageState();
}
class _UnityGamePageState extends State<UnityGamePage> {
late UnityWidgetController _unityController;
String _playerPosition = "等待人物移动...";
// Unity 初始化完成回调
void _onUnityCreated(UnityWidgetController controller) {
_unityController = controller;
}
// 接收 Unity 发送的消息(如人物位置)
void _onUnityMessage(UnityMessage message) {
if (message.name == "player_position") {
setState(() => _playerPosition = "人物位置:${message.data}");
}
}
// 向 Unity 发送移动指令
void _sendMoveCommand(String direction) {
_unityController.postMessage(
"Player", // Unity 中人物模型的名称(必须与编辑器中一致)
"Move", // 调用的 C# 方法名(与 PlayerController 中一致)
direction // 传递的参数(移动方向)
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Unity + Flutter 3D 示例")),
body: Column(
children: [
// 显示 Unity 3D 场景(占满屏幕主要区域)
Expanded(
child: UnityWidget(
onUnityCreated: _onUnityCreated,
onUnityMessage: _onUnityMessage,
unityScene: "Assets/Scenes/MainScene.unity", // Unity 场景路径
),
),
// 显示人物位置信息
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(_playerPosition, style: const TextStyle(fontSize: 16)),
),
// 移动控制按钮
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: const Icon(Icons.arrow_upward, size: 32),
onPressed: () => _sendMoveCommand("forward"),
),
IconButton(
icon: const Icon(Icons.arrow_downward, size: 32),
onPressed: () => _sendMoveCommand("back"),
),
IconButton(
icon: const Icon(Icons.arrow_left, size: 32),
onPressed: () => _sendMoveCommand("left"),
),
IconButton(
icon: const Icon(Icons.arrow_right, size: 32),
onPressed: () => _sendMoveCommand("right"),
),
],
),
const SizedBox(height: 16),
],
),
);
}
}
在 main.dart 中设置入口:
import 'package:flutter/material.dart';
import 'unity_game_page.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Unity + Flutter",
home: const UnityGamePage(),
);
}
}
五、Step 3:项目关联与打包运行
1. 导出 Unity 工程到 Flutter 项目
(1)Android 平台
- 在 Unity 中,File > Build Settings,勾选 “Export Project”,点击 “Export”;
- 选择导出路径:
flutter项目根目录/android/unityLibrary(自动创建该文件夹); - 导出完成后,Flutter 会自动识别 Unity 模块。
(2)iOS 平台
- 在 Unity 中,File > Build Settings,点击 “Build”,导出 iOS 工程到
flutter项目根目录/ios/UnityLibrary; - 用 Xcode 打开 Flutter 项目的 iOS 工程:
flutter项目根目录/ios/Runner.xcworkspace; - 右键点击 “Runner” 项目,选择 “Add Files to Runner”,导入 Unity 导出的
UnityLibrary.xcodeproj。
2. 平台配置调整
(1)Android 配置
- 打开
android/build.gradle,确保minSdkVersion与 Unity 一致:buildscript { ext { minSdkVersion = 19 // 需 ≥ Unity 设置的最低版本 compileSdkVersion = 33 targetSdkVersion = 33 } } - 打开
android/settings.gradle,确认 Unity 模块已添加:include ':unityLibrary' project(':unityLibrary').projectDir = file('./unityLibrary')
(2)iOS 配置
- 在 Xcode 中,选中 “Runner” 项目,设置 Minimum Deployments 为 11.0+;
- 选中 “UnityLibrary” 项目,在 Signing & Capabilities 中配置与 Runner 一致的签名;
- 在 Build Settings > Other Linker Flags 中添加
-ObjC(解决链接错误)。
3. 运行与测试
(1)Android 运行
# 查看设备列表
flutter devices
# 运行到指定设备
flutter run --device-id <设备ID>
(2)iOS 运行
- 在 Xcode 中选择连接的 iOS 设备,点击运行按钮(▶️);
- 首次编译可能需要 5-10 分钟(Unity 资源打包)。
成功运行后,你将看到:
- Flutter 界面顶部显示 Unity 3D 场景;
- 底部的方向按钮可控制人物移动;
- 人物位置信息会实时同步到 Flutter 界面。
六、常见问题与解决方案
1. 通信失败(Flutter 调用 Unity 无响应)
- 检查名称匹配:
postMessage的第一个参数(物体名称)必须与 Unity 场景中人物模型的名称完全一致(区分大小写); - 方法名错误:C# 脚本中的方法名(如
Move)必须与 Flutter 调用的名称一致; - 插件版本不匹配:确保 Unity 插件
unity_bridge与 Flutter 插件flutter_unity_widget版本对应。
2. 打包 APK 闪退
- 权限缺失:在
android/app/src/main/AndroidManifest.xml中添加权限:<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> - Gradle 冲突:统一 Unity 和 Flutter 的 Gradle 版本(在
unityLibrary/build.gradle中修改)。
3. iOS 编译错误 “Undefined symbols for architecture arm64”
- 在 Xcode 中,为 UnityLibrary 项目的 Other Linker Flags 添加
-ObjC; - 确认 Unity 导出时勾选了 ARM64 架构(在 Player Settings 中设置)。
七、总结
Unity 与 Flutter 的混合开发,完美结合了专业 3D 引擎与跨平台 UI 框架的优势。通过本文的步骤,你可以实现:
- Unity 3D 场景在 Flutter 中的无缝嵌入;
- 双向通信(Flutter 控制 3D 人物,Unity 反馈状态);
- 跨 Android/iOS 平台的一致体验。
这种方案适合开发中大型 3D 游戏或高保真交互场景,虽然初期配置稍显复杂,但一旦搭建完成,后续开发可专注于业务逻辑,大幅提升开发效率。
如果需要进一步优化,可探索:
- 更复杂的通信协议(如 JSON 数据传输);
- Unity 场景与 Flutter UI 的深度融合(如半透明叠加);
- 资源热更新方案(结合 Firebase 或自定义服务器)。
更多推荐
所有评论(0)