# Quickstart in Flutter

In this quickstart guide, we will be integrating the ARwayKit SDK in the standard flutter app

## Installed Versions

In this guide, we will be using the following versions of Flutter, Dart, and Unity:

* **Flutter version:** 3.10.5
* **Dart version:** 3.0.5
* **Unity:** 2022.3.29f1 LST

## Download the ARwayKit SDK

**Steps**

1. Download the ARwayKit SDK project from GitHub as a **ZIP**. You can [contact us](https://www.arway.ai/contact) for access to the ARwayKit SDK.

## Creating a Blank Project in Flutter

If you have already created a Flutter project, you may skip the installation instructions and proceed with the next steps. Otherwise, kindly refer to the [Flutter documentation](https://docs.flutter.dev/) for installation guidelines.

```
flutter create my_project_name
```

## Configure the Flutter Project&#x20;

{% hint style="info" %}
We are using the **flutter\_unity\_widget** package to integrate our ARwayKit SDK with Flutter. <https://pub.dev/packages/flutter_unity_widget>
{% endhint %}

**Steps**

1. Open the `pubspec.yaml` file and add **flutter\_unity\_widget** to it under the *dependencies section.*

   ```yaml
   dependencies:
     flutter_unity_widget: ^2022.2.0
   ```

   * Now inside your Dart code you can import it.

     ```dart
     import 'package:flutter_unity_widget/flutter_unity_widget.dart';
     ```
2. After adding the dependencies, you need to fetch them into your Flutter project. \
   \&#xNAN;*You can fetch the dependencies by* -
   * From the terminal: Run `flutter pub get`\
     **OR**
   * From Android Studio/IntelliJ: Click **Packages get** in the action ribbon at the top of `pubspec.yaml`.
   * From VS Code: Click **Get Packages** located on the right side of the action ribbon at the top of `pubspec.yaml`.
3. Then add an import statement for using the package inside your Dart code.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>We have created sample Dart files with unity pre-integrated to help you get started quickly with the project. The Dart files are located in the <strong>lib folder</strong> within the Flutter project.</p></div>

## Add the ARwayKit SDK to the Flutter Folder

**Steps:**

1. Download the Source code (zip) from the[ GitHub repo](https://github.com/arway-ai/ARwayKit-Unity-SDK/releases) (unity-viewer-sdk-3.1.4.zip).&#x20;
2. Extract the source code from the downloaded zip file by right-clicking on it and selecting "Extract All" or using a zip extraction tool of your choice.
3. In your Flutter app directory, create a new folder named "unity".

   * Move the extracted Unity project folder into the newly created "unity" folder. The expected path should be: `unity/unity-viewer-sdk-3.1.4/...`

   ```
   .
   ├── my_project_name
   │   └── .dart_tool
   │   └── .idea
   │   └── android
   │   └── ios
   │   └── lib
   │   └── linux
   │   └── macos
   │   └── test
   │   └── unity    // Create this folder
   │       └── <Your Unity Project>    // Example: unity-viewer-sdk-3.1.4
   │   └── web
   │   └── windows
   ```
4. Make sure you have the Unity editor version 2022.3.29f1  installed on your computer. If you don't have it, download and install it from the official Unity website.
5. Open the Unity editor and navigate to the "unity-viewer-sdk-3.1.4" folder by selecting "Open Project" from the Unity editor's file menu and choosing the appropriate folder.
6. Before opening the project, ensure that you have the required modules downloaded and installed for both Android and iOS builds. If you haven't already, download and install the following modules in the Unity Hub:
   * Android Build Support
   * OpenJDK
   * Android SDK & NDK Tools
   * iOS Build Support
7. Once you have the required modules installed, open the Unity project by selecting it from the Unity Hub or by double-clicking on the Unity project file in the "unity-viewer-sdk-3.1.4" folder.
8. After opening the project, the Unity editor will start importing the necessary files, and a new Unity editor window will open, displaying the project's contents.

## Update Addressables Groups & Set Account ID and Secret Key

### Getting the Account ID and Secret Key

1. From the ARway Creator Portal, go to "For Developers -> Create a New App -> Enter App Name".
2. Copy your **Account ID** and **SecretKey** for that App.

<figure><img src="https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2FJu8eWIZGmYcfox7u5qyl%2F9FyMWaoEPl.png?alt=media&#x26;token=81fda761-7ae0-4e6c-824a-85cb6f8c3477" alt=""><figcaption><p>The "For Developers" page of the Creator Portal</p></figcaption></figure>

### **Adding the Account ID and Secret Key**

1. In the Project Window, go to "Assets -> ARway -> Viewer Mode -> Resource-> ARWayKitConfig " and add your credentials for the Account ID and Secret Key.

<figure><img src="https://4128853559-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlDytDSBRx8P4ZZXD57DA%2Fuploads%2FdW8rwkubF3zq4lAMJ1j4%2Fimage.png?alt=media&#x26;token=e121d95c-e745-45eb-b60e-212dded7bb83" alt=""><figcaption><p>AR Way Kit Config</p></figcaption></figure>

### **Switch Build Platform to** Android or iOS.

1. "File -> Build Settings -> Build -> Select iOS/Android"

### **Updating the** Addressables Groups

1. Navigate to "Window -> Asset Management -> Addressable -> Groups".
2. In the Addressables Groups window, click on "Build -> New Build -> Default Build Script".

{% hint style="info" %}
When making any changes that affect localization strings, you will need to update the Addressables Groups.
{% endhint %}

## Configure the flutter\_unity\_widget Package

Configuring the [flutter\_unity\_widget](https://github.com/juicycleff/flutter-unity-view-widget) can be done by following the instructions in their README.md, or by following the steps outlined below.

{% hint style="info" %}
Make sure to add the Account ID and Secret Key variables to the Unity project. Follow the guide for [Integrating Unity Packages](https://docs.arway.ai/arway-sdk/quickstart-in-unity) for instructions.
{% endhint %}

**Steps**

1. Download the [*fuw-2022.2.0.unitypackage*](https://github.com/juicycleff/flutter-unity-view-widget/blob/master/unitypackages/fuw-2022.2.0.unitypackage) file and place it into the Unity project folder.
   * The expected path is `unity/unity-viewer-sdk-3.1.4/fuw-2022.2.0.unitypackage`
2. Using Unity, open the Unity project, go to **File -> Build Settings -> Player Settings -> Settings for Android -> Other Settings** and change the following under the **Configuration** section:
   * In **Scripting Backend**, change to IL2CPP
   * In **Target Architectures**, select ARMv7 and ARM64
3. **File -> Build Settings -> Player Settings -> Settings for iOS -> Other Settings** and change the following under the **Configuration** section:
   * In **Scripting Backend**, change to IL2CPP
   * In **Target Device**, choose iPhone Only
   * In **Target SDK**, choose Device SDK
4. After importing, click on **Flutter** and select the **Export Android Debug** or **Export Android Release** option (will export to *android/unityLibrary*) or the **Export iOS Debug** or **Export iOS Release** option (will export to *ios/UnityLibrary*).

{% hint style="info" %}
The "**Release**" export option is recommended due to optimizations.
{% endhint %}

To build for Android or iOS, follow the instructions below:

<details>

<summary><strong>Android</strong></summary>

6.1. Open the *android/settings.gradle* file and add the following:

```git
+    include ":unityLibrary"
+    project(":unityLibrary").projectDir = file("./unityLibrary")
+    include ':unityLibrary:xrmanifest.androidlib'
```

6.2. The minimum SDK version required for this app is 24. Open the *android/app/build.gradle* file and change the following:

```git
     android {
          defaultConfig {
+            minSdkVersion 24                                                                            
          }  
     }
     dependencies {
+        implementation project(':unityLibrary')
     }
```

6.3. If you need to build a release package, open the *android/app/build.gradle* file and change the following:

```git
     buildTypes {
         release {
             signingConfig signingConfigs.debug
         }
+        debug {
+            signingConfig signingConfigs.debug
+        }
+        profile {
+            signingConfig signingConfigs.debug
+        }
+        innerTest {
+            matchingFallbacks = ['debug', 'release']
+        }
+   }
```

The code above use the `debug` signConfig for all buildTypes, which can be changed as you well if you need specify signConfig.

6.4. **(Optional)** If you use `minifyEnabled true` in your *android/app/build.gradle* file, open the *android/unityLibrary/proguard-unity.txt* and change the following:

```git
+    -keep class com.xraph.plugin.** {*;}
```

6.5. Open the *android/unityLibrary/src/main/AndroidManifest.xml* and change the following:

<pre class="language-git"><code class="lang-git"><strong>-    &#x3C;provider android:name="androidx.core.content.FileProvider" android:authorities="com.arway.sdkviewer.unitywebview.fileprovider" android:exported="false" android:grantUriPermissions="true"> 
</strong>-        &#x3C;meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/unitywebview_file_provider_paths" /> 
-    &#x3C;/provider>
</code></pre>

6.6. **(Optional)** If you want Unity in it's own activity as an alternative, open the *android/unityLibrary/src/main/AndroidManifest.xml* and change the following:

```git
+    <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>
```

</details>

<details>

<summary>iOS</summary>

6.1. Open the *ios/Runner.xcworkspace* (workspace, not the project) file in Xcode, right-click on the Navigator (not on an item), go to **Add Files to "Runner"** and add the *ios/UnityLibrary/Unity-Iphone.xcodeproj* file.

6.2. (Optional) Select the *Unity-iPhone/Data* folder and change the Target Membership for Data folder to UnityFramework.

6.3.1. If you're using Swift, open the *ios/Runner/AppDelegate.swift* file and change the following:

```git
     import UIKit
     import Fluttergit
+    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)
         }
     }
```

6.3.2. If you're using Objective-C, open the *ios/Runner/main.m* file and change the following:

```git
+    #import "flutter_unity_widget.swift.h"

     int main(int argc, char * argv[]) {
          @autoreleasepool {
+             InitUnityIntegration(argc, argv);
              return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
          }
     }
```

6.4. Add the *UnityFramework.framework* file as a library to the Runner project

6.5 If you are using Xcode 14 or a newer version, and your Unity version is older than 2021.3.17f1 or 2022.2.2f1, there is a possibility that your app may crash when running from Xcode. To resolve this issue, you need to disable the Thread Performance Checker feature in Xcode. Follow these steps:

1. Open Xcode and navigate to Product > Scheme > Edit Scheme...
2. With the "Run" option selected on the left side, go to the Diagnostics tab.
3. Uncheck the checkbox for Thread Performance Checker.

6.6 Open the *ios/Runner/Info.plist* and change the following:

```git
     <dict>
+        <key>NSCameraUsageDescription</key> 
+        <string>Used for AR Content and mapping</string> 
+        <key>NSLocationWhenInUseUsageDescription</key> 
+        <string>Used to attach maps with global coordinates and public map searching</string> 
+        <key>NSMicrophoneUsageDescription</key> 
+        <string>Used for creating audio content</string> 
+        <key>NSPhotoLibraryAddUsageDescription</key> 
+        <string>The app requires access to Photos to save media to it.</string> 
+        <key>NSPhotoLibraryUsageDescription</key> 
+        <string>The app requires access to Photos to interact with it.</string> 
     </dict>
```

</details>

## Sample Dart Files

We have created sample Dart files to help you get started quickly with the project.

<details>

<summary>main.dart</summary>

<pre class="language-dart" data-title="main.dart" data-line-numbers><code class="lang-dart"><strong>import 'package:flutter/material.dart';
</strong>
import 'menu_screen.dart';
import 'arwaysdk_unity_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Flutter App',
      theme: ThemeData.dark(),
      initialRoute: '/',
      routes: {
        '/': (context) => MenuScreen(),
        '/unity': (context) => ARwayKitUnityScreen(),
      },
    );
  }
}
</code></pre>

</details>

<details>

<summary>menu_screen.dart</summary>

{% code title="menu\_screen.dart" lineNumbers="true" %}

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

class MenuScreen extends StatefulWidget {
  const MenuScreen({Key? key}) : super(key: key);

  @override
  // ignore: library_private_types_in_public_api
  _MenuScreenState createState() => _MenuScreenState();
}

class _MenuScreenState extends State<MenuScreen> {
  final String title = 'Open ARway SDK';
  final String route = '/unity';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('ARwayKit Flutter Demo'),
      ),
      body: Center(
        child: Column(
          children: [
            const SizedBox(
              height: 32,
            ),
            const Padding(
              padding: EdgeInsets.all(30),
              child: Text(
                'Example scene to show how to link "ARwayKit SDK" scenes with '
                'Flutter.',
                style: TextStyle(
                  fontSize: 24,
                  letterSpacing: 2,
                  wordSpacing: 5,
                  fontStyle: FontStyle.italic,
                ),
              ),
            ),
            const SizedBox(
              height: 96,
            ),
            Padding(
              padding: const EdgeInsets.all(30),
              child: ElevatedButton(
                onPressed: () {
                  Navigator.of(context).pushNamed(route);
                },
                style: ElevatedButton.styleFrom(
                  elevation: 10,
                  primary: Color(0xFF1AB146),
                  minimumSize: Size(192, 64),
                ),
                child: Text(
                  title,
                  style: const TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
```

{% endcode %}

</details>

<details>

<summary>arwaysdk_unity_screen.dart</summary>

{% code title="arwaysdk\_unity\_screen.dart" lineNumbers="true" %}

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

class ARwayKitUnityScreen extends StatefulWidget {
  ARwayKitUnityScreen({Key? key}) : super(key: key);

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

class _ARwayKitUnityScreenState extends State<ARwayKitUnityScreen> {
  static final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  late UnityWidgetController _unityWidgetController;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    _unityWidgetController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Card(
        margin: const EdgeInsets.all(8),
        clipBehavior: Clip.antiAlias,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20.0),
        ),
        child: Stack(
          children: [
            UnityWidget(
              onUnityCreated: _onUnityCreated,
              onUnityMessage: onUnityMessage,
              onUnitySceneLoaded: onUnitySceneLoaded,
              useAndroidViewSurface: true,
              borderRadius: const BorderRadius.all(Radius.circular(70)),
            ),
          ],
        ),
      ),
    );
  }

  void setRotationSpeed(String speed) {
    _unityWidgetController.postMessage(
      'Cube',
      'SetRotationSpeed',
      speed,
    );
  }

  void onUnityMessage(message) {
    print('Received message from unity: ${message.toString()}');
  }

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

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

{% endcode %}

</details>

### **How to use ARway SDK Scenes?**

For how to use the scenes in the **ARwayKit SDK**, kindly look at the documentation for those scenes linked below.

{% content-ref url="../../arway-sdk" %}
[arway-sdk](https://docs.arway.ai/arway-sdk)
{% endcontent-ref %}

## Build And Run:

Run the app on **Android** with the following command. For **iOS**, build an XCode project to deploy it to an iOS device from the IDE of your choice.

```bash
flutter run
```

{% hint style="info" %}
The application must be run on a real device rather than an emulator.
{% endhint %}

## Extras:

Here are some extra methods and APIs which you can implement to communicate to and from Unity using Flutter.&#x20;

### **Props**&#x20;

* `fullscreen` (Enable or disable fullscreen mode on Android)
* `disableUnload` (Disable unload on iOS when unload is called)

### API&#x20;

* `pause()` (Use this to pause unity player)
* `resume()` (Use this to resume unity player)
* `unload()` (Use this to unload unity player)
* `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 a new scene is loaded)

{% hint style="info" %}
To see more details, check out the package's official documentation linked below.&#x20;

<https://pub.dev/documentation/flutter_unity_widget/latest/>
{% endhint %}
