Membawa Objek 3D ke Dunia Nyata: Dasar-dasar Unity AR

I Nyoman Donostia 991 kata
Membawa Objek 3D ke Dunia Nyata: Dasar-dasar Unity AR

Pendahuluan: AR Foundation sebagai Pondasi

Saya pertama kali terjun ke Unity AR saat project klien minta visualisasi produk furniture di ruang nyata secara real-time. Pilihan awal saya: ARCore langsung (Java/Kotlin) atau Unity dengan AR Foundation? Tapi realita: AR Foundation memberi abstraksi yang sama untuk Android (ARCore) dan iOS (ARKit), jadi satu codebase, dua platform. Worth it.

Artikel ini adalah ringkasan setup dan fitur inti yang saya pakai dalam produksi.

1. Setup Environment

Unity Hub dan Editor

  1. Install Unity Hub dari unity.com
  2. Install Unity Editor 2022.3 LTS atau lebih baru (LTS = Long Term Support, stabil untuk production)
  3. Saat install, pilih modules:
    • Android Build Support (untuk ARCore)
    • iOS Build Support (untuk ARKit, jika develop di Mac)

Buat Project dan Install Packages

Buka Unity → New Project → 3D (URP atau Built-in).

Window → Package Manager (atau Window > Package Manager).

Install paket berikut (klik + → Add package from name):

com.unity.xr.arcore
com.unity.xr.arkit
com.unity.xr.arfoundation
com.unity.xr.interaction.toolkit

Atau via Packages/manifest.json:

{
  "dependencies": {
    "com.unity.xr.arcore": "4.2.7",
    "com.unity.xr.arkit": "4.2.7",
    "com.unity.xr.arfoundation": "4.2.7",
    "com.unity.xr.interaction.toolkit": "2.3.2"
  }
}

Enable XR Plugin di Build Settings

File → Build Settings → Platform (Android): Switch Platform → Player Settings:

  • Resolution and Presentation: Default Orientation = Landscape
  • XR Plug-in Management: ✅ ARCore (Android) atau ARKit (iOS)

2. Plane Detection: Mendeteksi Permukaan

Inilah pondasi AR — aplikasi harus tahu di mana "lantai" atau permukaan datar di ruangan.

Buat AR Session dan Origin

Di scene baru (atau scene existing), buat GameObject sebagai wadah AR:

AR Session (Component: ARSession)
│
└── AR Session Origin (Component: ARSessionOrigin, XROrigin)
    ├── AR Camera (Camera dengan TrackedPoseDriver)
    ├── AR Plane Manager (Component)
    ├── AR Raycast Manager (Component)
    └── AR Placement Indicator

Konfigurasi AR Plane Manager

using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class PlaneDetectionManager : MonoBehaviour
{
    [SerializeField] private ARPlaneManager planeManager;
    
    void Start()
    {
        planeManager.planesChanged += OnPlanesChanged;
    }
    
    void OnPlanesChanged(ARPlanesChangedEventArgs args)
    {
        foreach (var plane in args.added)
        {
            Debug.Log($"Plane detected: {plane classifications}");
            // Optional: Ubah visual plane (warnaPrefab berbeda berdasarkan tipe)
            if (plane.classifications == PlaneClassifications.Floor)
            {
                plane.gameObject.GetComponent<Renderer>().material.color = Color.green;
            }
        }
    }
}

PlaneClassifications tersedia: Floor, Wall, Ceiling, Table. Filter via planeManager.requestedPlaneClassifications.

3. Reuse AR Default Plane (Visual Indikator)

Untuk visual feedback plane yang terdeteksi, buat prefab:

  1. Buat material dengan warna semi-transparan (Color: (1, 0, 0, 0.3), shader: Unlit)
  2. Buat prefab dari AR Default Plane (klik kanan di Hierarchy → XR → AR Default Plane)
  3. Tambahkan material ke mesh
  4. Drag prefab ke AR Plane Manager > Plane Prefab di inspector

4. Raycasting: Tap-to-Place

Menggunakan ARRaycastManager untuk mendapatkan titik dari screen ke world.

using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class TapToPlace : MonoBehaviour
{
    [SerializeField] private ARRaycastManager raycastManager;
    [SerializeField] private GameObject objectPrefab;
    
    private static List<ARRaycastHit> hits = new List<ARRaycastHit>();
    
    void Update()
    {
        if (Input.touchCount == 0) return;
        
        Touch touch = Input.GetTouch(0);
        if (touch.phase != TouchPhase.Began) return;
        
        if (raycastManager.Raycast(touch.position, hits, TrackableTypes.PlaneWithinPolygon))
        {
            Pose hitPose = hits[0].pose;
            Instantiate(objectPrefab, hitPose.position, hitPose.rotation);
        }
    }
}

