wan의 개발일기
RoomCraft #7. 프로젝트 저장/불러오기 — JSON 직렬화 본문
소스코드 → github.com/Jywan/RoomCraft
들어가며
지금까지 만든 기능들 — 방 만들고, 가구 배치하고, 회전하고 — 이걸 Play 멈추면 다 날아간다. 매번 처음부터 배치하는 건 말이 안 되니까, 이번에는 JSON으로 저장하고 불러오는 기능을 만든다.
저장 구조 설계
저장해야 할 정보:
- 방 크기 (가로, 세로, 높이)
- 배치된 가구들 (치수, 카테고리, 색상, 위치, 회전)
이걸 하나의 ProjectData 클래스로 묶었다.
public class ProjectData
{
public string projectName;
public string createdDate;
public RoomData roomData;
public List<FurnitureSaveData> furnitureList;
}
Color 직렬화 문제
Unity의 Color는 JsonUtility로 직렬화가 안 된다. 그래서 float 4개(R, G, B, A)로 분리 저장했다.
// Color를 float으로 분리 저장
public float colorR;
public float colorG;
public float colorB;
public float colorA;
JsonUtility는 Unity 내장 직렬화 도구인데, Vector3는 되면서 Color는 안 된다. 일관성이 좀 없긴 하다.
FurnitureSaveData — 가구 저장 변환
씬에 있는 FurnitureObject에서 저장용 데이터를 뽑는 메서드와, 반대로 저장 데이터를 FurnitureData로 복원하는 메서드를 만들었다.
// 씬 오브젝트 → 저장 데이터
public static FurnitureSaveData FromFurnitureObject(FurnitureObject obj)
{
var data = obj.GetData();
var save = new FurnitureSaveData();
save.id = data.id;
save.furnitureName = data.furnitureName;
save.categoryIndex = (int)data.category;
save.widthCm = data.widthCm;
save.depthCm = data.depthCm;
save.heightCm = data.heightCm;
save.colorR = data.color.r;
save.colorG = data.color.g;
save.colorB = data.color.b;
save.colorA = data.color.a;
save.posX = obj.transform.position.x;
save.posZ = obj.transform.position.z;
save.rotationY = obj.transform.eulerAngles.y;
return save;
}
// 저장 데이터 → FurnitureData 복원
public FurnitureData ToFurnitureData()
{
FurnitureData data = new FurnitureData(
furnitureName,
(FurnitureCategory)categoryIndex,
widthCm, depthCm, heightCm
);
data.id = id;
data.color = new Color(colorR, colorG, colorB, colorA);
return data;
}
ProjectManager — 파일 입출력
저장 경로
Application.persistentDataPath 아래에 Projects/ 폴더를 만들어서 JSON을 저장한다. 이 경로는 플랫폼마다 자동으로 적절한 위치를 잡아준다.
저장
public void SaveProject(string projectName, RoomData roomData)
{
ProjectData project = new ProjectData();
project.projectName = projectName;
project.roomData = roomData;
// 씬에 있는 모든 가구를 수집
FurnitureObject[] allFurniture = FindObjectsByType<FurnitureObject>(FindObjectsSortMode.None);
foreach (FurnitureObject obj in allFurniture)
{
project.furnitureList.Add(FurnitureSaveData.FromFurnitureObject(obj));
}
string json = JsonUtility.ToJson(project, true);
File.WriteAllText(filePath, json);
}
불러오기
public ProjectData LoadProject(string fileName)
{
string json = File.ReadAllText(filePath);
ProjectData project = JsonUtility.FromJson<ProjectData>(json);
return project;
}
JsonUtility.ToJson(project, true)에서 두 번째 인자 true는 pretty print. 사람이 읽을 수 있게 들여쓰기 된 JSON을 생성한다. 디버깅할 때 편하다.
불러오기 시 복원 흐름
- 기존 가구 전부 삭제 (Destroy)
- 저장된 가구 목록 순회
- 각 가구를 CreateFurniture()로 생성
- MoveTo()로 저장된 위치로 이동
- transform.rotation으로 회전 복원
// 기존 가구 전부 삭제
FurnitureObject[] existing = FindObjectsByType<FurnitureObject>(FindObjectsSortMode.None);
foreach (FurnitureObject obj in existing)
Destroy(obj.gameObject);
// 저장된 가구 복원
foreach (FurnitureSaveData save in project.furnitureList)
{
FurnitureData data = save.ToFurnitureData();
FurnitureObject furniture = interaction.CreateFurniture(data);
furniture.MoveTo(new Vector3(save.posX, 0f, save.posZ));
furniture.transform.rotation = Quaternion.Euler(0f, save.rotationY, 0f);
}
정리
| 기능 | 핵심 구현 |
|---|---|
| 프로젝트 데이터 | ProjectData — 방 + 가구 목록 통합 |
| 가구 직렬화 | FurnitureSaveData — 위치/회전/색상 float 분리 저장 |
| 저장 | JsonUtility.ToJson() → File.WriteAllText() |
| 불러오기 | File.ReadAllText() → JsonUtility.FromJson() |
| 저장 경로 | Application.persistentDataPath/Projects/ |
현재는 S/L 키로 테스트 중이다. 추후 저장 파일 목록 UI를 만들어서 선택해서 불러오는 기능을 추가할 예정.
'1인 게임개발 활동 > 가구배치 시뮬레이터' 카테고리의 다른 글
| RoomCraft #9. 방 커스터마이징 — 사용자 입력으로 방 크기 설정 (0) | 2026.06.28 |
|---|---|
| RoomCraft #8. 그리드 스냅 + 치수 표시 — 정렬 도우미와 가구 정보 UI (0) | 2026.06.28 |
| RoomCraft #6. 카테고리별 동적 모델 생성 — 팩토리 패턴으로 가구 형태 조합 (0) | 2026.06.28 |
| RoomCraft #5. 가구 생성 UI — 카테고리/치수/색상 입력 팝업 (0) | 2026.06.28 |
| RoomCraft 개발일지 #4. 충돌 감지 — 벽 밖 제한 + 겹침 경고 (0) | 2026.06.27 |