한 줄 요약
기존 스킬 카드 시스템을 스킬트리로 확장하면서, 단순한 수치 변화와 특수한 기능을 가진 스킬을 하나의 구조에서 함께 관리할 수 있도록 설계를 개선했어요.
들어가며
안녕하세요, <우주적 베이글샵> PO 장조성이에요.
이전 개발일지에서는 BaseCardBehavior와 ScriptableObject를 바탕으로 한 스킬 카드 시스템 1차안을 소개했어요.
이번에는 그 구조를 발전시켜, 게임의 핵심 성장 요소를 담당할 스킬트리 시스템으로 확장한 과정을 정리해 보려고 해요.
우주적 베이글샵의 스킬은 단순히 수치만 올리는 기능부터, 노드 생성 방식이나 선긋기 조작처럼 게임의 규칙 자체를 바꾸는 기능까지 포함해요. 그래서 모든 스킬을 같은 방식으로 구현하기보다, 공통 데이터 구조 안에서 수치형과 특수형 효과를 함께 관리할 수 있도록 구성했어요.
이번 주 목표
스킬트리 시스템을 구성하며 중점으로 둔 목표는 세 가지예요.
- 확장성: Q0~Q3의 서로 다른 게임 요소를 하나의 규칙 안에서 관리하기
- 기획 편의성: 스킬 이름, 설명, 가격, 레벨, 선행 조건을 데이터 에셋과 CSV에서 확인하기
- 구현 유연성: 단순 수치 강화와 특수 로직을 같은 스킬트리에서 함께 활용하기
실제로 한 것
1. 스킬트리 노드 데이터 구조 만들기
스킬트리의 각 노드는 SkillNodeData라는 ScriptableObject로 관리하고 있어요.
각 노드에는 다음과 같은 정보가 들어가요.
- 스킬 고유 ID
- 표시 이름과 설명
- 아이콘과 소속 분기
- 해금 가격 및 레벨업 가격
- 최대 레벨
- 선행 노드
- 배타 선택 그룹
- 실제 효과를 적용할 대상 스탯 또는 특수 행동 프리팹
이 구조 덕분에 새 스킬을 추가할 때는 기본적으로 코드부터 새로 만드는 것이 아니라, 노드 데이터를 만들고 필요한 효과만 연결하는 방식으로 작업할 수 있게 됐어요.
[CreateAssetMenu(fileName = "NewSkillNode", menuName = "SpaceBagel/SkillNode")]
public class SkillNodeData : ScriptableObject
{
public string skillId;
public string displayName;
public string description;
public SkillBranch branch;
public int unlockCost;
public int maxLevel;
public int[] levelUpCosts;
public TargetStat targetStat;
public float valuePerLevel;
public BaseCardBehavior behaviorPrefab;
public List<SkillNodeData> prerequisites;
public PrerequisiteMode prerequisiteMode;
public string exclusiveGroup;
}

2. 수치형 스킬과 특수형 스킬 분리하기
현재 스킬은 크게 두 방식으로 작동해요.
첫 번째는 수치형 스킬이에요.
예를 들어 베이글 가치 증가, 합성 추가 히트, 손님 관계도 증가 확률처럼 특정 수치만 바꾸는 효과예요.
이런 효과는 TargetStat과 레벨당 수치만 지정하면 중앙 스탯 계산 구조에서 처리할 수 있도록 만들었어요. 기획 데이터와 실제 적용 대상이 분리되기 때문에, 밸런스를 조정할 때 코드 수정이 줄어드는 장점이 있어요.
두 번째는 특수형 스킬이에요.
노드 생성 규칙 변경, 선의 유지 시간 조절, 자동 판매처럼 별도 이벤트 처리나 오브젝트 제어가 필요한 효과가 여기에 해당해요.
특수형 스킬은 기존 카드 시스템의 BaseCardBehavior를 활용합니다. 스킬이 해금되면 효과 프리팹이 생성되고, 필요한 게임 이벤트를 구독하거나 기능을 적용하는 방식이에요.
public abstract class BaseCardBehavior : MonoBehaviour
{
[HideInInspector]
public int currentLevel;
public void Initialize(int level)
{
currentLevel = level;
OnEquip();
}
protected virtual void OnEquip() { }
protected virtual void OnDestroy() { }
}
즉, 단순한 수치 강화는 데이터 중심으로, 게임 규칙을 바꾸는 효과는 행동 중심으로 구현하는 혼합 구조를 사용하고 있어요.
3. Q0~Q3 분기로 게임 요소 정리하기
스킬트리는 게임의 주요 조작 영역을 기준으로 네 개의 분기로 나누었어요.
- Q0: 오븐과 노드 생성, 변환
- Q1: 매대와 합성, 판매 보조
- Q2: 손님, 관계도, 보상
- Q3: 선긋기와 조작 확장
이렇게 분리하면서 각 스킬이 어느 플레이 요소에 영향을 주는지 한눈에 확인할 수 있게 됐어요. 또한 기획 단계에서도 “이 효과가 어떤 분기에 속하는가”를 먼저 판단할 수 있어, 스킬이 무분별하게 섞이는 문제를 줄일 수 있었어요.

