LoginSignup
30
19

More than 3 years have passed since last update.

[Flutter開発]FlutterとARCoreを組み合わせてAndroidのARアプリを作成してみる

Posted at

はじめに

AndroidのスマートフォンでAR(拡張現実)を表示できるアプリを作ってみようと思う。
Androidで動作するARアプリを作る場合はGoogle公式のARCoreを使用するのが有力な候補だと思うが、このARCoreをクロスプラットフォームアプリを作成できるFlutterで使えるようにしたい。

有り難いことに、FlutterでARCoreを使用するための「arcore_flutter_plugin」というパッケージがpubで公開されており、さらにこのパッケージを使用したサンプルも公式のGithubで公開されているので、まずはこのサンプルをAndroid上で動かすことを目標とする。

iPhoneでARアプリを作成したい場合

[Flutter開発]FlutterとARKitを組み合わせてARアプリを作成してみる という記事も作成しているので、こちらを参考にしてほしい。

環境情報

開発環境

  • Windows 10 Home
  • Android Studio 3.4.2
  • Flutter 1.7.8+hotfix.4
  • arcore_flutter_plugin

端末環境

  • Pixel2(Emulator) Android 8.1 Oreo

作成手順

新規のFlutterプロジェクトを作成

新規のFlutterプロジェクトを作成する。名前は「flutter_arcore_test_app」としてみた。
image.png

image.png

image.png

arcore_flutter_pluginのインストール

Flutterプロジェクトを作成できたら、pubspec.yamlを開いてarcore_flutter_pluginの記述を追加する。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  arcore_flutter_plugin: ^0.0.2+1 #この行を追加

main.dartを開き、「Get Dependenceis」を押してarcore_flutter_pluginをインストールする。
image.png

コード0が表示されればインストールは成功。
image.png

main.dartの書き換え

main.dartを以下の内容に書き換える。

main.dart
import 'package:arcore_flutter_plugin/arcore_flutter_plugin.dart';
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;

class HelloWorld extends StatefulWidget {
  @override
  _HelloWorldState createState() => _HelloWorldState();
}

class _HelloWorldState extends State<HelloWorld> {
  ArCoreController arCoreController;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Hello World'),
        ),
        body: ArCoreView(
          onArCoreViewCreated: _onArCoreViewCreated,
        ),
      ),
    );
  }

  void _onArCoreViewCreated(ArCoreController controller) {
    arCoreController = controller;

    _addSphere(arCoreController);
    _addCylindre(arCoreController);
    _addCube(arCoreController);
  }

  void _addSphere(ArCoreController controller) {
    final material = ArCoreMaterial(
        color: Color.fromARGB(120, 66, 134, 244), texture: "earth.jpg");
    final sphere = ArCoreSphere(
      materials: [material],
      radius: 0.1,
    );
    final node = ArCoreNode(
      shape: sphere,
      position: vector.Vector3(0, 0, -1.5),
    );
    controller.add(node);
  }

  void _addCylindre(ArCoreController controller) {
    final material = ArCoreMaterial(
      color: Colors.red,
      reflectance: 1.0,
    );
    final cylindre = ArCoreCylinder(
      materials: [material],
      radius: 0.5,
      height: 0.3,
    );
    final node = ArCoreNode(
      shape: cylindre,
      position: vector.Vector3(0.0, -0.5, -2.0),
    );
    controller.add(node);
  }

  void _addCube(ArCoreController controller) {
    final material = ArCoreMaterial(
      color: Color.fromARGB(120, 66, 134, 244),
      metallic: 1.0,
    );
    final cube = ArCoreCube(
      materials: [material],
      size: vector.Vector3(0.5, 0.5, 0.5),
    );
    final node = ArCoreNode(
      shape: cube,
      position: vector.Vector3(-0.5, 0.5, -3.5),
    );
    controller.add(node);
  }

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

AndroidManifest.xmlにエントリを追加する

/android/app/src/main/AndroidManifest.xmlを開き、以下のエントリを追加する。

AndroidManifest.xml
<!-- "AR Required" apps must declare minSdkVersion ≥ 24 -->
<uses-sdk android:minSdkVersion="24" />

<uses-permission android:name="android.permission.CAMERA" />

<!-- Indicates that app requires ARCore ("AR Required"). Ensures app is only
     visible in the Google Play Store on devices that support ARCore.
-->
<uses-feature android:name="android.hardware.camera.ar" />
AndroidManifest.xml
<application><!-- Indicates that app requires ARCore ("AR Required"). Causes Google
         Play Store to download and install ARCore when the app is installed.
    -->
    <meta-data android:name="com.google.ar.core" android:value="required" />
</application>

