[Unity] 타워 디펜스에 "타워 합성" 시스템 만들기
뭘 만들었나
그리드 타워 디펜스에 타워 합성을 넣었다. 같은 타워를 계속 까는 대신, 이미 설치한 타워 몇 개를 재료로 상위 타워를 만드는 성장 축이다.
예: 아처 타워 2개 + 캐논 1개 → 스나이퍼 타워
구현은 크게 두 부분으로 나눴다.
- 데이터 구조 — 어떤 재료로 어떤 결과가 나오는지 정의하는 "레시피"
- 실행 로직 — 버튼을 누르면 재료를 없애고 비용을 지불하고 결과 타워를 배치
설계에서 정한 3가지
① 결과 타워는 특별한 타입이 아니라 그냥 일반 타워다
합성 결과라고 새 클래스를 만들면 배치·전투 코드마다 "합성 타워냐 아니냐" 분기가 번진다. 그래서 결과도 평범한 TowerAsset(기존 타워 데이터)으로 두고, 기존 배치 파이프라인을 그대로 태웠다.
② 레시피는 ScriptableObject로
CSV 테이블도 고려했지만, 레시피는 "타워 SO를 참조"하는 구조라 CSV의 ID 문자열보다 인스펙터에서 직접 드래그하는 게 자연스럽다.
public class TowerRecipe : ScriptableObject
{
public List<MaterialEntry> Materials; // 재료 타워 + 개수
public TowerAsset Result; // 결과 타워
public List<CostEntry> ExtraCost; // 추가 비용
}
③ 매칭 로직은 순수 함수로 뽑았다
"선택한 타워들로 이 레시피가 되나?"를 판단하는 부분을 씬·MonoBehaviour에 의존하지 않는 순수 함수로 분리했다. 덕분에 GameObject 없이 테스트할 수 있다. 매칭 규칙은 포함 매칭 — 필요 개수 이상이면 성립하고, 여분은 남긴다.
겪은 버그 2개
1. 타워를 놨는데 공격을 안 한다
합성 결과 스나이퍼를 배치했는데 가만히 있었다. 처음엔 "낮이라 그런가?"(타워는 밤에만 공격) 했는데, 진짜 원인은 따로 있었다.
스나이퍼 프리팹만 데이터(SO) 참조가 비어 있었다. 다른 타워는 다 연결돼 있는데 이것만 누락. 데이터가 없으니 공격 스탯을 못 읽어서 조용히 안 쐈던 것.
→ 프리팹에 SO 연결.
2. 재료가 사라진 자리에 타워를 못 놓는다
합성으로 재료 타워를 없앴는데, 그 타일에 다시 배치가 안 됐다. 배치할 때 타일을 "점유됨"으로 잠그는데, 타워가 파괴돼도 그 잠금이 안 풀렸다. 타워가 자기가 어느 타일을 점유했는지 기억하지 않아서다.
→ 배치된 타워에 점유 타일을 기록하는 컴포넌트를 붙이고, 파괴될 때(OnDestroy) 잠금을 풀게 했다. 합성 소모든 나중의 철거든 공통으로 동작한다.


![[Unity] PC 세이브 데이터 Android로 옮기기](https://data.develog.develrocket.com/upload/develog/muchan/1792206352286-hd4xz4/_____2026-10-17_114953.png)
![[Unity] 제네릭 박싱 예방](https://data.develog.develrocket.com/upload/develog/gmumdev/1792123312021-bhxx2i/_____.png)