using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; using ZXing; public class ImageTracker : MonoBehaviour { ARCameraManager cameraManager; [SerializeField] List listName; [SerializeField] List listAnimal; [SerializeField] float spawnScale = 0.3f; [SerializeField] float spawnDistance = 1.5f; Dictionary dictPrefab = new(); Dictionary dictSpawn = new(); // 현재 소환된 QR 이름 추적 string currentName = ""; IBarcodeReader reader = new BarcodeReader(); void Awake() { cameraManager = FindFirstObjectByType(); for (int i = 0; i < listName.Count; i++) dictPrefab[listName[i]] = listAnimal[i]; } void OnEnable() => StartCoroutine(ScanQR()); void OnDisable() => StopAllCoroutines(); IEnumerator ScanQR() { while (true) { yield return new WaitForSeconds(0.5f); if (!cameraManager.TryAcquireLatestCpuImage(out var cpuImage)) continue; using (cpuImage) { var tex = new Texture2D(cpuImage.width, cpuImage.height, TextureFormat.RGBA32, false); var conversionParams = new XRCpuImage.ConversionParams(cpuImage, TextureFormat.RGBA32); var buffer = tex.GetRawTextureData(); cpuImage.Convert(conversionParams, buffer); tex.Apply(); var result = reader.Decode(tex.GetPixels32(), tex.width, tex.height); Destroy(tex); if (result == null) continue; if (!dictPrefab.ContainsKey(result.Text)) continue; string detected = result.Text; // 같은 QR이면 무시 if (detected == currentName) continue; SpawnCharacter(detected); } } } void SpawnCharacter(string name) { // 이전 동물 전부 Destroy foreach (var key in new List(dictSpawn.Keys)) DestroyCharacter(key); Vector3 spawnPos = GetSpawnPosition(); var go = Instantiate(dictPrefab[name], spawnPos, Quaternion.identity); go.transform.localScale = Vector3.one * spawnScale; // 카메라를 바라보도록 회전 Vector3 lookDir = Camera.main.transform.position - spawnPos; lookDir.y = 0; go.transform.rotation = Quaternion.LookRotation(lookDir); dictSpawn[name] = go; currentName = name; } void DestroyCharacter(string name) { if (!dictSpawn.ContainsKey(name)) return; Destroy(dictSpawn[name]); dictSpawn.Remove(name); } Vector3 GetSpawnPosition() { Transform cam = Camera.main.transform; return cam.position + cam.forward * spawnDistance; } }