게임에서 뽑기 시스템은 플레이어의 몰입도를 극대화하는 핵심 메커니즘 중 하나입니다.
이번 글에서는 Unity에서 2단계 확률 기반 가챠 시스템을 설계하고 구현하는 방법을 소개합니다.
시스템 개요
이 가챠 시스템은 다음과 같은 구조로 구성됩니다:
- 1단계: 제작 방식(일반, 고급, 특수 등)을 확률에 따라 결정
- 2단계: 선택된 제작 방식에 따라 세부 결과(동일 오퍼레이터, 상위 등급 등)를 다시 확률 기반으로 결정
이 방식은 단계별로 결과를 분기할 수 있어, 일반적인 단일 룰 방식보다 확장성과 다양성이 뛰어납니다.
예시 데이터 구조
실제 프로젝트와 헷갈리지 않도록 예시용 테이블로 구성하였습니다.
🔹 1단계: 제작 타입 선택 테이블
Key | category | weight | desc |
20001 | normal | 70 | 일반 제작 |
20002 | advanced | 20 | 고급 제작 |
20003 | special | 10 | 특수 제작 |
🔹 2단계: 세부 결과 분기 테이블
Key | category | resultType | weight | desc |
30001 | 20001 | same_operator | 15 | 동일 오퍼레이터 등장 |
30002 | 20001 | higher_tier | 25 | 상위 등급 등장 |
30003 | 20001 | material_difference | 60 | 재료 조합 변화 |
30004 | 20002 | same_operator | 20 | 동일 오퍼레이터 등장 |
30005 | 20002 | higher_tier | 30 | 상위 등급 등장 |
30006 | 20002 | material_difference | 50 | 재료 조합 변화 |
30007 | 20003 | special_case | 100 | 특수 제작 고정 결과 |
코드 구현 (작동 흐름 설명 포함)
🔸 데이터 구조 정의
public enum ProductionType { normal, advanced, special }
public enum ResultType { same_operator, higher_tier, material_difference, special_case }
[System.Serializable]
public class ProductionEntry
{
public int key;
public ProductionType category;
public float weight;
public string desc;
}
[System.Serializable]
public class ResultEntry
{
public int key;
public int productionKey;
public ResultType resultType;
public float weight;
public string desc;
}
- 제작 방식과 결과 분기를 각각 별도의 클래스로 관리
- enum을 사용해 가독성과 유지보수성 확보
🔸 1단계 가챠: 제작 방식 선택
public int GetRandomProductionKey(ProductionType category)
{
var filtered = productionTable.Where(e => e.category == category).ToList();
float totalWeight = filtered.Sum(e => e.weight);
float rand = Random.Range(0, totalWeight);
float cumulative = 0f;
foreach (var entry in filtered)
{
cumulative += entry.weight;
if (rand <= cumulative)
return entry.key;
}
return -1;
}
- category에 해당하는 제작 방식 리스트에서
- 가중치 기반으로 하나의 제작 ID(key)를 무작위로 선택합니다.
- 예시:
- rand가 85일 경우:
- 첫 항목(70)보다 크므로 패스
- 두 번째 항목(70+20=90)이 되면 85 <= 90 이 항목이 뽑힘
- rand가 85일 경우:
🔸 2단계 가챠: 결과 분기 결정
public ResultEntry GetRandomResult(int productionKey)
{
var filtered = resultTable.Where(e => e.productionKey == productionKey).ToList();
float totalWeight = filtered.Sum(e => e.weight);
float rand = Random.Range(0, totalWeight);
float cumulative = 0f;
foreach (var entry in filtered)
{
cumulative += entry.weight;
if (rand <= cumulative)
return entry;
}
return null;
}
- 1단계에서 선택된 제작 ID에 따라 다시 세부 결과를 가중치 기반으로 무작위 선택합니다.
🔸 전체 실행 흐름
public void ExecuteGacha(ProductionType category)
{
int productionKey = GetRandomProductionKey(category);
var result = GetRandomResult(productionKey);
Debug.Log($"제작 방식: {category}, 선택된 제작 ID: {productionKey}");
Debug.Log($"결과: {result.resultType} (key: {result.key})");
}
마무리
이 포스트에서는 Unity에서 2단계 확률 기반 가챠 시스템을 설계하고 구현하는 과정을 다뤘습니다.
단순한 뽑기 시스템을 넘어서 구조적이며 확장 가능한 설계 방식을 도입하면, 운영 편의성과 밸런싱 조정 모두에 유리한 기반을 마련할 수 있습니다.
현재는 Inspector에서 수동으로 설정한 테이블을 사용하고 있지만,
다음 단계에서는 JSON 기반의 외부 테이블을 불러와 가챠 데이터를 동적으로 구성할 계획입니다. 이를 통해 실제 서비스 환경에서도 실시간 데이터 수정이 가능하도록 만들 예정입니다.
'내일배움캠프 > Unity Final Projcet' 카테고리의 다른 글
[Unity] 보상 드롭 시스템 및 UI 구현 (0) | 2025.04.21 |
---|---|
[Unity] GridLayoutGroup에서 마지막 줄이 가운데 정렬되지 않을 때 해결 방법 (트러블슈팅) (0) | 2025.04.18 |
[Unity] UI 패널 전환 효과를 DOTween으로 구현하기 (0) | 2025.04.16 |
[Unity] 카드 뽑기 시스템 리팩터링 (0) | 2025.04.14 |
[Unity] 랜덤 카드 뽑기 기능 구현 (0) | 2025.04.11 |