[Unity] Firebase를 활용한 리더보드 구현

muchan
muchan
∙∙조회 12

개요

Firebase Realtime Database를 활용하여 실시간으로 갱신되는 리더보드 시스템을 구현하였다. 플레이어의 점수를 서버에 저장하고, 점수 변경 시 모든 사용자에게 즉시 반영되는 구조로 개발하였다.


시스템 구조

리더보드 시스템은 크게 다음과 같은 흐름으로 동작한다.

text
게임 종료
    ↓
점수 저장
    ↓
최고 점수 여부 확인
    ↓
Firebase 리더보드 갱신
    ↓
실시간 이벤트 발생
    ↓
리더보드 UI 갱신

게임이 종료되면 현재 점수를 저장하고, 기존 최고 점수보다 높은 경우에만 Firebase 리더보드를 업데이트한다.


최고 점수 관리

모든 게임 결과를 저장하는 대신 사용자별 최고 점수만 관리하도록 설계하였다.

csharp
if(score > cachedBestScore)
{
    await UpdateBestScoreAsync(score);
    await LeaderboardManager.Instance.SaveToLeaderboardAsync(score);
}

위와 같은 방식으로 기존 기록보다 높은 점수가 나왔을 때만 리더보드를 갱신한다. 이를 통해 불필요한 데이터 저장을 줄이고 효율적으로 랭킹을 관리할 수 있다.


Firebase 데이터 저장

리더보드 데이터는 사용자 ID를 Key로 사용하여 저장하였다.

json
leaderboard
{
    "user_uid":
    {
        "userId":"user_uid",
        "nickname":"Player",
        "score":300,
        "timestamp":1750000000000
    }
}

저장 시에는 사용자 ID, 닉네임, 점수, 저장 시간을 함께 기록한다.

csharp
Dictionary<string, object> entryData =
new Dictionary<string, object>
{
    {"userId", userId},
    {"nickname", nickname},
    {"score", score},
    {"timestamp", ServerValue.Timestamp}
};

사용자 ID를 기준으로 데이터를 저장하기 때문에 한 사용자는 하나의 리더보드 정보만 가지며, 새로운 최고 점수가 등록되면 기존 데이터가 갱신된다.


리더보드 조회

리더보드는 점수를 기준으로 정렬하여 상위 랭킹만 조회한다.

csharp
Query query =
    leaderboardRef
        .OrderByChild("score")
        .LimitToLast(10);

Firebase는 오름차순으로 데이터를 반환하므로, 데이터를 수신한 뒤 내림차순으로 다시 정렬하였다.

csharp
list.Sort((a, b) => b.score.CompareTo(a.score));

이를 통해 높은 점수를 가진 플레이어가 상단에 표시되도록 구현하였다.


실시간 업데이트 구현

Firebase Realtime Database의 가장 큰 장점은 데이터 변경을 실시간으로 감지할 수 있다는 점이다.

리더보드 시스템에서는 ValueChanged 이벤트를 활용하여 실시간 갱신 기능을 구현하였다.

csharp
listenerQuery.ValueChanged += OnValueChanged;

리더보드 데이터가 변경되면 이벤트가 호출되고, 최신 데이터를 다시 불러온다.

csharp
private void OnValueChanged(
    object sender,
    ValueChangedEventArgs args)
{
    List<LeaderboardEntry> leaderboard =
        ParseEntries(args.Snapshot);

    OnLeaderboardUpdated?.Invoke(leaderboard);
}

이벤트를 통해 UI에 최신 리더보드 정보를 전달한다.


UI 갱신

리더보드 UI는 이벤트 기반으로 동작한다.

csharp
LeaderboardManager.Instance.OnLeaderboardUpdated
    += OnLeaderboardUpdated;

데이터가 변경되면 기존 UI를 제거한 뒤 최신 데이터를 이용해 다시 생성한다.

csharp
texts[0].text = $"{rank}";
texts[1].text = entry.nickname;
texts[2].text = $"{entry.score}점";

결과적으로 사용자는 별도의 새로고침 없이도 실시간으로 변경되는 랭킹을 확인할 수 있다.


구현 결과

이번 리더보드 시스템은 Firebase Realtime Database를 활용하여 서버 구축 없이 실시간 랭킹 기능을 구현할 수 있었다. 또한 최고 점수만 저장하는 구조를 통해 데이터 관리 효율성을 높였으며, 이벤트 기반 UI 갱신을 통해 사용자 경험을 개선할 수 있었다.

Firebase의 실시간 동기화 기능 덕분에 비교적 적은 코드로도 안정적인 리더보드 시스템을 구축할 수 있었고, 향후 시즌제 랭킹이나 친구 랭킹 등의 기능으로 확장하기에도 용이한 구조를 설계할 수 있었다.