[Unity] SerializeReference
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
튜토리얼 22단계를 데이터로 만들려는데 단계마다 "완료 조건"이 다 다르다. 타워 3개 놓기, 2초 기다리기, 건물 업그레이드하기 등이 있어서 추상 클래스로 만들고 싶었다.
[SerializeField] private TutorialCondition completion; // 안 된다
Unity 기본 직렬화는 다형성을 담지 못한다. 추상 클래스라서 안 되고, 구체 클래스여도 값 복사라서 파생 타입 정보가 날아간다. 우회책 둘 다 별로였다. 조건마다 ScriptableObject로 만들면 .asset 파일이 조건 수만큼 늘어난다. enum + switch로 하면 모든 조건의 필드가 한 클래스에 몰려서 Delay를 골랐는데 인스펙터에 Target Tower 칸이 보인다.
값이 아니라 참조로 저장하고, 타입 이름을 같이 적어둔다.
[SerializeReference]
private TutorialCondition completion;
인스펙터에 드롭다운이 뜨고, 고른 타입의 인스턴스가 스텝 에셋 안에 직접 저장된다. 별도 파일이 안 생긴다.
얻은 것 1 — 진행부가 조건을 모른다. 컨트롤러가 하는 일은 이게 전부다.
_active.Satisfied += OnConditionSatisfied;
_active.Begin(_context);
새 조건 추가 = 클래스 파일 하나 추가. 지금 조건이 14개인데 컨트롤러는 처음 그대로다.
얻은 것 2 — 조건마다 자기 필드만 갖는다. TowerPlacedCondition은 count와 targetTower만, DelayCondition은 seconds와 ignoreGameSpeed만. [Min], [Tooltip] 같은 어트리뷰트도 그대로 먹는다.
1. 클래스 이름이 곧 데이터 키다. rename 하면 저장된 데이터가 깨진다. 그래서 조건 파일 13개 전부 첫 줄에 경고를 박아뒀다.
// ⚠ 클래스 이름을 바꾸면 [SerializeReference]로 저장된 기존 스텝 데이터가 깨진다.
2. 삭제하면 null로 남는다. 컴파일 에러가 아니라 조용한 런타임 null이다. 리스트 순회할 땐 null 검사가 필수.
3. 인스턴스가 에셋에 눌러앉는다 → 상태가 남는다. MonoBehaviour와 달리 플레이를 껐다 켜도 같은 객체라서, private 필드에 지난 판 값이 그대로 있다.
public override void Begin(TutorialContext context)
{
// 조건 객체는 에셋에 저장되므로 이전 플레이의 값이 남아 있다 — 반드시 여기서 다시 잡는다.
_baseline = CountMatching();
4. GameObject 수명에 안 묶인다. 아무도 정리해주지 않는다. DelayCondition이 CancellationTokenSource를 직접 들고 End()에서 끊는 이유 — 안 끊으면 이미 지나간 단계의 완료 신호가 뒤늦게 날아온다.
[SerializeReference]의 진짜 비용은 Begin**/**End 짝 맞추기 규율이다. MonoBehaviour가 공짜로 해주던 초기화와 정리를 손으로 해야 한다. 그 대가로 파일 폭발도 거대한 switch도 없는 데이터 주도 확장을 얻는다.
![[Unity] 튜토리얼 설계](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1787322579554-zopplu/_____2026-08-21_232731.png)
튜토리얼 설계
![[Unity] Event Trigger Component](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1786976296699-a3tu75/_____2026-08-17_231353.png)
Unity Event Trigger 컴포넌트

에픽게임즈에서 지원하는 EOS에 대해 알아보았다.
![[Unity] 튜토리얼 설계](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1787322579554-zopplu/_____2026-08-21_232731.png)
![[Unity] Event Trigger Component](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1786976296699-a3tu75/_____2026-08-17_231353.png)