유니티에서 캐릭터를 움직이고 점수를 올리고 적을 등장시키는 일은 모두 C# 스크립트가 맡습니다. 스크립트는 처음 보면 낯설지만 정해진 틀이 있어서, 그 틀만 이해하면 읽고 고치는 일이 훨씬 쉬워집니다. 이 글은 유니티 스크립트의 기본 구조와 자주 쓰는 문법을 정리합니다.
스크립트 파일의 기본 구조
Project 창에서 C# 스크립트를 새로 만들면 클래스 하나가 들어 있는 파일이 생깁니다. 이 클래스는 MonoBehaviour라는 유니티 기본 클래스를 이어받습니다. 상속이라고 부르는 이 구조 덕분에 스크립트를 게임 오브젝트에 컴포넌트로 붙일 수 있습니다.
주의할 점은 파일 이름과 클래스 이름이 같아야 한다는 것입니다. 파일 이름만 바꾸고 안의 클래스 이름을 그대로 두면 컴포넌트로 붙일 때 오류가 납니다.
생명주기 함수: 언제 실행되는가
유니티는 정해진 시점에 정해진 이름의 함수를 자동으로 불러 줍니다. 이를 생명주기 함수 또는 이벤트 함수라고 합니다.
| 함수 | 실행 시점 | 주로 하는 일 |
|---|---|---|
| Awake | 오브젝트가 만들어질 때 한 번 | 자기 자신의 변수 초기화 |
| Start | 첫 프레임 직전에 한 번 | 다른 오브젝트를 찾아 연결 |
| Update | 매 프레임마다 | 입력 확인, 일반적인 움직임 |
| FixedUpdate | 일정한 물리 계산 주기마다 | Rigidbody에 힘을 주는 물리 처리 |
| LateUpdate | 모든 Update가 끝난 뒤 | 캐릭터를 따라가는 카메라 이동 |
Update는 기기 성능에 따라 1초에 실행되는 횟수가 다릅니다. 그래서 이동 거리에 Time.deltaTime(직전 프레임에서 걸린 시간)을 곱해 어느 기기에서나 같은 속도로 움직이게 만듭니다.
변수와 인스펙터 연결
클래스 안에 public으로 선언한 변수나 [SerializeField]를 붙인 private 변수는 인스펙터 창에 나타납니다. 이동 속도나 체력 같은 값을 코드를 고치지 않고 에디터에서 바로 조절할 수 있어 테스트가 편해집니다.
외부에서 마음대로 바꾸면 안 되는 값은 private에 [SerializeField]를 붙이는 방식이 권장됩니다. 인스펙터에서는 보이되 다른 스크립트가 함부로 건드리지 못하게 막을 수 있기 때문입니다.
다른 컴포넌트와 오브젝트 다루기
- GetComponent: 같은 오브젝트에 붙은 다른 컴포넌트를 가져옵니다. 예를 들어 Rigidbody를 가져와 속도를 바꿀 때 씁니다.
- Instantiate: 프리팹을 복제해 새 오브젝트를 만듭니다. 총알 발사나 적 생성에 씁니다.
- Destroy: 오브젝트를 없앱니다. 맞은 적이나 수명이 다한 총알을 지울 때 씁니다.
- OnCollisionEnter, OnTriggerEnter: 다른 오브젝트와 부딪히거나 범위 안에 들어왔을 때 자동으로 불립니다.
- 코루틴(Coroutine): 몇 초 기다렸다가 실행하는 것처럼 시간에 걸쳐 일어나는 동작을 쉽게 만듭니다.
GetComponent는 매 프레임 부르기보다 Awake나 Start에서 한 번 가져와 변수에 저장해 두는 것이 좋습니다. 같은 일을 반복하지 않아 성능에도 유리합니다.
초보가 자주 하는 실수
- 스크립트를 만들고 오브젝트에 붙이지 않아 아무 일도 일어나지 않음
- 인스펙터에서 변수에 대상을 연결하지 않아 NullReferenceException 오류 발생
- Rigidbody가 있는 오브젝트를 transform으로 직접 옮겨 물리가 어색해짐
- 콘솔 창의 경고와 오류 메시지를 읽지 않고 넘어감
콘솔 창 오류 메시지를 두 번 누르면 문제가 난 코드 줄로 바로 이동합니다. 오류를 읽는 습관이 실력을 가장 빨리 늘려 줍니다.
C#을 탄탄하게 다지려면
SBS아카데미게임학원 유니티3D(Unity) 과정에는 클래스, 캡슐화, 상속, 인터페이스, 델리게이트, 컬렉션, LINQ 등 C# 문법을 따로 다루는 단계가 있어 스크립트 기초를 엔진 실습 전에 정리할 수 있습니다.
자주 묻는 질문
C# 대신 다른 언어로 유니티를 쓸 수 있나요?
현재 유니티의 기본 스크립트 언어는 C#입니다. 코딩 없이 노드를 연결하는 비주얼 스크립팅 기능도 있지만, 실무에서는 대부분 C#을 씁니다.
C언어를 먼저 배워야 하나요?
꼭 그렇지는 않습니다. 다만 C언어로 메모리와 포인터 개념을 익혀 두면 이후 C++이나 엔진 내부 구조를 이해할 때 도움이 됩니다.
Update와 FixedUpdate 중 무엇을 써야 하나요?
키 입력 확인은 Update, Rigidbody에 힘을 주는 물리 처리는 FixedUpdate에서 하는 것이 기본 원칙입니다.
