flutter_unity_widget 4.0.3-null-safe copy "flutter_unity_widget: ^4.0.3-null-safe" to clipboard
flutter_unity_widget: ^4.0.3-null-safe copied to clipboard

outdated

Flutter Unity 3D widget for embedding Unity game scenes in flutter. This library now supports Unity as a Library.

flutter_unity_widget #

All Contributors

version MIT License PRs Welcome

Watch on GitHub Star on GitHub

Gitter

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 and iOS. There are now two unity app examples in the unity folder, one with the default scene and another based on Unity AR foundation samples.
Note: Supports only Unity 2019.4.3 or later. UnityFramework does not support emulator.

Installation #

First depend on the library by adding this to your packages pubspec.yaml:

dependencies:
  flutter_unity_widget: ^4.0.1+1

null-safe version

dependencies:
  flutter_unity_widget: ^4.0.3-null-safe

Now inside your Dart code you can import it.

import 'package:flutter_unity_widget/flutter_unity_widget.dart';

Preview #

30 fps gifs, showcasing communication between Flutter and Unity:

gif gif


Setup Project #

For this, there is also a video tutorial, which you can find a here.

Add Unity Project #

  1. Create an unity project, Example: 'UnityDemoApp'.
  2. Create a folder named unity in flutter project folder.
  3. Move unity project folder to unity folder.

Now your project files should look like this.

.
├── android
├── ios
├── lib
├── test
├── unity
│   └── <Your Unity Project>    // Example: UnityDemoApp
├── pubspec.yml
├── README.md

Configure Player Settings #

  1. First Open Unity Project.

  2. Click Menu: File => Build Settings

Be sure you have at least one scene added to your build.

  1. => Player Settings

    Android Platform:

    1. Change Scripting Backend to IL2CPP.

    2. Mark the following Target Architectures :

      • ARMv7 ✅
      • ARM64 ✅

iOS Platform: 1. Depending on where you want to test or run your app, (simulator or physical device), you should select the appropriate SDK on Target SDK.


Add Flutter Unity Package to Unity Project #

Import FlutterUnityPackage.unitypackage to unity/<Your Unity Project>. (You can access the unity packages in the scripts folder too)

Open your unity project in Unity Editor. Now you can export the Unity project with Flutter/Export Android (for Unity versions 2019.3 and up, which uses the new Unity as a Library export format), or Flutter/Export IOS menu.

Please do not use Flutter/Export <Platform> plugin as it was specially added to work with flutter_unity_cli for larger projects

Android will export unity project to android/unityLibrary.

IOS will export unity project to ios/UnityLibrary.


Note: The build unity export script automatically sets things up for you, so you don't have to do anything for android. But if you want to manually set it up, continue, else skip to iOS.

Android Platform Only (Manual Steps)

  1. After exporting the unity game, open Android Studio and then
  2. Add the following to your <Your Flutter Project>/android/settings.gradlefile:
include ":unityLibrary"
project(":unityLibrary").projectDir = file("./unityLibrary")
  1. open <Your Flutter Project>/android/app/build.gradlefile and add:
 dependencies {
     implementation project(':unityLibrary')
 }
  1. To build a release package, you need to add signconfig in UnityExport/build.gradle. The code below use the debug signConfig for all buildTypes, which can be changed as you well if you need specify signConfig.
buildTypes {
    release {
        signingConfig signingConfigs.debug
    }
    debug {
        signingConfig signingConfigs.debug
    }
    profile{
        signingConfig signingConfigs.debug
    }
    innerTest {
        //...
        matchingFallbacks = ['debug', 'release']
    }
}
  1. If you use minifyEnabled true and need to use UnityMessage in Flutter, please add proguard content below:
-keep class com.xraph.plugin.** {*;}
  1. If you want unity in it's own activity as an alternative, just add this to your app AndroidManifest.xml file
<activity
    android:name="com.xraph.plugin.flutter_unity_widget.OverrideUnityActivity"
    android:theme="@style/UnityThemeSelector"
    android:screenOrientation="fullSensor"
    android:launchMode="singleTask"
    android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
    android:hardwareAccelerated="false"
    android:process=":Unity"
>
    <meta-data android:name="com.xraph.plugin.flutter_unity_widget.OverrideUnityActivity" android:value="true" />
</activity>

