[Unity] 본진 업그레이드 시스템
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
현재 프로젝트에서 본진 업그레이드 시스템을 도입했다. 다른 건물들마다 업그레이드할 수있는 Max 레벨이 있고 본진 업그레이드를 하면 그 건물의 Max 레벨을 늘리는 식으로 구현했다.
업그레이드 트랙 등록 코드가 Skill.UpgradeLevels를 하드코딩으로 읽고 있었다.
tables.Add(building.Skill?.UpgradeLevels ?? new List<BuildingAsset.SkillUpgradeLevel>());
본진은 BuildingType.Castle, 연금술사는 Store. 둘 다 Skill 필드 그룹이 비어 있어서 등록 자체가 안 됐다.
본진 업그레이드 효과를 두 가지로 정의했다.
본진이 하위 건물 목록을 갖는 대신, 각 건물의 레벨 행이 자기 해금 조건을 소유하도록 했다.
성장 속도는 요구 레벨 배열로 표현된다.
생산 건물 3종: [0, 0, 1, 1, 2, 2] → 본진 한 단계당 2레벨
마법 연구소: [0, 0, 0, 1, 2] → 처음 3레벨, 이후 단계당 1레벨
건물이 추가돼도 해당 건물 파일만 편집하면 되고, 레벨 행을 지우면 조건도 함께 사라진다.
레벨 클래스가 타입별로 따로 있었다(UpgradeLevel, SkillUpgradeLevel, ExchangeUpgradeLevel). 여기에 본진용 CastleUpgradeLevel을 추가하고, 넷의 공통 부모를 뽑았다.
public abstract class UpgradeStep
{
public List<ResourceCost> Cost; // 이 레벨 도달 비용
public int RequiredCastleLevel; // 열리는 데 필요한 본진 레벨 (0 = 처음부터)
}
건물 에셋에 타입 중립 창구를 만들었다. 분기 키는 BuildingType이 아니라 '데이터가 채워져 있는가'다.
public IReadOnlyList<UpgradeStep> UpgradeSteps
{
get
{
if (HasSteps(Castle?.UpgradeLevels)) return Castle.UpgradeLevels;
if (HasSteps(Skill?.UpgradeLevels)) return Skill.UpgradeLevels;
if (HasSteps(Production?.UpgradeLevels)) return Production.UpgradeLevels;
if (HasSteps(Exchange?.UpgradeLevels)) return Exchange.UpgradeLevels;
return Array.Empty<UpgradeStep>();
}
}
컨트롤러는 한 줄만 바꿨다.
- tables.Add(building.Skill?.UpgradeLevels ?? new List<SkillUpgradeLevel>());
+ tables.Add(building.UpgradeSteps);
효과값(생산량, 스킬 배율, 교환 배율)은 각 소비 시스템이 자기 필드 그룹에서 직접 읽는다. 컨트롤러는 비용과 해금 조건만 알면 되므로 부모 클래스 필드는 둘뿐이다.
마이그레이션 불필요 — Cost를 자식에서 부모로 올렸지만, Unity는 상속된 직렬화 필드를 같은 이름으로 평탄하게 저장하기 때문에 기존 에셋 YAML의 Cost: 위치가 그대로였다. 전 건물 에셋 덤프로 확인.
기존은 행 개수 = 최대 레벨이었다.
public int LineMaxLevel(int index) => _lineUpgradeLevels[index].Count;
이를 "현재 본진 레벨로 열려 있는 만큼"으로 바꿨다.
private int EffectiveMaxLevel(IReadOnlyList<UpgradeStep> levels, bool ignoreGate = false)
{
if (ignoreGate) return levels.Count;
int castle = CastleLevel;
for (int i = 0; i < levels.Count; i++)
{
if (levels[i] == null || levels[i].RequiredCastleLevel > castle) return i;
}
return levels.Count;
}
앞에서부터 훑다가 조건을 못 넘는 행에서 멈춘다(잠긴 행 뒤는 살리지 않음 — 레벨은 순차적으로 오르므로). 본진 자신은 게이팅에서 제외(ignoreGate)해 자기 조건에 의한 데드락을 방지한다.
비용 조회, 업그레이드 가능 판정, 버튼 활성화 모두 levels.Count 대신 이 함수를 부르게 바꾸는 것으로 완료.
![[Unity] 렌더 큐](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1785158340538-3i4lkp/_____2026-07-27_215606.png)
유니티 렌더 큐
타워 디펜스에 타워 합성 시스템 구현
![[Unity] 피벗은 뭐고 앵커는 머요](https://data.develog.develrocket.com/upload/develog/user_1776858831954/1784966048688-1uin6m/image.png)
네모들의 위치를 피벗과 앵커로 설명하시오
![[Unity] 렌더 큐](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1785158340538-3i4lkp/_____2026-07-27_215606.png)
![[Unity] 피벗은 뭐고 앵커는 머요](https://data.develog.develrocket.com/upload/develog/user_1776858831954/1784966048688-1uin6m/image.png)