이틀전에인가.. 저녁에 만들었던 코드이다.
인터넷에서 찾아보며 만들고 나니 나중에 봤을때 코드의 흐름이 잘 이해가 되지 않았다.
자기가 작성한 코드를 봤을때 이해가 되지 않는건 부끄러우니까 코드 리뷰를 하긴 해야겠다 했는데
일요일인 오늘 시간이 나서 해보기로 했다.
[System.Serializable]
public class RankEntry
{
public string playerName;
public int score;
public RankEntry(string playerName, int score)
{
this.playerName = playerName;
this.score = score;
}
}
위 코드는 간단하게 설명하자면 데이터를 직렬화 해서 저장하기 위한 틀이다.
여기서 "직렬화"란 ? 객체의 상태를 저장 혹은 전송 하기위해 객체를 변환하는 과정이다.
데이터를 저장할 때 객체의 상태를 파일에 기록 하기 위한 과정이라고 생각하면 된다.
반대로 이 기록된 데이터를 객체로 변환하는것은 역 직렬화이다.
그리고 아래에서 보여줄 코드는 사실 PlayerPrefs를 사용하며, 복잡하지 않은 String값과 Int값만 저장하기에 위의 직렬화 코드는 굳이 필요하지 않았다.
하지만 앞으로의 과정에 이런 습관은 도움이 될 것 같아 작성하게 된 코드이다.
아래의 코드는 실질적으로 랭킹시스템을 관리하는 코드이다.
설명은 코드를 보며 주석에 작성하도록 하겠다
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class RankingManager : MonoBehaviour
{
private const int maxRankCount = 5;
public TMP_Text[] nameTexts;
public TMP_Text[] scoreTexts;
// rankList 에 RankEntry형식의 객체를 담을 수 있는 리스트를 생성
private List<RankEntry> rankList = new List<RankEntry>();
private void Start()
{
LoadRanking();
UpdateRankingUI();
}
public void AddNewScore(string playerName, int score)
{
// RankEntry 클래스를 사용하여 매개변수로 받아온 이름과 점수를 newEntry에 RankEntry형식으로 담아주고 객체화 하고
RankEntry newEntry = new RankEntry(playerName, score);
rankList.Add(newEntry); // rankList 리스트에 newEntry 객체를 추가
// 점수를 기준으로 내림차순으로 정렬(람다식) 간단하게 "리스트명.Sort((entry1, entry2) => entry2.비교할변수.CompareTo(entry1.score));"
// 자세하게 설명하면 entry2.비교할변수.CompareTo(entry1.비교할변수) 에서 entry2가 entry1보다 크면 양수 같으면 0, 적으면 음수를 반환한다.
rankList.Sort((entry1, entry2) => entry2.score.CompareTo(entry1.score));
// 점수가 적든 많든 추가했으니 가장 낮은 점수를 1개 제거해야함 맥스랭킹이 5니까 6개라면 if문 작동
if (rankList.Count > maxRankCount)
{
// 리스트가6개라면 0 1 2 3 4 5 이렇게 저장되어있을거고 위에서 내림차순 정렬했으니 5번을 삭제해야함 그러면 count는 6이니까 -1 해서 5번 RemoveAt으로 5번을 삭제
rankList.RemoveAt(rankList.Count - 1);
}
SaveRanking();
UpdateRankingUI();
}
private void SaveRanking()
{
// 데이터 저장하기 (이부분이 이해가 안되면 PlayerPrefs 및 List에 관한 설명을 찾아볼것.)
for (int i = 0; i < rankList.Count; i++)
{
PlayerPrefs.SetString($"RankName{i}", rankList[i].playerName);
PlayerPrefs.SetInt($"RankScore{i}", rankList[i].score);
}
PlayerPrefs.Save();
}
private void LoadRanking()
{
rankList.Clear();
// 저장된 데이터 불러오기 (이부분이 이해가 안되면 PlayerPrefs에 관한 설명을 찾아볼것.)
for (int i = 0; i < maxRankCount; i++)
{
if (PlayerPrefs.HasKey($"RankName{i}") && PlayerPrefs.HasKey($"RankScore{i}"))
{
string playerName = PlayerPrefs.GetString($"RankName{i}");
int score = PlayerPrefs.GetInt($"RankScore{i}");
rankList.Add(new RankEntry(playerName, score));
}
}
}
private void UpdateRankingUI()
{
for (int i = 0; i < maxRankCount; i++)
{
if (i < rankList.Count)
{
nameTexts[i].text = rankList[i].playerName;
scoreTexts[i].text = rankList[i].score.ToString();
}
else
{
// (예외처리) 저장된 데이터가 모자라면 표시
nameTexts[i].text = "---";
scoreTexts[i].text = "---";
}
}
}
}
끗 (사실 작성하고 이해하고나면 어렵지 않은 코드들이다. 생각만으로는 오 구현하기 꽤 어렵겠는데,, 싶은 로직들도
뜯어보고나면 다 알고있는 방법들이다. 정말 대부분의 코드가 그렇다 .. 뭐 수학식이 많이 들어간 코드들 제외하고...
)