오늘까지 제출해야하는 내일배움캠프 Chapter 1의 미니프로젝트가 있었다.
게임개발종합반 4주차 강의에서 진행한 카드게임을 따라서 만들면 되는 프로젝트다.
추가기능을 구현해도 된다고 해서 여태까지의 클리어타임 중에 가장 빠른 1~5위를 저장해두고, 게임오버 창에 띄워주는 기능을 구현했다.
베스트 클리어 타임을 저장할 List가 필요했다. 이 List는 다음의 규칙을 따른다.
public void AddBestTime()
{
bestTimes.Add(time);
bestTimes = bestTimes.OrderBy(item => item).ToList();
while (bestTimes.Count > 5)
bestTimes.RemoveAt(bestTimes.Count - 1);
}
PlayerPrefs는 유니티에서 데이터를 플레이어의 로컬에 Save/Load 할 수 있게 해주는 기능이다.
string, int, float 3가지 자료형을 취급할 수 있으며, 저장할 땐 key와 value가 한 쌍이다.
key는 string타입이며, 변수명을 그대로 가져다 쓰는 등, 이게 어디에 쓰는 데이터인지 알아 볼 수 있게 해주는 것이 좋겠다.
근데 내가 취급할 데이터는 List<float>이다. 배열 데이터를 저장해야하는데 그런건 없다. 그래서 List<float>를 string으로 변환해서 저장하기로 했다. JSON처럼 말이다.
저장할 때는 List<float>의 값들을 string으로 변환하고, 원소 사이사이에 ',' 문자로 구분해준다.
ex) List의 원소가 { 1 2 3 4 5 } 라면, string "1,2,3,4,5"로 변환하여 저장.
public void SaveBestTimes()
{
string key = "bestTimes";
string value = "";
for (int i = 0; i < bestTimes.Count; i++)
value += bestTimes[i].ToString("N2") + ',';
value = value.TrimEnd(',');
PlayerPrefs.SetString(key, value);
Debug.Log("save : " + key + ":" + value);
}
불러올 때는 PlayerPrefs에서 받아온 string을 ',' 문자로 split하고 float형으로 parsing하여 List로 들고 온다!
public void LoadBestTimes()
{
List<float> res = new List<float>();
string key = "bestTimes";
string value = PlayerPrefs.GetString(key);
Debug.Log("load : " + key + ":" + value);
if (value.Length != 0)
{
var splits = value.Split(',');
for (int i = 0; i < splits.Length; i++)
res.Add(float.Parse(splits[i]));
bestTimes = res;
}
}
void GameOver()
{
Time.timeScale = 0f;
LoadBestTimes();
if (time <= 30f)
AddBestTime();
SaveBestTimes();
for (int i = 0; i < bestTimes.Count; i++)
bestTimeTexts[i].text = bestTimes[i].ToString("N2");
gameOverWindow.SetActive(true);
}
게임이 끝나면, PlayerPrefs에서 데이터를 불러와서 List로 받는다. 이 List에 이번 판의 클리어 타임(클리어 못했다면 패스)을 추가하고 순위를 갱신한다.
갱신된 List를 다시 PlayerPrefs에 저장하고, GameOver 창에 순서대로 표시해준다. 이때, bestTimeTexts[i].text의 기본값은 아직 자리가 남은 순위권의 처리를 위해 "-"로 해줬다.
테스트를 위해 리스트에 { 25.30, 28.88, 28.90, 29.70 } 4개를 넣어놓고 그대로 클리어 실패를 해봤다.

제대로 동작하는 것 같다. 다음 판은 리스트에 제대로 삽입/정렬이 되는지 확인하기 위해 클리어를 해봤다.

25.30초 만에 클리어했고 제대로 1위에 랭크됐다. 다음 판은 리스트가 제대로 크기 5를 유지하는지 확인하기 위해 클리어를 해봤다.

18.76초 만에 클리어했고 제대로 1위에 랭크됐다. 기존의 5위였던 29.70초는 순위권에서 쫓겨났고 제대로 동작하는 것을 확인했다.
처음에 배열 요소를 로컬에 저장한다고 생각했을 떄, 프로젝트에 JSON을 설치해야하나.... 싶었다.
구글링을 해보니 PlayerPrefs에 string으로 변환해서 배열을 저장할 수 있다는 걸 보고 JSON 쓸 생각은 하면서 왜 이 생각은 못했지? 싶었다.
PlayerPrefs가 취급하는 자료형이 string, float, int뿐이라 string에는 문자열만 저장해야한다는 틀에 박힌 사고방식 때문인 것 같다.
유연한 사고를 해야겠다. 어떻게 해야 유연한 사고를 할 수 있을까 ,,