
경량(Flyweight) Pattern은 많은 수의 객체를 효율적으로 관리하기 위해 공통된 데이터를 공유하도록 만들어 메모리 사용량을 최소화하는 디자인 패턴이다.
공통된 Material, Sprite, Mesh 등을 매번 인스턴스화하지 않고,
하나의 데이터를 여러 오브젝트가 공유 참조하도록 구성함으로써
메모리 낭비를 방지하는 것이 경량 패턴.
public class WaitForSeconds
{
static Dictionary<float, UnityEngine.WaitForSeconds> dic = new();
public static UnityEngine.WaitForSeconds Wait(float sec)
{
if (!dic.ContainsKey(sec))
{
UnityEngine.WaitForSeconds waitForSeconds = new(sec);
dic[sec] = waitForSeconds;
}
return dic[sec];
}
}
반복 코루틴에서 WaitForSeconds를 매번 new로 새로 생성하지않고 딕셔너리에 한 번만 만들어주고 재사용함으로써 메모리 사용을 줄임.
| 항목 | 경량(Flyweight) Pattern | ScriptableObject |
|---|---|---|
| 목적 | 메모리 사용 최소화, 성능 최적화 | 메모리 사용 최소화, 데이터 공유 |
| 데이터 관리 | 공통 데이터를 캐싱하여 재사용 | 공통 데이터를 에셋으로 저장하여 재사용 |
| 재사용 방식 | 코드 내에서 Dictionary 등으로 관리 | 여러 오브젝트가 동일한 ScriptableObject 참조 |
| 인스턴스 수 | 중복 객체 생성을 방지 | 중복 데이터 생성을 방지 |
| 설계 방식 | 런타임 중 객체를 캐싱하고 참조 | 에디터에서 데이터 생성, 런타임에 참조 |
유니티에서 지원하는 기능인 ScriptableObject로 간단하게 경량패턴과 비슷한 효과를 낼 수 있다.
using UnityEngine;
[CreateAssetMenu(fileName = "NewItemData", menuName = "Flyweight/ItemData")]
public class ItemData : ScriptableObject
{
public string itemName;
public string description;
public Sprite icon;
public int cost;
}
using UnityEngine;
using UnityEngine.UI;
public class ItemShop : MonoBehaviour
{
public ItemData itemData; // ScriptableObject 참조
[SerializeField] private Text nameText;
[SerializeField] private Text costText;
[SerializeField] private Image iconImage;
private void Start()
{
// itemData의 데이터 적용
nameText.text = itemData.itemName;
costText.text = itemData.cost.ToString();
iconImage.sprite = itemData.icon;
}
}
런타임 중에 값 변경 시 저장되지 않음
-> 게임 도중에 값을 변경하면 그 값은 런타임 한정으로 변경된다 저장을 하고 싶다면 다른 파일이나 데이터베이스를 사용해야한다.
직렬화 가능한 필드만 저장된다
-> Scriptable Object 안에 저장되는 데이터는 Unity가 직렬화 가능한 것만 가능.
런타임 중에 생성을 해도 에셋 파일로 저장되지않음.
많은 수의 객체가 동일한 데이터를 공유할 수 있다면
Flyweight 패턴을 통해 메모리를 크게 아낄 수 있다.