
유니티 개발자 면접에서는 "이 기능을 어떻게 구현했는가"보다 "왜 그렇게 구현했는가"를 자주 묻습니다. 수업에서는 같은 기능을 두세 가지 방식으로 만들어 보고…
모노비헤이비어와 무엇이 다를까
평소 쓰는 스크립트는 대부분 MonoBehaviour를 상속해 게임 오브젝트에 붙입니다. 오브젝트가 장면에 있어야 존재하고, 오브젝트마다 값을 따로 가집니다. 같은 슬라임을 열 마리 배치하면 체력, 공격력 같은 값도 열 벌이 생깁니다.
스크립터블 오브젝트는 ScriptableObject를 상속하고, 장면이 아니라 프로젝트 폴더에 에셋 파일로 존재합니다. 슬라임 데이터 파일 하나를 만들고 열 마리가 모두 그 파일을 참조하게 하면, 값은 한 벌만 있고 수정도 한 곳에서 끝납니다. 요리책 한 권을 주방 전체가 함께 보는 것과 비슷합니다.
| 기준 | MonoBehaviour | ScriptableObject |
|---|---|---|
| 존재하는 곳 | 장면 속 게임 오브젝트 | 프로젝트의 에셋 파일 |
| 값의 개수 | 오브젝트마다 따로 | 참조하는 쪽이 공유 |
| 주로 맡는 일 | 움직임, 충돌 같은 동작 | 설정값, 정적 데이터 |
| 수정하는 곳 | 장면의 인스펙터 | 에셋 파일의 인스펙터 |
만드는 순서: 클래스 작성부터 에셋 생성까지
- ScriptableObject를 상속하는 클래스를 만들고, 이름·체력·이동 속도 같은 필드를 선언합니다.
- 클래스 위에 CreateAssetMenu 속성을 달아 메뉴 이름과 기본 파일 이름을 지정합니다.
- 프로젝트 창에서 오른쪽 클릭해 Create 메뉴로 들어가면 지정한 이름의 항목이 생깁니다.
- 항목을 눌러 데이터 에셋을 만들고 인스펙터에서 값을 채웁니다.
- 몬스터 스크립트에 이 클래스 형식의 필드를 만들고, 인스펙터에서 에셋을 끌어 넣어 연결합니다.
이제 몬스터 스크립트는 자기 안에 수치를 들고 있지 않고, 연결된 데이터 에셋에서 값을 읽어 씁니다. 슬라임, 고블린, 늑대 데이터 에셋을 각각 만들어 두면 같은 몬스터 프리팹 하나에 데이터만 바꿔 끼워 여러 종류를 만들 수 있습니다.
필드에는 숫자뿐 아니라 스프라이트, 사운드, 프리팹 같은 다른 에셋 참조도 넣을 수 있습니다. 아이템 데이터라면 이름과 가격 옆에 아이콘 이미지와 획득 효과음까지 한 파일에 모아 둘 수 있어 관리가 편해집니다.
데이터 에셋 이름도 규칙을 정해 두면 좋습니다. 'Item_Sword_01', 'Monster_Slime'처럼 종류를 앞에 붙이면 프로젝트 창 검색에서 바로 찾을 수 있고, 폴더도 종류별로 나눠 두면 데이터가 백 개를 넘어도 헤매지 않습니다.
게임에서 자주 쓰는 활용 예
가장 흔한 쓰임은 데이터 테이블입니다. 아이템, 무기, 스킬, 몬스터, 스테이지 설정처럼 종류가 많고 형식이 같은 데이터를 파일 단위로 나눠 관리합니다. 기획자가 밸런스를 조정할 때 프로그래머에게 코드 수정을 부탁하지 않아도 되므로 협업 속도가 빨라집니다.
게임 전체 설정을 담는 용도로도 씁니다. 난이도별 배율, 사운드 기본 볼륨, 카메라 흔들림 세기 같은 값을 설정 에셋 하나에 모아 두면, 여러 스크립트가 같은 값을 참조해 일관성이 유지됩니다. 테스트용 설정과 출시용 설정을 별도 에셋으로 만들어 바꿔 끼우는 방법도 있습니다.
조금 더 나아가면 이벤트 채널로 쓰는 방식도 있습니다. '플레이어가 죽었다' 같은 이벤트를 스크립터블 오브젝트로 만들고, 알리는 쪽과 듣는 쪽이 모두 이 에셋만 참조하게 하는 구조입니다. 서로를 직접 알 필요가 없어져 스크립트 사이의 얽힘이 줄어듭니다. 다만 처음 배우는 단계에서는 데이터 그릇 용도부터 충분히 익힌 뒤 시도하는 편이 좋습니다.
가장 많이 헷갈리는 부분: 플레이 중 값 변경
에디터에서 플레이하는 동안 코드로 스크립터블 오브젝트의 값을 바꾸면, 플레이를 멈춰도 그 값이 에셋에 남아 있는 경우가 많습니다. 일반 오브젝트는 플레이를 멈추면 원래 값으로 돌아오기 때문에, 이 차이를 모르면 '체력 기본값이 왜 0이 됐지' 같은 당황스러운 일을 겪습니다.
반대로 빌드한 게임에서는 실행 중 바꾼 값이 파일로 저장되지 않습니다. 게임을 껐다 켜면 처음 값으로 돌아갑니다. 그래서 스크립터블 오브젝트는 세이브 데이터 저장 용도로 쓰면 안 됩니다. 진행 상황 저장은 파일이나 별도 저장 시스템으로 따로 처리해야 합니다.
안전한 원칙은 '스크립터블 오브젝트는 읽기 전용 원본으로 다룬다'입니다. 몬스터의 현재 체력처럼 플레이 중 변하는 값은 몬스터 스크립트 안의 변수로 복사해 쓰고, 원본 데이터 에셋은 건드리지 않습니다. 이 원칙만 지키면 대부분의 문제가 사라집니다.
처음 도입할 때의 점검 목록
- 여러 오브젝트가 같은 값을 쓰는 데이터인지, 오브젝트마다 달라지는 상태인지 구분했는가
- 플레이 중 변하는 값을 원본 에셋에 직접 쓰고 있지 않은가
- 데이터 에셋 폴더와 이름 규칙을 정해 두었는가
- 필드 이름을 바꾸기 전에 이미 입력된 값이 사라질 수 있다는 점을 확인했는가
마지막 항목은 실제로 자주 겪는 사고입니다. 필드 이름을 바꾸면 기존 에셋에 저장된 값이 연결을 잃어 비어 버릴 수 있습니다. 데이터가 많이 쌓인 뒤라면 이름 변경 전에 백업하거나, 이전 이름을 기억하게 하는 속성을 함께 쓰는 방법을 찾아보세요.
연습 과제로는 상점 아이템 다섯 개를 스크립터블 오브젝트로 만들고, 상점 UI가 이 목록을 읽어 버튼을 자동으로 만들게 해 보는 것을 추천합니다. 데이터와 화면이 분리되는 감각을 바로 느낄 수 있습니다. 내 프로젝트에서 어떤 데이터를 에셋으로 떼어 내야 할지 판단이 서지 않는다면, SBS아카데미게임학원 유니티3D(Unity) 과정 상담에서 코드 구조를 함께 들여다보며 분리 기준을 잡아 보시길 권합니다.
자주 묻는 질문
엑셀로 관리하던 데이터를 스크립터블 오브젝트로 옮길 수 있나요?
가능합니다. CSV로 내보낸 표를 읽어 에셋을 자동으로 만드는 에디터 스크립트를 작성하는 방식이 많이 쓰입니다.
스크립터블 오브젝트 안에 함수를 넣어도 되나요?
넣을 수 있습니다. 데미지 계산처럼 데이터와 밀접한 간단한 함수는 함께 두기도 하지만, 상태를 바꾸는 로직은 원본 데이터 원칙과 충돌하지 않는지 살펴야 합니다.
가까운 캠퍼스에서 유니티 알아보기
사는 곳과 가까운 캠퍼스를 고르면 수업 내용, 오시는 길, 상담 신청을 한 번에 볼 수 있습니다.