Flutter集成Unity游戏插件flutter_unity_widget的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter集成Unity游戏插件flutter_unity_widget的使用

flutter_unity_widget

All Contributors Pub Version License PRs Welcome

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

1 回复

更多关于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项目

  1. 创建Unity项目

    • 打开Unity Hub,创建一个新的Unity项目。
    • 在Unity中,确保你的项目设置正确,比如平台设置(通常需要设置Android和iOS平台)。
  2. 导出Unity项目

    • 在Unity中,通过File > Build Settings打开构建设置。
    • 选择平台(例如Android或iOS),然后点击Switch Platform
    • 确保Player Settings中的包名(Bundle Identifier)与你的Flutter项目中的包名一致。
    • 点击Build并选择一个目录来导出Unity项目。这个目录通常会成为Flutter项目中的一个子目录。
  3. 复制UnityPlayer.framework(iOS)或libunity.so(Android)

    • 对于iOS,将导出的UnityFramework文件夹复制到Flutter项目的ios/目录下。
    • 对于Android,将导出的libs文件夹中的libunity.so文件复制到Flutter项目的android/app/src/main/jniLibs/对应的架构文件夹中。

步骤 3: 在Flutter中集成Unity

  1. 修改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项目进行调整。

  1. 在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目录中,并调整路径。
  • 上述代码示例中的onUnityMessageonUnityCreated回调函数展示了如何从Unity接收消息和如何向Unity发送消息。

步骤 4: 运行Flutter项目

确保所有配置正确后,运行Flutter项目:

flutter run

这将启动你的Flutter应用,并在其中嵌入Unity内容。根据Unity项目的复杂性和Flutter环境的配置,启动时间可能会有所不同。

注意事项

  • 确保你的开发环境(如Android Studio、Xcode)配置正确,以便能够构建和运行对应的原生平台项目。
  • 根据你的具体需求,可能需要在Unity和Flutter之间进行更多的消息传递和同步。
  • 调试时,可以利用Flutter和Unity的日志输出功能来诊断问题。
回到顶部