TrackableTypes.PlaneWithinPolygon berarti raycast hanya mengenai polygon plane yang terdeteksi (lebih akurat dari hanya bounding plane).

5. Import Objek 3D

Drag file .fbx, .obj, atau .gltf ke folder Assets/Models. Unity akan otomatis generate Material dan Texture.

Tips file size AR mobile:

  • Maksimum 30K triangles untuk objek tunggal
  • Texture: 1024x1024 max untuk mobile, lebih rendah jika banyak objek
  • Format: GLTF lebih ringan, FBX lebih luas support
  • Compression: ASTC (Texture Importer > Format: ASTC 6x6)

6. Lighting di AR Scene

Gunakan environment lighting yang real-world (HDR environment): AR Foundation dapat mengambil data lighting dari kamera real.

using UnityEngine.XR.ARFoundation;

public class ARLightEstimation : MonoBehaviour
{
    [SerializeField] private Light directionalLight;
    [SerializeField] private ARLightManager lightManager;
    
    void OnEnable() {
        lightManager.brightnessChanged += UpdateBrightness;
        lightManager.colorTemperatureChanged += UpdateColor;
    }
    
    void UpdateBrightness(float? brightness) {
        if (brightness.HasValue) directionalLight.intensity = brightness.Value;
    }
    
    void UpdateColor(float? colorTemperature) {
        if (colorTemperature.HasValue)
            directionalLight.color = Mathf.CorrelatedColorTemperatureToColor(colorTemperature.Value);
    }
}

7. Gesture Interaction: Rotate dan Scale

Menggunakan AR Interaction Toolkit:

  1. Tambah XR Origin ke hierarchy
  2. Buat GameObject → add components XR Grab Interactable
  3. Atur Movement Type = Velocity Tracking agar rotation dengan tangan

Untuk pinch-to-scale:

private float initialDistance;
private Vector3 initialScale;

void Update()
{
    if (Input.touchCount == 2)
    {
        Touch touch1 = Input.GetTouch(0);
        Touch touch2 = Input.GetTouch(1);
        
        if (touch1.phase == TouchPhase.Began || touch2.phase == TouchPhase.Began)
        {
            initialDistance = Vector2.Distance(touch1.position, touch2.position);
            initialScale = transform.localScale;
        }
        else if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved)
        {
            float currentDistance = Vector2.Distance(touch1.position, touch2.position);
            float scaleFactor = currentDistance / initialDistance;
            transform.localScale = initialScale * scaleFactor;
        }
    }
}

8. Build dan Deploy ke Android

File → Build Settings → Android:

  • Minimum API Level: 24 (Android 7.0) — minimum ARCore
  • Target API Level: 33+
  • Player Settings:
    • Other Settings → Color Space: Linear
    • Other Settings → Auto Graphics API: ✅
    • XR Plug-in Management → ARCore: ✅

Build → Build APK → install ke device → grant camera permission.

9. Troubleshooting Umum

Plane tidak terdeteksi?

  • Pencahayaan ruangan terlalu redup → ARCore butuh texture di surface
  • Gerakan device terlalu cepat → ajak user "scanning" dengan motion circular

Objek 3D melayang atau tidak terlihat?

  • Cek Scale — mungkin terlalu kecil atau besar
  • Cek Position.y — harus 0 untuk attach ke plane
  • Cek Camera Far clip plane — mungkin terlalu dekat

Frame rate drop di device low-end?

  • Kurangi shadow: gunakan baked atau tanpa shadow
  • Disable MSAA di Player Settings
  • Batch static objects dengan Static flag

Kesimpulan

AR Foundation menurunkan barrier entry AR development secara signifikan. Dengan ~200 baris code C#, saya bisa create aplikasi tap-to-place furniture visualizer yang berjalan dengan mulus di Android dan iOS. Untuk pengalaman penjualan retail klien saya, ini alat yang powerful.

Langkah berikutnya untuk eksplorasi: AR Object Tracking (track objek fisik dengan marker), AR Image Tracking (scan QR/gambar memunculkan model 3D), dan AR Mesh Manager (scan mesh 3D ruangan). Semua itu tersedia di AR Foundation.

I Nyoman Donostia

I Nyoman Donostia

Fullstack Developer - Bali, Indonesia

Artikel Terkait