#nullable enable using Cysharp.Threading.Tasks; using System; using System.Collections.Generic; using UnityEngine; namespace UVC.Util { /// /// Unity 리소스를 관리하고 비동기적으로 로드하는 기능을 제공합니다. /// /// 클래스는 로드된 리소스의 내부 캐시를 유지하여 /// 후속 액세스를 최적화합니다. 리소스는 키별로 비동기적으로 로드하거나 키 목록을 사용하여 대량으로 로드할 수 있습니다. /// public static class ResourceManager { private static Dictionary _resources = new(); /// /// 문자열 키로 매핑된 리소스가 포함된 읽기 전용 사전을 가져옵니다. /// public static IReadOnlyDictionary get => _resources; /// /// 지정된 경로에서 지정된 유형의 리소스를 비동기적으로 로드합니다. /// /// 이 메서드는 Unity의 를 사용하여 /// 리소스를 비동기적으로 로드합니다. 지정된 리소스가 지정된 경로에 있는지 확인하여 /// 을 반환하지 않도록 합니다. /// 로드할 리소스의 유형입니다. 에서 파생되어야 합니다. /// 리소스 폴더 내 리소스 경로입니다. 이 경로는 리소스 폴더를 기준으로 하며 /// 파일 확장자를 포함하지 않아야 합니다. /// 비동기 작업을 나타내는 작업입니다. 결과에는 로드된 리소스 유형이 포함됩니다. /// (리소스가 발견되면); 그렇지 않으면 . public static async UniTask LoadOnlyAsync(string path) where T : UnityEngine.Object { var request = Resources.LoadAsync(path); await request; return request.asset as T; } /// /// Unity 리소스 시스템에서 지정된 유형의 리소스를 비동기적으로 로드합니다. /// /// 리소스가 이미 캐시된 경우, 새로운 로드 작업을 수행하지 않고 즉시 반환됩니다. /// 그렇지 않은 경우, 리소스는 비동기적으로 로드되어 나중에 사용할 수 있도록 캐시에 추가됩니다. /// /// 로드할 리소스의 유형입니다. 의 하위 클래스여야 합니다. /// Unity 리소스 시스템에서 리소스를 찾는 데 사용되는 키 또는 경로입니다. /// 로드된 리소스와 함께 호출할 선택적 콜백입니다. 콜백은 로드된 리소스를 /// 또는 (리소스를 로드할 수 없는 경우) 유형으로 받습니다. /// 비동기 작업을 나타내는 작업입니다. 작업 결과는 /// 또는 (리소스를 로드할 수 없는 경우) 유형으로 로드된 리소스입니다. public static async UniTask LoadAsync(string key, Action? callback = null) where T : UnityEngine.Object { T? t = null; if (_resources.TryGetValue(key, out var resource)) { t = resource as T; callback?.Invoke(t); return t; } var operation = Resources.LoadAsync(key); await operation; _resources.TryAdd(operation.asset.name, operation.asset); t = operation.asset as T; callback?.Invoke(t); return t; } /// /// 지정된 프리팹 경로 목록에서 모든 에셋을 비동기적으로 로드합니다. /// /// 이 메서드는 프리팹 경로 목록을 순차적으로 처리하여 각 에셋을 /// 비동기적으로 로드합니다. 콜백이 제공된 경우, 로드 작업의 진행 상황을 추적하는 데 사용할 수 있습니다. /// /// 로드할 에셋의 유형입니다. 에서 파생되어야 합니다. /// 로드할 프리팹 경로 목록입니다. /// 각 에셋이 로드된 후 호출되는 선택적 콜백입니다. 이 콜백은 로드된 에셋의 경로, /// 현재 로드된 에셋의 개수, 그리고 로드할 에셋의 총 개수를 받습니다. public static async void LoadAllAsync(List prefabPath, Action? callback = null) where T : UnityEngine.Object { int loadCount = 0; int totalCount = prefabPath.Count; // preloadKeys 배열의 주소들을 로드 foreach (var key in prefabPath) { await LoadAsync(key); loadCount++; callback?.Invoke(key, loadCount, totalCount); } } } }