오늘까지 제출해야하는 내일배움캠프 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
에는 문자열만 저장해야한다는 틀에 박힌 사고방식 때문인 것 같다.
유연한 사고를 해야겠다. 어떻게 해야 유연한 사고를 할 수 있을까 ,,