Flutter通过flutter_unity_widget嵌入Unity3D

这篇具有很好参考价值的文章主要介绍了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 unity,unity,flutter,android,iosflutter unity,unity,flutter,android,ios

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<UnityPage> {
  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 unity,unity,flutter,android,ios

 flutter unity,unity,flutter,android,ios

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

flutter unity,unity,flutter,android,ios

 flutter unity,unity,flutter,android,ios

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

flutter unity,unity,flutter,android,ios

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

flutter unity,unity,flutter,android,ios

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

flutter unity,unity,flutter,android,ios

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

flutter unity,unity,flutter,android,ios

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桥梁

<dict>

+        <key>io.flutter.embedded_views_preview</key>

+        <string>YES</string>

</dict>

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

flutter unity,unity,flutter,android,ios

Android集成

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

flutter unity,unity,flutter,android,ios

flutter unity,unity,flutter,android,ios

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

flutter unity,unity,flutter,android,ios

 flutter unity,unity,flutter,android,ios

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 unity,unity,flutter,android,ios文章来源地址https://www.toymoban.com/news/detail-673259.html

到了这里,关于Flutter通过flutter_unity_widget嵌入Unity3D的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter Widget 生命周期 & key探究

    在Flutter中,一切皆是Widget(组件),Widget的功能是“描述一个UI元素的配置数据”,它就是说,Widget其实并不是表示最终绘制在设备屏幕上的显示元素,它只是描述显示元素的一个配置数据。 实际上,Flutter中真正代表屏幕上显示元素的类是 Element,也就是说Widget 只是描述

    2024年02月08日
    浏览(56)
  • 【Flutter 工程】005-代码分离实践:flutter_hooks & functional_widget

    在Flutter开发中,“嵌套地狱”(Nesting Hell)是指在构建复杂的UI布局时,由于多层嵌套的组件结构,代码变得冗长、难以维护和理解的情况。 Flutter使用组件树的方式来构建用户界面,每个UI元素都是一个组件,可以包含其他组件。在某些情况下,特别是当需要实现复杂的布局

    2024年02月06日
    浏览(98)
  • flutter开发实战-父子Widget组件调用方法

    flutter开发实战-父子Widget组件调用方法 在最近开发中遇到了需要父组件调用子组件方法,子组件调用父组件的方法。这里记录一下方案。 父组件使用globalKey.currentState调用子组件具体方法,子组件通过方法回调callback方法调用父组件的方法。 例如示例中的 例如父组件 父组件使

    2024年02月15日
    浏览(43)
  • Flutter源码分析笔记:Widget类源码分析

    Flutter源码分析笔记 Widget类源码分析 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.net Email: 291148484@163.com. Shenzhen China Address of this article: https://blog.csdn.net/qq_28550263/article/details/132259681 【介绍】:本文记录阅读与分析Flutter源码 - Widget类源码分析。 Widget类是Flu

    2024年02月12日
    浏览(45)
  • flutter开发实战-RepaintBoundary实现Widget截图功能

    flutter开发实战-RepaintBoundary实现Widget截图功能 在开发中,遇到需要使用截图,像iOS可以截图UIView获取到UIImage,在flutter中可以使用RepaintBoundary实现截图功能 相机拍摄的图片: RepaintBoundary截图后的图片 RepaintBoundary是绘制边界。 如果CustomPaint有子节点,为了避免子节点不必要的

    2024年02月15日
    浏览(45)
  • flutter开发实战-获取Widget的大小及位置

    flutter开发实战-获取Widget的大小及位置 最近开发过程中需要获取Widget的大小及位置,这时候就需要使用到了GlobalKey了和WidgetsBinding.instance.addPostFrameCallback了 该函数的作用: flutter中的界面组件Widget每一帧渲染在界面上,addPostFrameCallback功能是在每一帧绘制完成后再回调执行自定

    2024年02月13日
    浏览(47)
  • Flutter Widget Life Cycle 组件生命周期

    了解 widget 生命周期,对我们开发组件还是很重要的。 今天会把无状态、有状态组件的几个生命周期函数一起过下。 原文 https://ducafecat.com/blog/flutter-widget-life-cycle https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html 无状态组件

    2024年02月15日
    浏览(41)
  • [Flutter]理解Widget-Key的作用

    运行结果如下图所示: ​​​​​​​      /// 运行并依次点击删除两次, 根据情况可以发现其更新结果: /// (1) StatelessWidget不管是否设置了Key或者前后Key是否相同, 其背景色都没有复用; /// (2) StatefulWidget未设置Key的时候, 其背景色不变, 但是数据向上移了; /// (3) StatefulWidget设

    2024年02月11日
    浏览(42)
  • flutter开发实战-自定义Switch开关控件Widget

    flutter开发实战-自定义Switch开关控件 在flutter中实现自定义Switch,主要实现类似IOS的UISwitch样式的开关控件 实现自定义Switch的Widget,主要实现交织动画。 交织动画 有些时候我们可能会需要一些复杂的动画,这些动画可能由一个动画序列或重叠的动画组成。一个动画组合在不同

    2024年02月13日
    浏览(50)
  • flutter开发实战-BackdropFilter高斯模糊子Widget控件

    flutter开发实战-BackdropFilter高斯模糊子Widget。 最近开发过程中遇到需要将控件进行模糊,比如iOS的effect的模糊效果。那在flutter中就需要用到了BackdropFilter BackdropFilter属性定义 其中ImageFilter的filter是必须传的,child为子控件。 ImageFilter一下两种两种构造方法 设置背景高斯模糊

    2024年02月14日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包