美文网首页
Flutter 与 Unity 通信

Flutter 与 Unity 通信

作者: 简栋梁 | 来源:发表于2021-09-12 23:30 被阅读0次

    概要

    Demo 说明

    Demo 通过 flutter-unity-view-widget 库,达到 Flutter 内嵌 Unity 目的
    主要功能:

    • flutter-unity-view-widget 为 Unity 提供依赖库导出插件,将 Unity 项目构建成 Android、IOS 依赖库
    • flutter-unity-view-widget 为 Flutter 提供组件库,将 Unity 视图以组件的形式渲染,并提供 Flutter、Unity 双向通信接口
    Demo 预览

    开发环境
    Demo 使用了两个操作系统,所以会产生一些操作不便之处
    win10:Unity 开发环境
    macOS:APP 开发环境
    macOS 环境操作,标记为 macOS。未标记的,都是 win10 环境操作


    Flutter API 文档

    UnityWidget 组件属性
    • fullscreen
      布尔值,是否全屏显示 UnityWidget 组件
    UnityWidget 组件生命周期
    • onUnityMessage(data)
      触发时机:Unity 通过 SendMessageToFlutter 发布消息
    • onUnitySceneLoaded(String name, int buildIndex, bool isLoaded, bool isValid)
      触发时机:Unity 场景加载完成
    • onUnityUnloaded()
      触发时机:Unity 场景被销毁
    UnityWidgetController API
    • pause()
      暂停 Unity 循环
    • resume()
      继续 Unity 循环
    • unload()
      销毁 Unity 场景
    • quit()
      退出 Unity 应用
    • postMessage(String gameObject, methodName, message)
      调用 Unity 类方法

    Unity API 文档

    • SendMessageToFlutter(string)
      发布消息,Flutter 通过 onUnityMessage 订阅消息

    初始化 Unity 项目

    新建项目

    Unity 版本要求:2019.4.3+

    替换案例场景
    新建方块 Cube、空物体 CanvasController

    安装 Unity 插件

    克隆 git 仓库
    git clone https://github.com/juicycleff/flutter-unity-view-widget.git
    
    插件粘贴至 Unity 项目
    mkdir ./demoFlutterUnity/ThirdpartyPackage
    cp ./flutter-unity-view-widget/scripts/FlutterUnityIntegration-v4.1.0.unitypackage ./demo_flutter_unity/unity/demoFlutterUnity/ThirdpartyPackage/FlutterUnityIntegration-v4.1.0.unitypackage
    

    Unity 项目编写

    编写脚本
    • UMMInject.cs
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class UMMInject : MonoBehaviour
    {
        void Start()
        {
            gameObject.AddComponent<UnityMessageManager>();
        }
    }
    
    • CubeInteraction.cs
    using System;
    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class CubeInteraction: MonoBehaviour, IEventSystemHandler
    {
        [SerializeField]
        Vector3 RotateAmount;
    
        void Start()
        {
            RotateAmount = new Vector3(1, 1, 1);
        }
    
        void Update()
        {
            gameObject.transform.Rotate(RotateAmount * Time.deltaTime * 10);
    
            for (int i = 0; i < Input.touchCount; ++i)
            {
                if (Input.GetTouch(i).phase.Equals(TouchPhase.Began))
                {
                    var hit = new RaycastHit();
    
                    Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
    
                    if (Physics.Raycast(ray, out hit))
                    {
                        UnityMessageManager.Instance.SendMessageToFlutter("方块被触碰");
                    }
                }
            }
        }
    
        // (Flutter 调用)设置旋转速度
        public void SetRotationSpeed(String message)
        {
            float value = float.Parse(message);
            RotateAmount = new Vector3(value, value, value);
        }
    }
    
    绑定脚本

    UnityMessageManager.cs 是插件内置脚本


    初始化 Flutter 项目

    macOS 新建项目
    flutter create demo_flutter_unity
    

    Flutter 项目生成后,复制副本到 win10,作为 Unity 项目容器,用于生成 Flutter 依赖库

    移动 Unity 项目 至 Flutter 项目
    mkdir ./demo_flutter_unity/unity
    cp -r ./demoFlutterUnity ./demo_flutter_unity/unity
    

    Unity Player Settings

    Android
    IOS


    导出 Android、IOS 依赖库

    修改源码
    // DoBuildAndroid()
    
    // var options = BuildOptions.AcceptExternalModificationsToPlayer;
    var options = BuildOptions.AllowDebugging;
    EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
    
    // BuildIOS()
    
    // var options = BuildOptions.AcceptExternalModificationsToPlayer;
    var options = BuildOptions.AllowDebugging;
    
    生成 unityLibrary 库

    导出前,需要切换到对应的构建平台
    Export Android:Android 依赖,导出到 android/unityLibrary
    Export Android:IOS 依赖,导出到 ios/UnityLibrary

    macOS 移动 Flutter 依赖库 至 macOS Flutter 项目

    macOS Android 项目配置

    android/settings.gradle
    + include ":unityLibrary"
    + project(":unityLibrary").projectDir = file("./unityLibrary")
    
    android/build.gradle
    allprojects {
        repositories {
            + flatDir {
            +     dirs "${project(':unityLibrary').projectDir}/libs"
            + }
        }
    }
    
    android/app/build.gradle
    android {
        defaultConfig {
            minSdkVersion xxx    // xxx 需要 Unity Player Settings Android SDK 版本号一致
        }
    }
    
    dependencies {
        + implementation project(':unityLibrary')
    }
    

    macOS IOS 项目配置

    注意:正常情况下,按照该配置,构建 IOS 应用时,还会出现一些小问题,需要按照报错信息,自行解决(如:文件访问权限、CocoaPods 相关等等)

    导入原生工程
    导入、配置 Unity-iPhone 工程
    配置 UnityFramework
    配置团队、签名
    单独构建 UnityFramework

    macOS Flutter 项目编写

    pubspec.yaml
    dependencies:
      + flutter_unity_widget: ^4.1.0
    
    lib/main.dart
    import 'package:flutter/material.dart';
    import 'package:flutter_unity_widget/flutter_unity_widget.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      static final GlobalKey<ScaffoldState> _scaffoldKey =
          GlobalKey<ScaffoldState>();
      late 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('Flutter 与 Unity 通信'),
            ),
            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,
                    child: Card(
                      elevation: 10,
                      child: Column(
                        children: <Widget>[
                          Padding(
                            padding: const EdgeInsets.only(top: 20),
                            child: Text("旋转速度"),
                          ),
                          Slider(
                            onChanged: (value) {
                              setState(() {
                                _sliderValue = value;
                              });
                              setRotationSpeed(value.toString());
                            },
                            value: _sliderValue,
                            min: 0,
                            max: 20,
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
      // Communcation from Flutter to Unity
      void setRotationSpeed(String speed) {
        _unityWidgetController.postMessage(
          'Cube',
          'SetRotationSpeed',
          speed,
        );
      }
    
      void onUnityMessage(message) {
        print('Unity 消息推送: ${message.toString()}');
      }
    
      void onUnityCreated(controller) {
        this._unityWidgetController = controller;
      }
    
      void onUnitySceneLoaded(SceneLoaded? sceneInfo) {
        print('场景名称: ${sceneInfo!.name}');
        print(
            '场景编号: ${sceneInfo!.buildIndex}');
      }
    }
    
    运行项目
    flutter emulators
    // apple_ios_simulator • iOS Simulator  • Apple  • ios
    // Pixel_2_API_30      • Pixel 2 API 30 • Google • android
    
    flutter emulators --launch apple_ios_simulator
    
    flutter run
    

    相关文章

      网友评论

          本文标题:Flutter 与 Unity 通信

          本文链接:https://www.haomeiwen.com/subject/lgqawltx.html