Flutter集成Unity游戏插件flutter_unity_widget的使用
Flutter集成Unity游戏插件flutter_unity_widget的使用
flutter_unity_widget
Flutter unity 3D widget for embedding Unity in Flutter. Now you can make awesome gamified features of your app in Unity and get it rendered in a Flutter app both in fullscreen and embeddable mode. Works great on Android, iPad OS, iOS, Web
.
注意事项
- 使用Windows或Mac导出和构建项目。Ubuntu用户在Unity导出时报告了很多错误。
- 模拟器支持有限,需要特殊设置。请使用物理设备进行Android和iOS测试。
- 支持Unity 2019.4.3或更高版本,推荐使用最新的LTS版本。
- 在Android上仅使用OpenGLES3作为图形API以确保AR兼容性。
安装
首先,在pubspec.yaml
文件中添加依赖项:
dependencies:
flutter_unity_widget: ^2022.2.0
然后在Dart代码中导入它:
import 'package:flutter_unity_widget/flutter_unity_widget.dart';
您需要打开并导出一个Unity项目,即使只是为了运行示例。如果只在Flutter中包含此小部件,您的构建将会失败!
示例Demo
以下是一个简单的示例,展示了如何将Unity场景嵌入到Flutter应用中,并与Unity进行通信。
简单示例
import 'package:flutter/material.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';
void main() {
runApp(
const MaterialApp(
home: UnityDemoScreen(),
),
);
}
class UnityDemoScreen extends StatefulWidget {
const UnityDemoScreen({Key? key}) : super(key: key);
@override
State<UnityDemoScreen> createState() => _UnityDemoScreenState();
}
class _UnityDemoScreenState extends State<UnityDemoScreen> {
static final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
UnityWidgetController? _unityWidgetController;
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
bottom: false,
child: WillPopScope(
onWillPop: () async {
// Pop the category page if Android back button is pressed.
return true;
},
child: Container(
color: Colors.yellow,
child: UnityWidget(
onUnityCreated: onUnityCreated,
),
),
),
),
);
}
// Callback that connects the created controller to the unity controller
void onUnityCreated(controller) {
_unityWidgetController = controller;
}
}
与Unity通信的示例
import 'package:flutter/material.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
static final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
UnityWidgetController? _unityWidgetController;
double _sliderValue = 0.0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('Unity Flutter Demo'),
),
body: Card(
margin: const EdgeInsets.all(8),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Stack(
children: <Widget>[
UnityWidget(
onUnityCreated: onUnityCreated,
onUnityMessage: onUnityMessage,
onUnitySceneLoaded: onUnitySceneLoaded,
fullscreen: false,
),
Positioned(
bottom: 20,
left: 20,
right: 20,
// <You need a PointerInterceptor here on web>
child: Card(
elevation: 10,
child: Column(
children: <Widget>[
const Padding(
padding: EdgeInsets.only(top: 20),
child: Text("Rotation speed:"),
),
Slider(
onChanged: (value) {
setState(() {
_sliderValue = value;
});
setRotationSpeed(value.toString());
},
value: _sliderValue,
min: 0,
max: 20,
),
],
),
),
),
],
),
),
),
);
}
// Communication from Flutter to Unity
void setRotationSpeed(String speed) {
_unityWidgetController?.postMessage(
'Cube',
'SetRotationSpeed',
speed,
);
}
// Communication from Unity to Flutter
void onUnityMessage(message) {
print('Received message from unity: ${message.toString()}');
}
// Callback that connects the created controller to the unity controller
void onUnityCreated(controller) {
_unityWidgetController = controller;
}
// Communication from Unity when new scene is loaded to Flutter
void onUnitySceneLoaded(SceneLoaded? sceneInfo) {
if (sceneInfo != null) {
print('Received scene loaded from unity: ${sceneInfo.name}');
print('Received scene loaded from unity buildIndex: ${sceneInfo.buildIndex}');
}
}
}
API
pause()
:暂停Unity播放器resume()
:恢复Unity播放器unload()
:卸载Unity播放器(需Unity 2019.4.3或更高版本)quit()
:退出Unity播放器postMessage(String gameObject, methodName, message)
:从Flutter调用Unity命令onUnityMessage(data)
:Unity到Flutter的消息绑定和监听器onUnityUnloaded()
:当Unity卸载时的监听器onUnitySceneLoaded(String name, int buildIndex, bool isLoaded, bool isValid,)
:新场景加载时的监听器
更多信息
有关更多详细信息和高级配置,请参考官方文档。
更多关于Flutter集成Unity游戏插件flutter_unity_widget的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter集成Unity游戏插件flutter_unity_widget的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中集成Unity游戏插件flutter_unity_widget
可以让你在Flutter应用中嵌入Unity游戏或3D内容。以下是一个基本的代码案例,展示如何在Flutter项目中集成和使用flutter_unity_widget
。
步骤 1: 添加依赖
首先,你需要在Flutter项目的pubspec.yaml
文件中添加flutter_unity_widget
依赖。
dependencies:
flutter:
sdk: flutter
flutter_unity_widget: ^x.y.z # 替换为最新版本号
运行flutter pub get
来安装依赖。
步骤 2: 配置Unity项目
-
创建Unity项目:
- 打开Unity Hub,创建一个新的Unity项目。
- 在Unity中,确保你的项目设置正确,比如平台设置(通常需要设置Android和iOS平台)。
-
导出Unity项目:
- 在Unity中,通过
File > Build Settings
打开构建设置。 - 选择平台(例如Android或iOS),然后点击
Switch Platform
。 - 确保
Player Settings
中的包名(Bundle Identifier)与你的Flutter项目中的包名一致。 - 点击
Build
并选择一个目录来导出Unity项目。这个目录通常会成为Flutter项目中的一个子目录。
- 在Unity中,通过
-
复制UnityPlayer.framework(iOS)或libunity.so(Android):
- 对于iOS,将导出的
UnityFramework
文件夹复制到Flutter项目的ios/
目录下。 - 对于Android,将导出的
libs
文件夹中的libunity.so
文件复制到Flutter项目的android/app/src/main/jniLibs/
对应的架构文件夹中。
- 对于iOS,将导出的
步骤 3: 在Flutter中集成Unity
- 修改AndroidManifest.xml(仅Android):
- 在
android/app/src/main/AndroidManifest.xml
中,添加必要的Unity活动配置。这通常包括UnityPlayerActivity的声明。
- 在
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:label="@string/app_name"
android:screenOrientation="sensorLandscape"
android:launchMode="singleTask"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|smallestScreenSize|fontScale|uiMode"
android:hardwareAccelerated="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
注意:上述配置可能需要根据你的具体Unity项目进行调整。
- 在Flutter中使用UnityWidget:
import 'package:flutter/material.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Unity Integration'),
),
body: Center(
child: UnityWidget(
onUnityMessage: (message) {
print('Unity to Flutter: $message');
},
onUnityCreated: (controller) {
// 可以在这里发送消息给Unity
controller.send('Hello from Flutter!');
},
// 指定Unity项目的lib路径(根据平台不同而异)
unityPlayerPath: DefaultAssetBundle.of(context)
.join('assets', 'UnityExport', 'build.unity3d'), // 对于Android和iOS,路径可能不同
),
),
),
);
}
}
注意:
unityPlayerPath
需要根据你的Unity项目导出位置进行调整。对于Android,通常是一个APK或AAB文件路径(但在Flutter集成中,通常使用libunity.so)。对于iOS,通常是一个Framework路径。在实际集成中,你可能需要将Unity导出的内容(如UnityFramework.framework
)正确放置在Flutter项目的iOS目录中,并调整路径。- 上述代码示例中的
onUnityMessage
和onUnityCreated
回调函数展示了如何从Unity接收消息和如何向Unity发送消息。
步骤 4: 运行Flutter项目
确保所有配置正确后,运行Flutter项目:
flutter run
这将启动你的Flutter应用,并在其中嵌入Unity内容。根据Unity项目的复杂性和Flutter环境的配置,启动时间可能会有所不同。
注意事项
- 确保你的开发环境(如Android Studio、Xcode)配置正确,以便能够构建和运行对应的原生平台项目。
- 根据你的具体需求,可能需要在Unity和Flutter之间进行更多的消息传递和同步。
- 调试时,可以利用Flutter和Unity的日志输出功能来诊断问题。