UNITY/Script

[UNITY C#] 게임 데이터 직렬화(Serialize) 저장 및 로드 구현

HYEOKJUN 2022. 2. 7. 18:00
반응형

데이터 저장 및 로드를 구현하기 위해서 데이터를 저장할 클래스를 만들어야 합니다.

[System.Serializable] // 이 클래스를 파일로 저장하기 위해서 직렬화를 가능하게 합니다.
public class Data
{   
	public ulong? highScore;
	public int? coin;
    
	//...

	public float? audio_BGM, audio_SFX;
	public UnityEngine.SystemLanguage? language;
}

위와 같이 클래스를 생성하고 저장할 필드 데이터를 작성합니다.

* Data 클래스에 클래스 데이터를 추가하는 경우 해당 클래스에 [System.Serializable] 속성을 추가해야 합니다.


DataManager.cs

using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEngine;

/// <summary>
/// 데이터를 관리하는 정적 클래스입니다.
/// </summary>
public static class DataManager
{
	/// <summary>
	/// 데이터의 경로입니다.
	/// </summary>
	static string path_data = Path.Combine(Application.persistentDataPath, "data.bin"); 

	/// <summary>
	/// 데이터에 이상이 있는지 검사합니다. (최초 실행시에 확인합니다)
	/// </summary>
	public static void CheckData() { 
		Data data = File.Exists(path_data) ? Load() : new Data(); // 데이터가 경로에 존재한다면 Load하고 없으면 새로운 데이터를 생성합니다.
        
		// 데이터가 존재하지 않는 경우 기본값으로 초기화합니다.
		if(!data.highScore.HasValue) { data.highScore = 0; }

		//...
        
		if(!data.audio_BGM.HasValue) { data.audio_BGM = -20f; }
		if(!data.audio_SFX.HasValue) { data.audio_SFX = -20f; }
		if(!data.language.HasValue) { data.language = Application.systemLanguage; }

        Save(data);
	}

	/// <summary>
	/// 데이터를 저장합니다.
	/// </summary>
	/// <param name="data">저장할 데이터입니다.</param>
	public static void Save(Data data) { 
		BinaryFormatter formatter = new BinaryFormatter();
		FileStream file = new FileStream(path_data, FileMode.Create);
		file.Position = 0;
		formatter.Serialize(file, data);
		file.Close();
	}
	/// <summary>
	/// <para>데이터를 불러옵니다.</para>
	/// <para>(데이터가 존재하지 않는 경우 null을 반환합니다)</para>
	/// </summary>
	public static Data Load() { 
		try {
			BinaryFormatter formatter = new BinaryFormatter();
			FileStream file = new FileStream(path_data, FileMode.Open);
			file.Position = 0;
			Data data = (Data)formatter.Deserialize(file);
			file.Close();
			return data;
		} catch {
            throw new FileNotFoundException("데이터가 존재하지 않습니다.");
		}
	}
}

유니티 데이터 저장 경로에 대해서는 아래 링크에서 자세히 살펴볼 수 있습니다.
https://3dmpengines.tistory.com/1745

유니티 데이터 패스(Application.dataPath, ) 정리 와 예약 폴더들(Resources, )

유니티 데이터 패스 정리 테스트한 기기에 따라 결과가 다를 수 있음 [윈도우 에디터] Application.persistentDataPath : 사용자디렉토리/AppData/LocalLow/회사이름/프로덕트이름 파일 읽기 쓰기 가능 Applicatio

3dmpengines.tistory.com

데이터 검사

데이터가 null이 반환되는 경우를 대비하여 메인 메뉴와 같은 게임 첫 실행 단계에서 다음 메서드를 실행합니다.

DataManager.CheckData();

다음 메소드를 실행하면 Data 클래스가 업데이트되었을 때에도 어느 정도 원활하게 작동하도록 도울 수 있습니다.

* Data 클래스를 업데이트하여 Save 및 Load시 일부 오류가 발생할 수 있습니다.
(Data 클래스에 저장한 클래스를 수정하는 경우 => 해당 클래스의 데이터 초기화 방법을 마련해야 합니다)

데이터 로드

데이터를 불러올 때 다음과 같은 메서드를 실행합니다.

Data data = DataManager.Load();

textComponent.text = data.highScore.Value; // 불러온 데이터를 사용합니다
//...

불러온 data 변수는 일반 클래스처럼 활용이 가능합니다.

데이터 저장

데이터를 저장할 때 다음과 같은 메서드를 실행합니다.

Data data = DataManager.Load();

data.highScore = 88; // 불러온 데이터를 수정합니다.
//...

DataManager.Save(data);

데이터를 불러오지 않은 상태에서 새 Data 클래스 인스턴트를 생성하여 저장하면 기존 데이터가 사라지기 때문에 반드시 데이터를 불러온 후에 저장해야 합니다.

반응형