
Dalam artikel sebelumnya, saya sudah menjelaskan apa itu ARCore dan bagaimana hal itu membantu pengembang untuk membuat aplikasi augmented reality yang menakjubkan tanpa perlu memahami matematika dan OpenGL.
Jika Anda belum membacanya, saya sangat merekomendasikan melakukan ini sebelum pindah ke artikel ini dan mulai mengembangkan aplikasi ARCore.
Memulai
Untuk mulai mengembangkan aplikasi ARCore, Anda harus terlebih dahulu menambahkan dukungan ARCore ke proyek Anda. Ini sangat sederhana, karena kita akan menggunakan Android Studio dan Sceneform SDK. Ada dua operasi utama yang dilakukan secara otomatis oleh Sceneform:
- Periksa ARCore.
- Minta izin untuk menggunakan kamera.
Anda tidak perlu khawatir tentang dua langkah ini saat membuat aplikasi ARCore menggunakan Sceneform SDK. Anda hanya perlu menambahkan Sceneform SDK ke proyek Anda.
Buat proyek Android Studio baru dengan Kegiatan kosong.
Tambahkan dependensi berikut ke file build.gradle
di tingkat proyek:
dependencies { classpath 'com.google.ar.sceneform:plugin:1.5.0' }
Dan tambahkan dependensi ini ke file build.gradle
di tingkat aplikasi:
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.5.0"
Sekarang sinkronkan proyek dengan file Gradle dan tunggu sampai build selesai. Dengan demikian, Sceneform SDK dan plugin Sceneform untuk Android Studio akan ditambahkan ke proyek. Ini akan memungkinkan Anda untuk melihat .sfb
, yang merupakan model 3D yang akan dirender di kamera Anda, serta membantu Anda mengimpor, melihat, dan membuat sumber daya 3D.
Membuat aplikasi ARCore pertama Anda
Sekarang setelah persiapan Android Studio selesai dan Sceneform SDK diinstal, kita dapat mulai membuat aplikasi ARCore pertama kami.
Pertama, kita perlu menambahkan fragmen Sceneform ke tata letak kita. Ini adalah adegan yang disebut di mana semua model 3D kami akan ditempatkan. Fragmen akan mengatur inisialisasi kamera dan memproses izin sendiri.
Buka file tata letak utama Anda. Dalam kasus saya, ini adalah file activity_main.xml
. Dan tambahkan fragmen Sceneform di sana:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <fragment android:name="com.google.ar.sceneform.ux.ArFragment" android:id="@+id/ux_fragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
Saya mengatur lebar dan tinggi match_parent
sehingga adegan layar penuh. Anda dapat memilih ukuran sesuai dengan kebutuhan Anda.
Pemeriksaan kompatibilitas
Ini semua yang perlu Anda lakukan dalam file tata letak. Sekarang kita beralih ke Activity, dalam kasus saya itu adalah MainActivity
. Tambahkan metode ke Aktivitas:
public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { Log.e(TAG, "Sceneform requires Android N or later"); Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show(); activity.finish(); return false; } String openGlVersionString = ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)) .getDeviceConfigurationInfo() .getGlEsVersion(); if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) { Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later"); Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG) .show(); activity.finish(); return false; } return true; }
Metode ini memeriksa apakah perangkat Anda mendukung Sceneform SDK atau tidak. SDK membutuhkan Android API level 27 atau lebih tinggi dan OpenGL ES versi 3.0 atau lebih tinggi. Jika perangkat tidak mendukung kedua parameter ini, adegan tidak akan dimuat, dan aplikasi Anda akan menampilkan layar kosong.
Namun, Anda masih dapat mengimplementasikan semua fungsi lain dari aplikasi Anda yang tidak memerlukan Sceneform SDK.
Setelah memeriksa kompatibilitas, kami dapat membuat model 3D kami dan melampirkannya ke tempat kejadian.
Menambah aset
Sekarang Anda perlu menambahkan model 3D ke proyek yang akan ditampilkan di layar Anda. Anda dapat membuat model ini sendiri jika Anda terbiasa dengan proses pembuatannya. Atau Anda bisa pergi ke Poly .
Di sana Anda akan menemukan repositori besar sumber daya 3D untuk dipilih. Selain itu, mereka gratis untuk diunduh.

Di Android Studio, buka folder aplikasi Anda di panel kiri. Anda memerlukan folder sampledata . Folder ini akan berisi semua model 3D Anda. Di dalam folder ini, buat folder dengan nama model Anda.
Di arsip yang Anda unduh dari Poly, kemungkinan besar Anda akan menemukan 3 file:
- file
.mtl
- File
.obj
- file
.png
Yang paling penting dari ketiga file ini adalah file .obj
. Ini adalah model Anda. Masukkan semua 3 file dalam sampledata -> "folder model Anda" .

Sekarang klik kanan pada file .obj
. Opsi pertama adalah Impor Aset Sceneform . Klik di atasnya, jangan mengubah pengaturan default, cukup klik Selesai di jendela berikutnya. Setelah itu, sinkronkan proyek dengan file Gradle.
Impor sumber daya 3D yang akan digunakan dalam proyek Anda selesai. Selanjutnya, mari kita gunakan model 3D dalam kode kita dan memasukkannya ke dalam adegan.
Pembuatan model
Tambahkan kode berikut ke Aktivitas Anda, dan saya akan menjelaskannya baris demi baris:
private static final String TAG = MainActivity.class.getSimpleName(); private static final double MIN_OPENGL_VERSION = 3.0; ArFragment arFragment; ModelRenderable lampPostRenderable; @Override @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"}) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!checkIsSupportedDeviceOrFinish(this)) { return; } setContentView(R.layout.activity_main); arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment); ModelRenderable.builder() .setSource(this, Uri.parse("LampPost.sfb")) .build() .thenAccept(renderable -> lampPostRenderable = renderable) .exceptionally(throwable -> { Toast toast = Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return null; }); }
Pertama kita menemukan arFragment
, yang sebelumnya kita tambahkan ke tata letak. Fragmen ini bertanggung jawab untuk penyimpanan dan pengoperasian tempat kejadian. Anda bisa membayangkannya sebagai wadah untuk adegan kami.
Selanjutnya, kami menggunakan kelas ModelRenderable
untuk membangun model kami. Menggunakan metode setSource
kami memuat model kami dari file .sfb
yang dihasilkan ketika sumber daya diimpor. Metode thenAccept
mendapatkan model setelah dibuat, dan kami mengatur model yang dimuat ke lampPostRenderable
variabel kami.
Untuk penanganan kesalahan, kami memiliki metode yang exceptionally
, yang disebut jika pengecualian terjadi.
Semua ini terjadi secara tidak sinkron, sehingga Anda tidak perlu khawatir tentang multithreading.
Sekarang setelah model dimuat dan disimpan dalam variabel lampPostRenderable
, kami akan menambahkannya ke adegan kami.
Menambahkan Model ke Adegan
Adegan kami berada di arFragment
dan akan menerima acara sentuhan pengguna. Oleh karena itu, kita perlu menginstal pendengar onTap
untuk fragmen kita untuk memproses sentuhan dan menempatkan objek di tempat yang diperlukan. Tambahkan kode berikut ke metode onCreate
:
arFragment.setOnTapArPlaneListener( (HitResult hitresult, Plane plane, MotionEvent motionevent) -> { if (lampPostRenderable == null){ return; } Anchor anchor = hitresult.createAnchor(); AnchorNode anchorNode = new AnchorNode(anchor); anchorNode.setParent(arFragment.getArSceneView().getScene()); TransformableNode lamp = new TransformableNode(arFragment.getTransformationSystem()); lamp.setParent(anchorNode); lamp.setRenderable(lampPostRenderable); lamp.select(); } );
Kami menetapkan pendengar onTapArPlaneListener
untuk fragmen AR kami. Sintaksis berikut digunakan untuk ekspresi lambda. Jika Anda tidak terbiasa dengan itu, maka lihat panduan kecil ini tentang topik ini.
Pertama, kita membuat jangkar dari HitResult
menggunakan hitresult.createAnchor()
dan menyimpannya di objek Anchor
.
Lalu kita buat simpul dari jangkar ini. Ini akan disebut AnchorNode
dan akan dilampirkan ke tempat kejadian menggunakan metode setParent
.
Selanjutnya, kita membuat TransformableNode
, yang akan menjadi model kita, dan ikat ke node kita. TransformableNode
masih belum memiliki informasi tentang objek yang harus ditampilkan. Kami akan meneruskan objek ini dengan menggunakan metode setRenderable
, yang mengambil objek bertipe ModelRenderable sebagai parameter (ingat, kami mendapat objek seperti itu dan menamakannya lampPostRenderable
?). Dan akhirnya, kita memanggil metode lamp.select()
;
Ooh! Terlalu banyak terminologi. Jangan khawatir, saya akan menjelaskan semuanya sekarang:
Adegan : ini adalah tempat di mana semua objek 3D Anda akan ditampilkan. Adegan ini terletak di fragmen AR yang kami tambahkan ke tata letak.
HitResult : ini adalah garis imajiner (atau sinar) yang datang dari tak terbatas, yang memberikan titik persimpangan dirinya dengan objek dari dunia nyata.
Jangkar : Ini adalah lokasi dan orientasi tetap di dunia nyata. Ini dapat dipahami sebagai koordinat (x, y, z) dalam ruang tiga dimensi. Pose adalah posisi dan orientasi suatu benda di atas panggung. Ini digunakan untuk mengubah ruang koordinat lokal dari suatu objek menjadi ruang koordinat nyata.
Anchor node : Ini adalah node yang secara otomatis memposisikan dirinya di dunia nyata. Ini adalah simpul pertama yang dipasang ketika sebuah pesawat terdeteksi.
TransformableNode : Ini adalah simpul yang dapat berinteraksi dengan Anda. Itu bisa dipindahkan, diskalakan, diputar, dan sebagainya. Dalam contoh ini, kita dapat mengatur skala objek kita dan memutarnya. Karenanya nama Transformable.
Tidak ada ilmu roket. Ini sebenarnya relatif sederhana. Seluruh adegan dapat dilihat dalam bentuk grafik di mana orang tua adalah adegan, dan anak-anak adalah jangkar node, yang kemudian bercabang ke berbagai node dan objek lain yang akan ditampilkan di layar.
Akibatnya, Aktivitas Anda akan terlihat seperti ini:
package com.ayusch.arcorefirst; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.net.Uri; import android.os.Build; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.widget.Toast; import com.google.ar.core.Anchor; import com.google.ar.core.HitResult; import com.google.ar.core.Plane; import com.google.ar.sceneform.AnchorNode; import com.google.ar.sceneform.rendering.ModelRenderable; import com.google.ar.sceneform.ux.ArFragment; import com.google.ar.sceneform.ux.TransformableNode; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private static final double MIN_OPENGL_VERSION = 3.0; ArFragment arFragment; ModelRenderable lampPostRenderable; @Override @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"}) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!checkIsSupportedDeviceOrFinish(this)) { return; } setContentView(R.layout.activity_main); arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment); ModelRenderable.builder() .setSource(this, Uri.parse("LampPost.sfb")) .build() .thenAccept(renderable -> lampPostRenderable = renderable) .exceptionally(throwable -> { Toast toast = Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return null; }); arFragment.setOnTapArPlaneListener( (HitResult hitresult, Plane plane, MotionEvent motionevent) -> { if (lampPostRenderable == null){ return; } Anchor anchor = hitresult.createAnchor(); AnchorNode anchorNode = new AnchorNode(anchor); anchorNode.setParent(arFragment.getArSceneView().getScene()); TransformableNode lamp = new TransformableNode(arFragment.getTransformationSystem()); lamp.setParent(anchorNode); lamp.setRenderable(lampPostRenderable); lamp.select(); } ); } public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { Log.e(TAG, "Sceneform requires Android N or later"); Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show(); activity.finish(); return false; } String openGlVersionString = ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)) .getDeviceConfigurationInfo() .getGlEsVersion(); if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) { Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later"); Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG) .show(); activity.finish(); return false; } return true; } }
Selamat! Anda baru saja menyelesaikan pembuatan aplikasi ARCore pertama Anda. Mulai menambahkan objek ke dalamnya dan Anda akan melihat bagaimana mereka mulai hidup di dunia nyata.
Ini adalah pandangan pertama Anda tentang cara membuat aplikasi ARCore sederhana dari awal di Android Studio. Dalam pelajaran berikutnya, saya akan mempelajari ARCore lebih dalam dan menambahkan lebih banyak fungsi ke aplikasi.