4. 선행 조건과 배타 선택 구조 추가하기
스킬트리는 단순히 가격만 지불하는 목록이 아니라, 플레이어가 성장 방향을 선택하는 구조여야 한다고 생각했어요.
그래서 노드마다 선행 조건을 둘 수 있도록 했어요.
- All: 모든 선행 노드를 해금해야 다음 노드 공개
- Any: 여러 선행 노드 중 하나만 해금해도 다음 노드 공개
- exclusiveGroup: 같은 그룹 안에서는 하나를 선택하면 다른 선택지를 잠그는 배타 분기
이를 통해 “노드 생성 강화 중심”, “매대 운영 중심”, “손님 보상 중심”처럼 플레이어가 원하는 방향으로 빌드를 구성할 수 있게 만들고 있어요.
5. CSV 기반 밸런스 관리 연결하기
스킬 수치와 가격은 자주 조정해야 하는 데이터에요.
그래서 스킬 이름, 설명, 스탯 변수, 최대 레벨, 레벨당 수치, 가격, 선행 조건 등을 CSV로도 정리해 관리하고 있어요.
기획 단계에서는 CSV를 통해 전체 밸런스를 빠르게 검토하고, Unity에서는 이를 기준으로 SkillNodeData 에셋을 구성하는 흐름을 사용하고 있어요.
특히 설명문 안의 {v} 표기처럼, 레벨당 수치를 자동으로 표시하는 방식도 적용했어요. 수치를 바꾸더라도 설명과 실제 효과가 서로 어긋날 가능성을 줄이기 위한 장치예요.

고민한 부분
1. TargetStat enum의 안정성
Unity의 ScriptableObject는 enum 이름이 아니라 내부 정수값을 저장해요.
따라서 enum 중간에 항목을 추가하거나 순서를 바꾸면, 기존 스킬 노드가 다른 스탯을 가리키는 문제가 생길 수 있어요.
이를 방지하기 위해 Q0~Q3별로 번호 영역을 나누고, 한 번 배정한 번호는 변경하거나 재사용하지 않는 규칙을 만들어요.
- Q0: 1~19
- Q1: 21~39
- Q2: 41~59
- Q3: 61~79
이 규칙은 눈에 바로 드러나는 기능은 아니지만, 스킬이 많아질수록 반드시 필요한 데이터 안정성 장치라고 판단했어요.
2. “스킬”이라는 하나의 이름 안에 담기는 서로 다른 역할
초기에는 모든 효과를 같은 방식으로 구현하려 했지만, 실제 게임에서는 단순 수치 상승과 게임 규칙 변경의 성격이 많이 달랐어요.
그래서 현재는 스킬트리라는 공통 UI와 데이터 구조는 유지하되, 내부 적용 방식은 수치형과 특수형으로 나누었습니다. 이 구조가 앞으로 새로운 아이디어를 추가할 때도 가장 유연하게 대응할 수 있을 것으로 보고 있어요.
다음 작업
다음 단계에서는 다음 작업을 진행할 예정이에요.
- Q0~Q3별 스킬 구현 상태 점검
- 아직 연결되지 않은 TargetStat과 실제 게임 시스템 연결
- 스킬 해금·레벨 정보 저장 및 불러오기 안정화
- 스킬트리 UI의 설명 박스와 가격 표시 개선
- 실제 플레이 데이터를 바탕으로 한 가격·수치 밸런스 조정
카드 시스템에서 시작한 구조가 이제는 플레이어의 운영 방향을 결정하는 스킬트리로 발전하고 있어요.
앞으로는 “어떤 스킬이 재미있는가”뿐 아니라 “어떤 조합이 새로운 플레이를 만드는가”를 중심으로 계속 다듬어 볼 예정이에요.

'Project > 우주적 베이글샵' 카테고리의 다른 글
| 인크리멘털 게임 스킬트리 재설계 - 103개 노드와 베이글형 구조 [우주적 베이글샵 개발일지 #05] (0) | 2026.09.20 |
|---|---|
| 인크리멘털 게임에 스토리를 넣었더니 장르가 흔들렸다 — 3개 모드로 푼 이유 | 우주적 베이글샵 개발일지 #04 (0) | 2026.09.16 |
| <우주적 베이글샵> - 우주를 유랑하며 베이글을 판매하는 성장형 퍼즐 게임, 4월부터 지금까지의 일대기 (0) | 2026.07.18 |
| [우주적 베이글샵 개발일지 #03] 게임 메인 화면 UI 디자인 — '예쁜 화면'과 '읽기 쉬운 화면' 사이에서 (1) | 2026.07.07 |
| [우주적 베이글샵 개발일지 #02] 유니티 스킬 카드 시스템 1차안 — 추상 클래스 + ScriptableObject + UI로 푼 구조 (0) | 2026.05.29 |