내일배움캠프 33일차 TIL
ScriptableObject는 Unity에서 데이터 중심 설계(Data-Driven Design) 를 할 수 있게 해주는 아주 유용한 기능이다.
특히 게임 밸런스 데이터, 아이템 정보, 스킬 설정, 몬스터 스탯 등을 따로 관리할 때 정말 많이 사용할 수 있다.
📌 ScriptableObject란?
ScriptableObject는 Unity에서 MonoBehaviour와는 다르게 씬에 존재하지 않고, 에셋 파일로 저장할 수 있는 데이터 컨테이너이다. 클래스지만 GameObject에 붙이지 않고 씬의 오브젝트와는 독립적으로 존재한다.
인스펙터에서 데이터를 저장하고 재사용 가능하고, 메모리 효율 좋고, 유지보수 용이하다.
왜 사용할까?
| 이유 | 설명 |
| 재사용성 | 여러 오브젝트가 동일 데이터를 공유 가능 |
| 직렬화 | 인스펙터에서 값을 편집 가능 |
| 독립성 | 씬에 의존하지 않음 (씬 간 공유 가능) |
| 퍼포먼스 | GameObject를 생성하지 않아서 메모리 효율이 좋음 |
| 구조화 | 데이터와 로직 분리를 통해 코드가 더 깔끔해짐 |
ScriptableObject 기본 구조
using UnityEngine;
[CreateAssetMenu(fileName = "NewItemData", menuName = "Item/ItemData")]
public class ItemData : ScriptableObject
{
public string itemName;
public int damage;
public Sprite icon;
}
📌 사용 예제: 무기 데이터 만들기
1. WeaponData.cs
using UnityEngine;
[CreateAssetMenu(fileName = "NewWeapon", menuName = "ScriptableObjects/WeaponData")]
public class WeaponData : ScriptableObject
{
public string weaponName;
public int attackPower;
public float range;
public Sprite icon;
}
2. 에셋 생성
- Unity 에디터에서 Project 창 → 우클릭 → Create → ScriptableObjects → WeaponData
- 여러 개의 무기 데이터를 각각 생성 가능
3. 무기를 사용하는 컴포넌트
using UnityEngine;
public class Weapon : MonoBehaviour
{
public WeaponData data;
void Start()
{
Debug.Log($"무기 이름: {data.weaponName}, 공격력: {data.attackPower}");
}
}
여러 무기 오브젝트가 같은 WeaponData를 공유하면 일괄 수정도 쉬워진다.
언제 쓰면 좋은가?
| 상황 | ScriptableObject 추천 |
| 아이템 데이터 관리 | ✅ |
| 스킬/스탯/능력치 관리 | ✅ |
| 퀘스트 정보 저장 | ✅ |
| 전역 설정, 게임 규칙 | ✅ |
| 저장/불러오기 용 | ❌ (PlayerPrefs, JSON 추천) |
| 씬에 존재하는 개별 객체의 고유 상태 | ❌ (MonoBehaviour 추천) |
장점과 주의사항
장점
- 데이터 중심 설계 가능
- 코드와 데이터 분리
- 유지보수, 테스트 편리
- 퍼포먼스 유리 (GameObject 생성 없음)
주의점
- ScriptableObject는 참조형이라 공유된 값이 동시에 바뀔 수 있음 (런타임에 조작 시 주의)
- 게임 플레이 중 값을 바꾸고 저장하려면 직렬화 시스템 또는 별도 저장 방식 필요
- 에디터에서만 생성 가능, 런타임 생성은 복잡함
고급 활용
게임 설정 데이터
[CreateAssetMenu(menuName = "Settings/GameConfig")]
public class GameConfig : ScriptableObject
{
public float enemySpawnRate;
public int maxEnemies;
}
게임 밸런스 조정 시 게임 종료 후 수치만 바꿔서 테스트 가능!
상태 기반 시스템 (State Pattern + ScriptableObject)
- 상태(State)나 전략(Strategy)을 ScriptableObject로 만들어 코드 분기 없이 사용 가능
결론
| 항목 | 설명 |
| 무엇인가? | 에셋으로 저장 가능한 데이터 객체 |
| 왜 쓰나? | 코드와 데이터를 분리하여 재사용, 유지보수, 퍼포먼스에 유리 |
| 언제 쓰나? | 게임 내 반복되는 데이터 구조를 효율적으로 관리할 때 |
| 주의할 점 | 참조 기반이라 런타임에서 값 수정 시 주의 필요 |

'TIL' 카테고리의 다른 글
| 커스텀 에디터(Custom Editor) (1) | 2025.06.04 |
|---|---|
| AnimationCurve로 구현한 낮과 밤 그리고 온도 (0) | 2025.05.27 |
| 전략 패턴과 SRP로 인벤토리 리팩토링 (0) | 2025.05.22 |
| [Unity] ImageType (1) | 2025.05.21 |
| [Unity] 델리게이트 (Delegate) (1) | 2025.05.20 |