iOS Platform Only

  1. open your ios/Runner.xcworkspace (workspace!, not the project) in Xcode and add the exported project in the workspace root (with a right click in the Navigator, not on an item -> Add Files to “Runner” -> add the unityLibrary/Unity-Iphone.xcodeproj file
  2. Select the Unity-iPhone/Data folder and change the Target Membership for Data folder to UnityFramework (Optional)
  3. Import flutter unity widget at the top of Runner/Runner/AppDelegate.swift
import flutter_unity_widget
  1. Add to Runner/Runner/AppDelegate.swift before the GeneratedPluginRegistrant call:
InitUnityIntegrationWithOptions(argc: CommandLine.argc, argv: CommandLine.unsafeArgv, launchOptions)

For example

import UIKit
import Flutter
import flutter_unity_widget

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    // Initialize Unity
    InitUnityIntegrationWithOptions(argc: CommandLine.argc, argv: CommandLine.unsafeArgv, launchOptions)

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Or when using Objective-C your main.m should look like this:

#import "flutter_unity_widget.swift.h"

int main(int argc, char * argv[]) {
  @autoreleasepool {
    InitUnityIntegration(argc, argv);
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  }
}
  1. Opt-in to the embedded views preview by adding a boolean property to the app's Info.plist file with the key io.flutter.embedded_views_preview and the value YES.

  2. Add UnityFramework.framework as a Library to the Runner project

AR Foundation ( requires Unity 2019.3.*) #

gif

Check out the Unity AR Foundation Samples Demo Repository

The Demo Repository is not guaranteed to be up-to-date with the latest flutter-unity-view-widget master. Make sure to follow the steps listed below for setting up AR Foundation on iOS and Android in your projects.

iOS

Go to target info list on Xcode and add this key and value;

key: Privacy - Camera Usage Description value: $(PRODUCT_NAME) uses Cameras

Android

If you want to use Unity for integrating Augmented Reality in your Flutter app, a few more changes are required:

  1. Export the Unity Project as previously stated (using the Editor Build script).
  2. Check if the exported project includes all required Unity libraries (.so) files (lib/\<architecture\>/libUnityARCore.so and libarpresto_api.so). There seems to be a bug where a Unity export does not include all lib files. If they are missing, use Unity to build a standalone .apk of your AR project, unzip the resulting apk, and copy over the missing .lib files to the unityLibrary module.
  3. Similar to how you've created the unity-classes module in Android Studio, create similar modules for all exported .aar and .jar files in the unityLibrary/libs folder (arcore_client.aar, unityandroidpermissions.aar, UnityARCore.aar).
  4. Update the build.gradle script of the unityLibrary module to depend on the new modules (again, similar to how it depends on unity-classes).
  5. Finally, set fullscreen: false to disable fullscreen

Add Flutter Unity Package #

Import Flutter .unitypackage to unity/<Your Unity Project>

PS: ^4.0.0 only supports Unity as a Library

Vuforia #

Android

Similar to setting up AR Foundation, but creating a module for the VuforiaWrapper instead.

Thanks to @PiotrxKolasinski for writing down the exact steps:

  1. Change in build.gradle: implementation(name: 'VuforiaWrapper', ext:'aar') to implementation project(':VuforiaWrapper')
  2. In settings.gradle in the first line at the end add: ':VuforiaWrapper'
  3. From menu: File -> New -> New Module choose "import .JAR/.AAR Package" and add lib VuforiaWrapper.arr. Move generated folder to android/
  4. Your App need camera permission (you can set in settings on mobile)

Examples #

Simple Example #

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

void main() {
  runApp(MaterialApp(
    home: UnityDemoScreen()
  ));
}

class UnityDemoScreen extends StatefulWidget {

  UnityDemoScreen({Key key}) : super(key: key);

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

class _UnityDemoScreenState extends State<UnityDemoScreen>{
  static final GlobalKey<ScaffoldState> _scaffoldKey =
      GlobalKey<ScaffoldState>();
  UnityWidgetController _unityWidgetController;

  Widget build(BuildContext context) {

    return Scaffold(
      key: _scaffoldKey,
      body: SafeArea(
        bottom: false,
        child: WillPopScope(
          onWillPop: () {
            // Pop the category page if Android back button is pressed.
          },
          child: Container(
            color: colorYellow,
            child: UnityWidget(
              onUnityCreated: onUnityCreated,
            ),
          ),
        ),
      ),
    );
  }

  // Callback that connects the created controller to the unity controller
  void onUnityCreated(controller) {
    this._unityWidgetController = controller;
  }
}

Communicating with and from Unity #

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>();
  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,
                child: Card(
                  elevation: 10,
                  child: Column(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(top: 20),
                        child: Text("Rotation speed:"),
                      ),
                      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,
    );
  }

  // 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) {
    this._unityWidgetController = controller;
  }

  // Communication from Unity when new scene is loaded to Flutter
  void onUnitySceneLoaded(SceneLoaded sceneInfo) {
    print('Received scene loaded from unity: ${sceneInfo.name}');
    print('Received scene loaded from unity buildIndex: ${sceneInfo.buildIndex}');
  }

}

Props #

  • fullscreen (Enable or disable fullscreen mode on Android)

API #

  • pause() (Use this to pause unity player)
  • resume() (Use this to resume unity player)
  • unload() (Use this to unload unity player) *Requires Unity 2019.4.3 or later
  • quit() (Use this to quit unity player)
  • postMessage(String gameObject, methodName, message) (Allows you invoke commands in Unity from flutter)
  • onUnityMessage(data) (Unity to flutter binding and listener)
  • onUnityUnloaded() (Unity to flutter listener when unity is unloaded)
  • onUnitySceneLoaded(String name, int buildIndex, bool isLoaded, bool isValid,) (Unity to flutter binding and listener when new scene is loaded)

Known issues #

  • Remember to disabled fullscreen in unity player settings to disable unity fullscreen.
  • App crashes on screen exit and re-entry do this

    Build Setting - iOS - Other Settings - Configuration - Enable Custom Background Behaviors

Sponsors

Support this project with your organization. Your donations will be used to help children first and then those in need. Your logo will show up here with a link to your website. [Contribute]

Contributors ✨ #

Thanks goes to these wonderful people (emoji key):

Rex Raphael
Rex Raphael

💻 📖 💬 🐛 👀
Thomas Stockx
Thomas Stockx

💻 📖 💬
Kris Pypen
Kris Pypen

💻 📖 💬
Lorant Csonka
Lorant Csonka

📖 📹

This project follows the all-contributors specification. Contributions of any kind welcome!

850
likes
0
points
2.18k
downloads

Publisher

verified publisherxraph.com

Weekly Downloads

Flutter Unity 3D widget for embedding Unity game scenes in flutter. This library now supports Unity as a Library.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_plugin_android_lifecycle, plugin_platform_interface, stream_transform

More

Packages that depend on flutter_unity_widget