✔ Unity, C# - 배열,리스트,딕셔너리를 데이터 파일로 저장하기
데이터베이스를 활용하지 않고 로컬내에서 데이터 관리를 해야하는 경우에는 보통 파일단위로 관리를 한다.
예를 들어 사용자마다 게임 환경 설정(마우스감도, 해상도 등)을 하고 저장하면 설치된 내 게임만 저장되면 된다.
데이터를 파일로 저장하는 방법은 다양하다.
가장 쉽게 사용할 수 있는 방법은 Serialize를 활용하는 방법이다.
저장하려고 하는 Class위에 [Serializable]을 선언해주어야 한다.
■ Class 데이터를 파일 저장 및 로드 예제
이 예제는 GameObject의 Position과 Name을 저장하고 불러오는 간단한 예제입니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class TestData
{
public string name;
public float posX;
public float posY;
public float posZ;
}
public class SaveAndLoad : MonoBehaviour
{
private string m_filePath = @"C:\test\TestData.dat";
private BinaryFormatter binaryFormatter = new BinaryFormatter();
void Start()
{
//테스트 데이터 생성
TestData testData1 = new TestData
{
name = gameObject.name,
posX = transform.position.x,
posY = transform.position.y,
posZ = transform.position.z
};
// --------- 데이터 저장 ------------
//데이터 저장
bool isSuccess = OnSave(m_filePath, testData1);
//저장완료
if(isSuccess)
{
Debug.Log("저장 완료");
}
else
{
Debug.Log("저장 오류");
}
// --------- 데이터 로드 -------------
TestData _loadData = OnLoad(m_filePath);
if(_loadData != null)
{
Debug.Log(_loadData.name);
}
}
//저장 함수
public bool OnSave(string filePath, TestData data)
{
try
{
using (Stream ws = new FileStream(filePath, FileMode.Create))
{
binaryFormatter.Serialize(ws, data);
}
return true;
}
catch(Exception e)
{
Debug.Log(e.ToString());
return false;
}
}
//로드 함수
public TestData OnLoad(string filePath)
{
TestData _loadData = null;
using (Stream rs = new FileStream(filePath, FileMode.Open))
{
_loadData = (TestData)binaryFormatter.Deserialize(rs);
}
return _loadData;
}
}
■ List, Array데이터를 파일 저장 및 로드 예제
위의 예제와 거의 일치하며 자료형만 List<T>로 변경되어 사용된 것을 볼 수 있습니다.
배열 형태의 데이터를 사용하고 싶다면 List<T>를 T [] 로 자료형만 변경해서 사용하시면 됩니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class TestData
{
public string name;
public float posX;
public float posY;
public float posZ;
}
public class SaveAndLoad : MonoBehaviour
{
private string m_filePath = @"C:\test\TestData.dat";
private BinaryFormatter binaryFormatter = new BinaryFormatter();
void Start()
{
List<TestData> datas = new List<TestData>();
//테스트 데이터 생성
TestData testData1 = new TestData
{
name = gameObject.name,
posX = transform.position.x,
posY = transform.position.y,
posZ = transform.position.z
};
datas.Add(testData1);
// --------- 데이터 저장 ------------
//데이터 저장
bool isSuccess = OnSave(m_filePath, datas);
//저장완료
if(isSuccess)
{
Debug.Log("저장 완료");
}
else
{
Debug.Log("저장 오류");
}
// --------- 데이터 로드 -------------
List<TestData> _loadData = OnLoad(m_filePath);
if(_loadData != null)
{
foreach (var item in _loadData)
{
Debug.Log(item.name);
}
}
}
public List<TestData> OnLoad(string filePath)
{
List<TestData> _loadData = null;
using (Stream rs = new FileStream(filePath, FileMode.Open))
{
_loadData = (List<TestData>)binaryFormatter.Deserialize(rs);
}
return _loadData;
}
public bool OnSave(string filePath, List<TestData> data)
{
try
{
using (Stream ws = new FileStream(filePath, FileMode.Create))
{
binaryFormatter.Serialize(ws, data);
}
return true;
}
catch (Exception e)
{
Debug.Log(e.ToString());
return false;
}
}
}
■ Dictionary 데이터를 파일로 저장 및 로드
마지막으로 Dictionary 데이터 입니다. 안타깝게도 Dictionary 자료형은 Serializable이 제공되지 않습니다.
.Net 프로젝트의 경우에는 Json Convert 를 제공하는 패키지를 설치하여 변환이 가능하지만 Unity에서는 안됩니다 ㅠ_ㅠ
유니티는 안되는게 참많네요 ㅠ_ㅠ
그래서 결국 Dictionary 형태를 List 혹은 Array 형태로 변경하여 Serialize 해야합니다.
우리는 위에서 배운 내용으로 응용하면 쉽게 해결가능합니다.
Dictionary의 key와 value를 담을수 있는 클래스를 하나 생성하여 저장하는 것입니다!!
그럼 클래스 하나만 저장하면 끝!
아래 예제를 참고하세요~
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Linq;
//딕셔너리 정보를 담을 클래스 추가
[Serializable]
public class DictionaryConvertData
{
public List<string> keys;
public List<TestData> values;
}
[Serializable]
public class TestData
{
public string name;
public float posX;
public float posY;
public float posZ;
}
public class SaveAndLoad : MonoBehaviour
{
private string m_filePath = @"C:\test\TestData.dat";
private BinaryFormatter binaryFormatter = new BinaryFormatter();
void Start()
{
Dictionary<string, TestData> testDatas = new Dictionary<string, TestData>();
// 1번째 테스트 데이터 생성
TestData testData1 = new TestData
{
name = gameObject.name + "1",
posX = transform.position.x,
posY = transform.position.y,
posZ = transform.position.z
};
//1번쨰 데이터 딕셔너리 저장
testDatas.Add("key1",testData1);
// 2번째 테스트 데이터 생성
testData1 = new TestData
{
name = gameObject.name + "2",
posX = transform.position.x,
posY = transform.position.y,
posZ = transform.position.z
};
//2번쨰 데이터 딕셔너리 저장
testDatas.Add("key2", testData1);
//---------- 딕셔너리를 저장데이터로 변경 -----------
DictionaryConvertData convertData = new DictionaryConvertData();
convertData.keys = testDatas.Keys.ToList();
convertData.values = testDatas.Values.ToList();
// --------- 데이터 저장 ------------
//데이터 저장
bool isSuccess = OnSave(m_filePath, convertData);
//저장완료
if(isSuccess)
{
Debug.Log("저장 완료");
}
else
{
Debug.Log("저장 오류");
}
// --------- 데이터 로드 -------------
DictionaryConvertData _loadData = OnLoad(m_filePath);
if(_loadData != null)
{
Dictionary<string, TestData> dictionaryDatas = new Dictionary<string, TestData>();
//로딩된 데이터를 딕셔너리로 변환
for (int i = 0; i < _loadData.keys.Count; i++)
{
Debug.Log(_loadData.keys[i] + " : " + _loadData.values[i].name);
//딕셔너리 저장
dictionaryDatas.Add(_loadData.keys[i], _loadData.values[i]);
}
}
}
public DictionaryConvertData OnLoad(string filePath)
{
DictionaryConvertData _loadData = null;
using (Stream rs = new FileStream(filePath, FileMode.Open))
{
_loadData = (DictionaryConvertData)binaryFormatter.Deserialize(rs);
}
return _loadData;
}
public bool OnSave(string filePath, DictionaryConvertData data)
{
try
{
using (Stream ws = new FileStream(filePath, FileMode.Create))
{
binaryFormatter.Serialize(ws, data);
}
return true;
}
catch (Exception e)
{
Debug.Log(e.ToString());
return false;
}
}
}
예제에서 보듯이 DictionaryConvertData 클래스안에 List로 Key정보와 Value정보를 모두 담을 수 있도록 구성하고 저장합니다.
비록 로드하고 나면 for문으로 작업을 한번 해야하지만 ㅠ_ㅠ
감사합니다 ^_^
'Programming > Unity' 카테고리의 다른 글
[Unity] 유니티 컴파일 에러 - Assembly 'unityplastic' , PlasticSCM 관련 (683) | 2022.10.05 |
---|---|
[Unity] 유니티에서 Mysql, MariaDB 연동하고 조회하기 (739) | 2022.09.23 |
[Unity] 충돌호출 함수 OnTrigger와 OnCollision 사용법 및 차이 (1) | 2022.09.15 |
[Unity] [해결] WebGL 빌드 시 나타나는 오류 - IL2CPP (2) | 2022.06.22 |
[Unity] 유니티 개발시 에디터 필수 조작 편의 Tips (936) | 2022.04.06 |
댓글