첫 C# 스크립트
4강. 첫 C# 스크립트
1. 이번 강의에서 해결할 문제
Scene의 택배는 보이지만 움직이지 않습니다. MonoBehaviour를 연결하고 언제 한 번 초기화하며 언제 반복 동작할지 구분합니다.
2. 학습 목표
3. 핵심 개념
MonoBehaviour는 C# 클래스를 GameObject에 붙이는 Component로 사용할 수 있게 합니다. Start는 활성화 후 첫 Update 전에 한 번, Update는 활성 상태에서 프레임마다 호출됩니다. Unity가 호출하는 메시지이므로 이름과 매개변수 형태가 정확해야 합니다.
용어 정리
| 용어 | 무엇인가 | 언제 쓰는가 | 주의할 점 |
|---|---|---|---|
| C# 클래스 | 데이터와 동작을 한 이름 아래 정의한 코드 | 택배 이동 규칙처럼 재사용할 동작을 작성할 때 | 파일만 만들었다고 Scene에서 실행되지는 않습니다. |
| MonoBehaviour | C# 클래스를 Unity Component로 연결하는 기반 클래스 | GameObject 수명 주기와 Inspector가 필요할 때 | 직접 new PackageMover()로 만들지 않고 GameObject에 붙입니다. |
| Unity 메시지 | Unity가 정해진 시점에 호출하는 메서드 | Start, Update, OnTriggerEnter2D 등 | 철자와 매개변수 형태가 맞아야 합니다. |
| 프레임 | 화면과 게임 상태를 한 번 갱신하는 단위 | 부드러운 이동을 매번 조금씩 계산할 때 | PC마다 초당 프레임 수가 다를 수 있습니다. |
| Transform | 위치·회전·크기를 저장하는 기본 Component | GameObject를 이동하거나 회전할 때 | position은 World 좌표입니다. |
Start와 Update는 우리가 직접 호출하는 일반 함수가 아닙니다. GameObject가 활성화되고 스크립트가 enabled 상태일 때 Unity의 Player Loop가 호출합니다. 초기 로그나 다른 Component를 한 번 준비하는 작업은 Start, 매 프레임 위치를 조금씩 바꾸는 작업은 Update가 알맞습니다.
4. 단계별 실습
C# · 파일 경로: Assets/DeliverySorter/Scripts/Packages/PackageMover.cs
using UnityEngine;
public sealed class PackageMover : MonoBehaviour
{
private float speed = 2f;
private void Start()
{
Debug.Log($"PackageMover started: {name}", this);
}
private void Update()
{
transform.position += Vector3.down * speed * Time.deltaTime;
}
}
코드 한 줄씩 이해하기
using UnityEngine;은MonoBehaviour,Vector3,Time,Debug같은 Unity 타입을 짧은 이름으로 쓰게 합니다.: MonoBehaviour는 이 클래스를 Inspector에서 GameObject에 붙일 수 있는 Component로 만듭니다.speed = 2f는 초당 2 Unity 단위로 이동하겠다는 값입니다.f는 이 숫자를 C#의float값으로 취급합니다.Start의 로그는 Component가 실제 GameObject에 연결되었는지 한 번 확인합니다.this를 함께 넘겨 Console 항목을 클릭했을 때 해당 오브젝트를 찾게 합니다.Vector3.down은(0, -1, 0)방향입니다.speed * Time.deltaTime은 “초당 거리”를 “이번 프레임에 이동할 거리”로 바꿉니다.transform.position += ...는 기존 위치에 아래 방향 이동량을 더해 새 World 위치를 저장합니다.
예를 들어 speed가 2이고 한 프레임의 deltaTime이 약 0.02초라면 그 프레임에는 Y가 약 0.04 감소합니다. 프레임 수가 달라도 1초 동안 누적 이동은 대략 2단위가 됩니다.
Unity Editor·Inspector에서 연결
- Project 창에서 스크립트 컴파일이 끝날 때까지 기다립니다. Console에 빨간 컴파일 오류가 있으면 먼저 해결합니다.
- Hierarchy의
PackagePrototype을 선택하고 Inspector에서Add Component > Package Mover를 추가합니다. - Play를 누르면 Console에
PackageMover started: PackagePrototype이 한 번만 표시되는지 확인합니다. - Scene 또는 Game 창에서 택배의 Y 위치가 계속 작아지는지 확인합니다. 아직 충돌이나 화면 이탈 처리가 없으므로 계속 아래로 내려가는 것이 정상입니다.
5. 코드가 동작하는 이유
Unity가 매 프레임 Update를 호출하고, 스크립트가 붙은 GameObject의 Transform 위치를 아래 방향으로 바꿉니다. Time.deltaTime은 이전 프레임부터 지난 시간을 곱해 초당 속도로 해석하게 하며 7강에서 자세히 다룹니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
실습 목표
MonoBehaviour를 GameObject에 연결하고 Start와 Update의 호출 횟수 차이, 프레임 독립 이동, 조건에 따른 Component 정지를 확인합니다.
시작 전 상태
PackagePrototype 위치를 (0, 2, 0)으로 되돌리고 Package Mover가 하나만 붙었는지 확인합니다. Console을 Clear한 뒤 Play합니다.
1단계: 가장 작은 변경
Start에 Debug.Log($"Start Y: {transform.position.y}", this);를 추가합니다. Play할 때 한 번만 Start Y: 2에 가까운 값이 나오는지 확인합니다. Scene에 저장된 시작 위치에 따라 숫자는 달라질 수 있습니다.
2단계: 값을 바꾸고 결과 비교
speed를 2f와 5f로 각각 실행해 1초 뒤 Y 위치를 비교합니다. 정확한 프레임 수보다 5가 2보다 약 2.5배 빠르게 내려가는지를 봅니다. 값을 바꿀 때마다 Play를 정지하고 시작 위치를 되돌립니다.
3단계: 직접 적용
Update 마지막에 아래 조건을 추가해 Y가 -6 이하가 되면 이 Component만 멈추게 만드세요.
if (transform.position.y <= -6f)
{
enabled = false;
Debug.Log("PackageMover stopped at the lower boundary.", this);
}
enabled = false 뒤에는 Update가 더 호출되지 않으므로 로그도 한 번만 나와야 합니다. GameObject 자체를 파괴하거나 비활성화한 것은 아닙니다.
4단계: 스스로 확인
막혔을 때
| 증상 | 원인 | 해결 |
|---|---|---|
| 스크립트가 Add Component 검색에 없음 | 컴파일 오류 또는 파일명·클래스명 불일치 | Console의 첫 빨간 오류를 해결하고 두 이름을 PackageMover로 맞춥니다. |
| 로그는 나오지만 움직이지 않음 | speed가 0이거나 Component가 비활성 | Inspector의 체크박스와 speed 값을 확인합니다. |
| 두 배 속도로 움직임 | 같은 Component가 두 번 붙음 | Inspector에서 Package Mover가 하나인지 확인합니다. |
| 정지 조건을 넣어도 계속 이동 | 비교 방향이나 중괄호 위치 오류 | 현재 Y를 로그로 한 번 확인하고 <= -6f가 Update 안에 있는지 봅니다. |
8. 이해 점검 질문 3개
9. 핵심 요약
다음 강의 연결
다음 강의에서는 코드에 고정한 이동 속도와 Sprite Renderer 참조를 Inspector에서 안전하게 조정·연결하도록 바꿉니다.
첫 C# 스크립트 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.