현재 필자는 개발 중인 게임에서 백단과 통신 하는 API를 개발 중이다.
문제는 현재 개발중인 프로젝트에선, S3 Cloud 저장소에 있는 이미지를 로드해야하는데.
처음엔 Local Memory에 저장하는 형태로 구현했다가 차후 1000 장, 1만 장 이상일 땐 어떻게 할 것인가에 대한 고민으로 인해 NHN에서 제공하는 캐시 스토리지를 도입하게 되었다.
public class HttpBestImageLoad : IImageDownload
{
private Action<errorCode> errorCallback;
public HttpBestImageLoad(Action<errorCode> errorCallback)
{
this.errorCallback = errorCallback;
}
private Dictionary<string, Texture2D> imageDatas = new();
public void SaveImageData(string url, Action<Texture2D> successCallback)
{
BackEnd.WebDownLoad(url, success =>
{
imageDatas.Add(url,success);
successCallback?.Invoke(null);
},errorCallback);
}
public void OverWriteTexture(string id, RawImage image)
{
Texture2D texture2D;
if (imageDatas.TryGetValue(id, out texture2D))
{
image.texture = texture2D;
return;
}
SaveImageData(id, (success)=> OverWriteTexture(id, image));
}
}
기존 소스코드는 위와 같다.
어디선가 OverWriteTexture를 호출하면 해당 해시 메모리에 저장되어 있으면 그대로 Texture를 입혀주고 아니라면 Save Image를 통해 저장 후, 다시 한번 OverWriteTexture를 호출하여 제귀하는 형태라 볼 수 있다.
일단 해당 코드의 문제점은 최초로 이미지를 로드할 때 깜박이는 현상 ( 네트워크 지연으로 인해 )이 있었고
무엇보다 매 번 이미지를 Memory에 올리기 위해서 Web과 통신해야하는 통신 비용 부담도 있었고
아까 말하였 듯 1천 건, 1만 건의 이미지가 Memory에 쌓였을 때 일어날 수 있는 문제점을 생각해봐야 하였고
마침 NHN에서 위와 비슷한 고민으로 에셋을 하나 배포 해놓았다.
원리는 위와 같이 캐시에 저장되어 있으면 클라이언트에게 바로 전송하고 없으면 서버에 요청을 보내는 형태다.
using System;
using MoreMountains.TopDownEngine.Core.BackEnd;
using UnityEngine;
using UnityEngine.UI;
public class NHNImageDownload : IImageDownload
{
private Action<errorCode> errorCallback;
public NHNImageDownload(Action<errorCode> errorCallback)
{
this.errorCallback = errorCallback;
}
public void SaveImageData(string url, Action<Texture2D> successCallback)
{
BackEnd.WebDownLoad(url, success =>
{
successCallback?.Invoke(success);
},errorCallback);
}
public void OverWriteTexture(string id, RawImage image)
{
SaveImageData(id, success =>
{
image.texture = success;
});
}
}
private static void _MakeNHNApiDownloadCall(string url, Action<Texture2D> successCallback,
Action<errorCode> errorCallback)
{
GpmCacheStorage.RequestTexture(url, (CachedTexture cachedTexture) =>
{
if (cachedTexture != null)
{
successCallback?.Invoke(cachedTexture.texture);
}
else
{
errorCallback?.Invoke(new errorCode("500","error not Texture Load"));
}
});
}
하여 기존 Download Call을 NHN 에서 제공하는 GpmCasheStorage 코드로 변경하였고
잘 적용된 모습을 볼 수 있다.
using UnityEngine.UI;
using Gpm.CacheStorage;
using MoreMountains.TopDownEngine.Core.BackEnd;
public partial class DataManager
{
private IImageDownload imageDownload = new NHNImageDownload(ErrorAPI);
private void InitCacheStorage()
{
int maxSize = 5 * 1024 * 1024; // 5 MB
int maxCount = 10000;
double reRequestTime = 7 * 24 * 60 * 60; // 7 Days
CacheRequestType defaultRequestType = CacheRequestType.FIRSTPLAY;
double unusedPeriodTime = 24 * 60 * 60; // 1 Day
double removeCycle = 1; // 1 Seconds
GpmCacheStorage.Initialize(maxCount, maxSize, reRequestTime, defaultRequestType, unusedPeriodTime, removeCycle);
}
public void OverWriteTexture(string id, RawImage image)
{
imageDownload.OverWriteTexture(id,image);
}
}
우선 캐시 스토리지를 사용하기 위해선 위와 같이 Init 설정을 해주어야 하는데
사이즈는 5MB로 설정해두고, 최대 1만건의 데이터를 저장할 수 있게끔 설정하였다.
이후 requestTime 은 7일 마다 검증한다고 보면 되고
저 Enum Type은
해당 검증 전략을 읽어보면 된다.
'Unity > Unity 프로그래밍' 카테고리의 다른 글
[ 최적화 ] 중간 진행 (1) | 2024.07.12 |
---|---|
[최적화]배치 수 줄이기 (0) | 2024.07.12 |
01. (대화창) 다이얼로그 및 분기점 구현 (4) | 2020.12.31 |