Flutter通过flutter_unity_widget嵌入Unity3D

实现方案:采用flutter开源组件flutter_unity_widget

环境搭建Unity

1、创建flutter项目flutter_unity_demo

2、在pubspec.paml文件dependencies添加flutter_unity_widget: ^2022.2.0,执行Pub get导入组件

3、在工程目录下创建unity文件夹

4、在unity目录下创建unity_demo的3D工程

5、下载flutter_unity_widget提供的unity插件

在unity_demo项目Assets右键导入(import package)插件unitypackages(注:我导入的是FlutterUnityIntegration-v4-WithDemo)会得到以下目录,这个时候Flutter打包的方式如下图

Flutter通过flutter_unity_widget嵌入Unity3D_第1张图片Flutter通过flutter_unity_widget嵌入Unity3D_第2张图片

7、修改Assets/FlutterUnityIntegration/Editor/Build.cs文件

DoBuildAndroid方法:
var options = BuildOptions.AcceptExternalModificationsToPlayer;

替换为:

var options = BuildOptions.AllowDebugging;

EditorUserBuildSettings.exportAsGoogleAndroidProject = true;

BuildIOS 方法:

var options = BuildOptions.AcceptExternalModificationsToPlayer;

替换为:

var options = BuildOptions.AllowDebugging;

8、为了方便测试创建Cube,绑定Assets/FlutterUnityIntegration/Demo/Rotote.cs脚本并调整好摄像头对准新创建的Cube

Flutter加载unity

  1. 创建UnityPage页面实现以下代码

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

class UnityPage extends StatefulWidget {
  const UnityPage({super.key});

  @override
  _UnityPageState createState() => _UnityPageState();
}

class _UnityPageState extends State {
  UnityWidgetController? _unityWidgetController;
  double _sliderValue = 0.0;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _unityWidgetController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: const Text("this Unity"),
      ),
      body: Container(
        child: Stack(
          children: [
            UnityWidget(
                onUnityCreated: onUnityCreated,
                onUnityMessage: onUnityMessage,
                onUnitySceneLoaded: onUnitySceneLoaded,
                fullscreen: false),
            Positioned(
                bottom: 10,
                left: 15,
                right: 15,
                child: Container(
                  width: MediaQuery.of(context).size.width,
                  child: Column(
                    children: [
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Slider(
                          onChanged: (value) {
                            setState(() {
                              _sliderValue = value;
                            });
                            setRotationSpeed(value.toString());
                          },
                          value: _sliderValue,
                          min: 0,
                          max: 20,
                        ),
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          MaterialButton(
                            onPressed: () {
                              _unityWidgetController!.pause();
                            },
                            child: const Text("Pause"),
                          ),
                          // Expanded(child: SizedBox()),
                          MaterialButton(
                            onPressed: () {
                              _unityWidgetController!.resume();
                            },
                            child: const Text("Resume"),
                          ),
                        ],
                      ),
                    ],
                  ),
                )),
          ],
        ),
      ),
    );
  }

  void setRotationSpeed(String speed) {
    //这里需要看看给3d模型绑定的脚本
    _unityWidgetController!.postMessage(
      'Cube',
      'SetRotationSpeed',
      speed,
    );
  }

  void onUnitySceneLoaded(scene) {
    print('Received scene loaded from unity: ${scene.name}');
    print('Received scene loaded from unity buildIndex: ${scene.buildIndex}');
  }

  void onUnityMessage(message) {}

  void onUnityCreated(controller) {
    this._unityWidgetController = controller;
  }
}

2、在main.dart修改flutter启动页面为UnityPage

3、等待原生集成unity后运行

iOS集成

1、打开unity项目 file - Build Setings选择iOS(iOS打包插件没安装点击右侧按钮安装)设置需要的配置信息

Flutter通过flutter_unity_widget嵌入Unity3D_第3张图片

 Flutter通过flutter_unity_widget嵌入Unity3D_第4张图片

  1. 使用flutter - export ios生成iOS工程文件,文件会自动创建到flutter项目下ios文件夹内

