빠른 비교
text
씬 사이 임시 공유:
- ScriptableObject
- DontDestroyOnLoad
앱 재실행 뒤에도 유지:
- PlayerPrefs
- JSON save file갈리는 기준
- Unity에서 "데이터를 저장한다"는 말은 사실 두 문제를 섞고 있습니다. 하나는 씬 전환 중에도 값을 유지하느냐이고, 다른 하나는 게임을 껐다 켜도 남아 있느냐입니다.
DontDestroyOnLoad는 오브젝트 자체를 다음 씬으로 가져가는 방식입니다. 오디오 플레이어, 전역 서비스, 공용 오버레이처럼 생명주기를 유지해야 하는 매니저에 잘 맞지만, 전역 상태를 늘리기 쉬워서 남용은 위험합니다.ScriptableObject는 씬 밖 공유 데이터 컨테이너로 쓰기 좋습니다. 여러 시스템이 같은 런타임 상태나 설정값을 공유하게 만들 수 있지만, asset 원본과 세션 중 임시 상태를 혼동하지 않도록 규칙이 필요합니다.PlayerPrefs는 옵션, 마지막 선택값, 간단한 해금 여부처럼 작은 값을 저장하는 데 적합합니다. 구조화된 세이브 시스템을 대신하기에는 표현력과 보안, 버전 관리가 제한적입니다.- JSON 저장은 복잡한 진행 상태, 인벤토리, 퀘스트, 월드 상태처럼 구조가 있는 데이터를 파일 형태로 직렬화할 때 더 잘 맞습니다. 대신 저장 시점, 버전 마이그레이션, 로드 실패 처리를 스스로 설계해야 합니다.
선택 기준
| 상황 | 적합한 선택 |
|---|---|
| 씬이 바뀌어도 살아있어야 하는 매니저 | DontDestroyOnLoad |
| 여러 씬/시스템이 공유할 설정·데이터 | ScriptableObject 데이터 컨테이너 |
| 볼륨·마지막 선택 등 간단한 값 저장 | PlayerPrefs |
| 인벤토리·퀘스트 등 구조화된 세이브 | JSON 직렬화 → 파일 저장 |
주의할 점
모든 공유 데이터를 DontDestroyOnLoad 전역 매니저로 해결하면 테스트와 디버깅이 급격히 어려워집니다. 값만 필요한 경우에는 오브젝트를 살려 두지 말고 데이터 전달 구조로 해결하세요.
csharp
// ❌ 값 하나 때문에 매니저 전체를 DontDestroyOnLoad
public class PlayerDataManager : MonoBehaviour
{
public static PlayerDataManager Instance;
public int score; // 이 값 하나 때문에 씬 간 이동
void Awake() => DontDestroyOnLoad(gameObject);
}
// ✅ 데이터만 ScriptableObject로 분리
[CreateAssetMenu]
public class PlayerData : ScriptableObject
{
public int score; // SO는 씬 로드와 무관하게 유지
}
// 또는 씬 전환 시 static/파라미터로 값만 전달참고 링크
4 sources