using System.Collections; using UnityEngine; using UnityEngine.Networking; /// /// HOY Gallery V2 — ArtworkFrame /// Handles image or video display on each frame quad. /// Scale and position are applied by GalleryManager from Spatial coordinates. /// The frame itself is always a simple quad at localScale=1; the parent /// GameObject carries the Spatial scale. /// public class ArtworkFrame : MonoBehaviour { [Header("References (set on prefab)")] public Renderer artworkRenderer; public Transform labelAnchor; public GameObject labelPrefab; ArtworkData _data; public void Initialise(ArtworkData data) { _data = data; if (data.type == "video") StartCoroutine(LoadVideo()); else StartCoroutine(LoadImage()); SpawnLabel(); } // ── Image ───────────────────────────────────────────────────────────────── IEnumerator LoadImage() { string url = GetStreamingURL(_data.file); using var req = UnityWebRequestTexture.GetTexture(url); yield return req.SendWebRequest(); if (req.result != UnityWebRequest.Result.Success) { Debug.LogWarning($"[Frame] Image failed: {_data.file} — {req.error}"); SetPlaceholder(); yield break; } var tex = DownloadHandlerTexture.GetContent(req); tex.wrapMode = TextureWrapMode.Clamp; if (artworkRenderer != null) { artworkRenderer.material = new Material(artworkRenderer.sharedMaterial); artworkRenderer.material.mainTexture = tex; } } // ── Video ───────────────────────────────────────────────────────────────── IEnumerator LoadVideo() { string url = GetStreamingURL(_data.file); #if UNITY_WEBGL && !UNITY_EDITOR if (artworkRenderer != null) { var bridge = gameObject.AddComponent(); bridge.Initialise(url, artworkRenderer, Mathf.Abs(_data.spatialId.GetHashCode() % 10000)); } #else yield return StartCoroutine(LoadVideoEditor(url)); #endif yield return null; } #if !UNITY_WEBGL || UNITY_EDITOR IEnumerator LoadVideoEditor(string url) { var vp = gameObject.AddComponent(); vp.url = url; vp.isLooping = true; vp.playOnAwake = false; vp.renderMode = UnityEngine.Video.VideoRenderMode.MaterialOverride; vp.targetMaterialRenderer = artworkRenderer; vp.targetMaterialProperty = "_MainTex"; vp.audioOutputMode = UnityEngine.Video.VideoAudioOutputMode.None; vp.Prepare(); float t = 8f; while (!vp.isPrepared && t > 0) { t -= Time.deltaTime; yield return null; } if (vp.isPrepared) vp.Play(); else Debug.LogWarning($"[Frame] VideoPlayer timeout: {_data.file}"); } #endif void SetPlaceholder() { if (artworkRenderer == null) return; var m = new Material(artworkRenderer.sharedMaterial); m.color = new Color(0.12f, 0.12f, 0.15f); artworkRenderer.material = m; } void SpawnLabel() { if (labelPrefab == null || labelAnchor == null) return; var label = Instantiate(labelPrefab, labelAnchor.position, labelAnchor.rotation, labelAnchor); label.GetComponent()?.SetText(_data.title, _data.artist); } static string GetStreamingURL(string rel) { #if UNITY_WEBGL && !UNITY_EDITOR return $"{Application.streamingAssetsPath}/{rel}"; #else return $"file://{Application.streamingAssetsPath}/{rel}"; #endif } }