Flutter通过flutter_unity_widget嵌入Unity3D_第5张图片

 Flutter通过flutter_unity_widget嵌入Unity3D_第6张图片

  1. 打开flutter项目内iOS工程Runner.xcworkspace,在终端cd 到flutter项目内iOS目录下。执行pod install 导入flutter引用的组件

Flutter通过flutter_unity_widget嵌入Unity3D_第7张图片

导入UnityLibrary工程,在Runner工程目录下方空白右键Add Files to “Runner”,选择UnityLibrary/Unity-iPhone.xcodeproj,点击Add添加,会得到如下工程目录结构

Flutter通过flutter_unity_widget嵌入Unity3D_第8张图片

5、绑定一下Unity-iPhone Data资源,编译一下Unity-iPhone

Flutter通过flutter_unity_widget嵌入Unity3D_第9张图片

6、在Runner工程中添加UnityFramework.framework

Flutter通过flutter_unity_widget嵌入Unity3D_第10张图片

7、通过flutter_unity_widget初始化unity项目

swift:打开ios/Runner/AppDelegate.swift 添加一下代码

     import UIKit

     import Flutter

+    import flutter_unity_widget

     @UIApplicationMain

     @objc class AppDelegate: FlutterAppDelegate {

         override func application(

             _ application: UIApplication,

             didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?

         ) -> Bool {

+            InitUnityIntegrationWithOptions(argc: CommandLine.argc, argv: CommandLine.unsafeArgv, launchOptions)

             GeneratedPluginRegistrant.register(with: self)

             return super.application(application, didFinishLaunchingWithOptions: launchOptions)

         }

     }

Object-C:打开ios/Runner/main.m 添加一下代码

+    #import "flutter_unity_widget.swift.h"

     int main(int argc, char * argv[]) {

          @autoreleasepool {

+             InitUnityIntegration(argc, argv);

              return UIApplicationMain(argc,argv,nil, NSStringFromClass([AppDelegate class]));

          }

     }

8、在Runner项目中ios/Runner/Info.plist添加flutterH5桥梁

+        io.flutter.embedded_views_preview

+        YES

运行flutter至iOS得到以下界面:

Flutter通过flutter_unity_widget嵌入Unity3D_第11张图片

Android集成

1、打开unity项目 file - Build Setings选择Android(Android打包插件没安装点击右侧按钮安装)设置需要的配置信息

Flutter通过flutter_unity_widget嵌入Unity3D_第12张图片

Flutter通过flutter_unity_widget嵌入Unity3D_第13张图片

2、使用flutter - export Android生成Android工程文件,文件会自动创建到flutter项目下android文件夹内,也会自动导入Android项目

Flutter通过flutter_unity_widget嵌入Unity3D_第14张图片

 Flutter通过flutter_unity_widget嵌入Unity3D_第15张图片

3、配置NDK信息打开android/local.properties添加ndk.dir=/Applications/Unity/Hub/Editor/2020.3.19f1/PlaybackEngines/AndroidPlayer/NDK  注:2020.3.19f1替换为自己安装的unity版本号

  1. 打开android/app/build.gradle增加以下代码

 dependencies {

+        implementation project(':unityLibrary')

     }

     buildTypes {

         release {

             signingConfig signingConfigs.debug

         }

+        debug {

+            signingConfig signingConfigs.debug

+        }

+        profile {

+            signingConfig signingConfigs.debug

+        }

+        innerTest {

+            matchingFallbacks = ['debug', 'release']

+        }

}

  1. 打开gradle.properties添加:

unityStreamingAssets=.unity3d, google-services-desktop.json, google-services.json, GoogleService-Info.plist

注:运行遇到minSdkVersion版本报错,修改/flutter/packages/flutter_tools/gradle/flutter.gradle里的minSdkVersion

运行Flutter到Android设备得到:

Flutter通过flutter_unity_widget嵌入Unity3D_第16张图片

你可能感兴趣的:(unity,flutter,android,ios)