エントリを追加すると、AndroidManifest.xmlは以下のようになる。

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="xxx.xxxxx.flutter_arcore_test_app">

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->

    <!-- "AR Required" apps must declare minSdkVersion ≥ 24 -->
    <uses-sdk android:minSdkVersion="24" />

    <uses-permission android:name="android.permission.CAMERA" />

    <!-- Indicates that app requires ARCore ("AR Required"). Ensures app is only
         visible in the Google Play Store on devices that support ARCore.
    -->
    <uses-feature android:name="android.hardware.camera.ar" />

    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="flutter_arcore_test_app"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <!-- Indicates that app requires ARCore ("AR Required"). Causes Google
         Play Store to download and install ARCore when the app is installed.
        -->
        <meta-data android:name="com.google.ar.core" android:value="required" />
    </application>
</manifest>

ビルドの依存関係を確認

プロジェクトのbuild.gradleを確認

/android/gradle/build.gradleを開き、allprojectsにgoogleのレポジトリ指定が含まれていることを確認。

build.gradle
allprojects {
    repositories {
        google()
        jcenter()
    }
}

アプリのbuild.gradleにARCoreとSceneformの依存関係を追加

/android/app/build.gradleに以下の記述を追加する。

build.gradle
android {
    // compileSdkVersionの指定はもともとあるはず
    compileSdkVersion 28

    // 省略

    // compileOptionsの指定は追加する
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }

    // defaultConfigのminSdkVersion指定を24に書き換える
    defaultConfig {
        // 省略
        minSdkVersion 24
        // 省略
    }

    // 省略
}

// もともとあるdependenciesの指定に以下の3行を追加する
dependencies {
    // 省略
    implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.8.0'
    implementation 'com.google.ar.sceneform:core:1.8.0'
    implementation 'com.google.ar:core:1.8.0'
}

AndroidXを有効にする

/android/gradle.propertiesを開き、useAndroidXがtrueであることを確認しておく。

gradle.properties
org.gradle.jvmargs = -Xmx1536M
android.useAndroidX = true
android.enableJetifier = true

実行してみる

ARCoreに対応している実機

ARCoreは、Android 7.0(Nougat)以降であることが動作前提となっているが、これを満たしていてもすべてのAndroid端末でARCoreが動作するわけではないところに注意が必要。

以下にARCoreが動作することを確認できている端末の一覧が公開されているので、持っているAndroid端末がこのリストに載っていれば実機で動作確認ができる。
ARCore supported devices

ARCore対応のAndroid端末を持っていなかったり、そもそもiPhoneユーザだという方は、大人しくAndroidエミュレータで動作確認をすることになる。

エミュレータで実行してみる

仮想端末の用意

GoogleのAndroid端末「Pixel2」を選択し、OSは「Android 8.1 Oreo」のシステムイメージを使用した。
image.png
image.png

カメラエミュレータでの実行結果

作成したFlutterプロジェクトをエミュレータで実行するとまずはアプリが起動し、写真の撮影とビデオの保存を許可するかどうか聞いてくるのでALLOW(許可)をタップする。

アプリに3Dの部屋が映し出され、円柱と立方体のARオブジェクトが表示される。

この3Dの部屋はエミュレータでカメラ映像を使用するときにデフォルトで表示されるもののようで、Altキーを押すとカメラのアングル変更や移動もできるようになっている。(ただし操作は結構難しい)

行いたいカメラ操作 キー入力
カメラアングルを右に向ける [Alt]キー + 右方向にスワイプ
カメラアングルを左に向ける [Alt]キー + 左方向にスワイプ
カメラアングルを上に向ける [Alt]キー + 上方向にスワイプ
カメラアングルを下に向ける [Alt]キー + 下方向にスワイプ
カメラ位置を前に進める [Alt]キー + [w]キー
カメラ位置を後ろに進める [Alt]キー + [s]キー
カメラ位置を右に進める [Alt]キー + [d]キー
カメラ位置を左に進める [Alt]キー + [a]キー
カメラ位置を上げる [Alt]キー + [e]キー
カメラ位置を下げる [Alt]キー + [q]キー

まとめ

ARCoreの面白いところは、対応端末がAndroid端末だけでなくiOS端末も含まれているところだ。
FlutterにARKitとARCoreを組み合わせれば、Android向けとiOS向けのARアプリを同じコードベースで開発できるのではないかと期待していたが、ARCoreがiOS端末もカバーするのならARKitを使用しなくてもよいのかもしれない。(Apple純正のARKitに対して、ARCoreのiOS対応が見劣りしなければの話ではあるが)

[Flutter開発]FlutterとARKitを組み合わせてARアプリを作成してみる という記事でiOS向けのARサンプルアプリを実行するところまでできているので、次のステップとしてはFlutterの強みを生かして同一のコードベースからAndroid・iOSの双方のアプリをビルドできるようにしてみたいと考えている。

参考URL

arcore_flutter_pluginのパッケージ及びソース配布

pub.dev (arcore_flutter_plugin)
Github (arcore_flutter_plugin)

arcore_flutter_pluginの使用方法を紹介した公式記事

ARCore Flutter Plugin: configurations
ARCore Flutter Plugin: add object on the plane

30
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
19