Week 03 / Period 01 / Script reading

C# 기초 문법과 스크립트 구조

코드가 어떤 값을 저장하고, 어떤 조건에서 어떤 동작을 실행하는지 순서대로 읽습니다.

60분 / Cursor 설치·연결 / C# 기초 / AI 설명 검증

왼쪽의 코드 구조가 가운데 컴포넌트 설정을 거쳐 오른쪽 2D 오브젝트의 연속 위치 변화로 이어지는 장면
스크립트에 정의한 코드를 게임오브젝트의 컴포넌트로 사용합니다.
이 페이지에서
핵심 질문
코드는 어떤 값을 저장하고, 어떤 조건에서 실행되는가?
학습 방식
한 파일을 수정하며 AI 설명과 실행 결과 비교
이전 학습
게임오브젝트 · 컴포넌트 · Transform
핵심 개념
필드 · 자료형 · 메서드 · 조건문
작업 프로젝트
GameEngine1
다음 교시
Unity가 코드를 실행하는 방식
학습 목표 값 저장, 메서드 호출, 조건에 따른 실행을 구분하기

2주차에는 게임오브젝트(GameObject)에 여러 컴포넌트(Component)를 추가해 기능을 구성했습니다. Sprite Renderer가 모습을 표시하듯, 스크립트로 만든 컴포넌트는 값을 저장하고 조건에 따라 동작을 실행합니다. 이번 교시에는 MotionController.cs 파일 하나를 단계별로 수정합니다. Console에 이름을 출력하고, 속도 변수를 추가한 뒤, 출력 코드를 메서드로 묶고 조건에 따라 메시지를 출력합니다. 마지막으로 AI의 설명과 실행 결과를 비교합니다. 2교시에는 이 파일에 실제 움직임을 추가합니다.

  1. 01Cursor 설치와 첫 실행

    설치 파일을 다운로드하고, 설치 후 Cursor를 실행하여 로그인합니다.

  2. 02스크립트 이해와 편집기 연결

    파일과 컴포넌트의 관계를 이해하고, Cursor를 Unity에 연결합니다.

  3. 03스크립트 생성과 Console

    스크립트를 게임오브젝트에 추가하고 Debug.Log로 실행을 확인합니다.

  4. 04변수와 자료형

    속도를 저장할 필드를 선언하고 값을 Console에 출력합니다.

  5. 05메서드 정의와 호출

    출력 두 줄을 메서드로 묶고 Start에서 호출합니다.

  6. 06조건문과 전체 코드

    조건에 따라 메시지를 출력하고 AI의 설명과 실행 결과를 비교합니다.

Cursor를 설치하고 실행합니다

코드를 작성할 공통 편집기를 준비합니다. 사용 중인 컴퓨터의 운영체제에 맞는 설치 절차를 따릅니다. Cursor가 이미 설치된 경우 실행과 로그인을 확인한 뒤 C#·Unity 연결을 점검합니다.

  1. 운영체제에 맞는 설치 파일 다운로드

    Cursor 공식 다운로드 페이지 ↗에서 데스크톱 앱의 설치 파일을 다운로드합니다.

    Windows: 설정의 시스템 → 정보 → 시스템 종류를 확인합니다. x64이면 Windows (x64) (User), ARM64이면 Windows (ARM64) (User)를 선택합니다.

    macOS: Apple 메뉴의 이 Mac에 관하여에서 칩을 확인합니다. Apple M 계열이면 Mac (ARM64), Intel이면 Mac (x64)를 선택합니다. Mac Universal은 두 종류를 모두 지원합니다.

    다운로드 확인다운로드 폴더에서 Windows용 .exe 또는 macOS용 .dmg 설치 파일을 확인합니다.
  2. Cursor 설치 및 실행

    Windows: 다운로드한 .exe를 더블클릭합니다. 설치 안내에 따라 설치 위치 등 기본 설정을 확인하고 설치를 완료합니다. 시작 메뉴에서 Cursor를 실행합니다.

    macOS: 다운로드한 .dmg를 열고 Cursor 아이콘을 Applications(응용 프로그램) 폴더로 드래그합니다. 복사가 완료되면 응용 프로그램 폴더에서 Cursor를 실행합니다.

    완료 기준설치 파일 창을 닫은 상태에서도 시작 메뉴나 응용 프로그램 폴더에서 Cursor를 실행할 수 있습니다.
  3. 초기 설정 및 로그인

    최초 실행 시 안내에 따라 Cursor 계정으로 로그인합니다. 계정이 없는 경우 가입 후 로그인합니다. 브라우저 인증을 완료한 경우 Cursor로 전환합니다. 키보드 단축키와 테마 등 초기 설정은 기본값을 사용할 수 있습니다.

    Cursor에서 File → Open Folder 메뉴의 위치를 확인합니다. 다음 연결 단계에서는 이 메뉴로 기존 Unity 프로젝트인 GameEngine1 폴더를 엽니다.

    설치 완료Cursor 실행과 로그인이 완료되어 프로젝트 폴더를 열 수 있는 상태입니다.

공식 설치 안내 ↗에서 설치 과정을 다시 확인할 수 있습니다. 다음으로 스크립트와 컴포넌트의 관계를 확인하고, C# 확장과 Unity 외부 편집기 설정을 진행합니다.

스크립트로 게임오브젝트의 동작을 정의합니다

2주차의 Player에서 Transform은 위치를 저장하고 Sprite Renderer는 모습을 표시했습니다. 이번에는 Player에 직접 작성한 코드를 실행하는 컴포넌트를 추가합니다.

01스크립트 파일

Project 창에서 .cs 파일을 생성하고 Cursor에서 코드를 작성합니다.

02컴포넌트 추가

스크립트를 게임오브젝트에 추가해 컴포넌트로 사용합니다.

03인스턴스 생성

각 컴포넌트는 같은 코드를 사용하면서도 서로 다른 값을 저장할 수 있습니다.

04코드 실행

Play를 누르면 Unity가 Start를 호출해 시작 코드를 실행합니다.

2주차에는 Collectible.prefab 하나를 여러 번 배치했습니다. 같은 방식으로 MotionController.cs 하나를 게임오브젝트 세 개에 각각 추가할 수 있습니다. 이때 각각 생성된 컴포넌트를 인스턴스(instance)라고 합니다. 파일은 하나이고 컴포넌트 인스턴스는 세 개입니다. 각 인스턴스의 속도 값은 다르게 설정할 수 있습니다. 이번 실습은 Player 하나로 진행합니다.

MotionController.cs 설계서 하나에서 게임오브젝트 세 개에 추가된 동일한 제어 모듈로 연결되며, 각 모듈의 moveSpeed 값은 2, 5, 8로 다른 모습
같은 설계서로 만든 장치도 설정은 서로 다를 수 있습니다. 스크립트도 코드는 공유하지만, 각 컴포넌트에 저장한 속도 값은 다를 수 있습니다.
작성과 실행 Cursor에서 코드를 작성하고, Unity에서 게임오브젝트에 스크립트를 추가해 실행합니다. 이번 실습의 출력 코드는 Start에서 시작합니다.

코드는 Cursor에서 작성하고 Unity에서 실행합니다

이번 수업의 공통 편집기는 Cursor입니다. Cursor에서 C# 파일을 수정해 저장하면 Unity가 컴파일합니다. 컴파일 오류가 없는지 확인한 뒤 Play 버튼을 눌러 실행합니다. 편집기, AI 코딩 도구, Unity의 역할을 먼저 구분합니다.

  • Cursor · 작성Unity 프로젝트 폴더를 열고 C# 코드를 수정합니다. C# 확장의 자동완성과 오류 표시 기능을 사용하고, AI가 제안한 코드의 변경 전후를 비교합니다.
  • AI 도구 · 설명과 수정 보조Codex, Claude Code, Gemini CLI 중 하나를 연결합니다. 이번 교시 마지막에 코드 설명을 요청하고, 2교시에는 메서드 하나의 작성을 요청합니다.
  • Unity · 실행과 관찰Console, Inspector, Game 뷰에서 결과를 확인합니다. 이번 예제는 Unity의 Play 버튼으로 실행합니다.

설치한 Cursor를 Unity에 연결합니다

  1. Cursor에 C# 확장 설치

    Cursor 설치와 첫 실행을 완료한 상태에서 진행합니다. Cursor의 Extensions를 열고 C#을 검색해 게시자가 Anysphere인 확장(anysphere.csharp)을 설치합니다. .NET 설치 안내가 표시되면 해당 절차를 따릅니다.

    확인Cursor의 C# 확장이 활성화되어 있어야 합니다. 확장은 Cursor의 Extensions에서 설치합니다. 공식 확장 안내 ↗
  2. Unity의 외부 편집기로 지정

    Unity에서 Windows는 Edit → Preferences, macOS는 Unity → Settings를 엽니다. External Tools → External Script Editor에서 Cursor를 선택합니다. 목록에 없으면 Browse…로 설치한 Cursor 앱을 지정합니다.

    선택할 앱Windows는 Cursor.exe, macOS는 Cursor.app을 선택합니다. 설치 위치는 각 컴퓨터에서 확인합니다.
  3. GameEngine1 프로젝트 폴더 열기

    Cursor의 File → Open Folder에서 Unity 프로젝트의 GameEngine1 폴더를 엽니다. 왼쪽 Explorer에 Assets, Packages, ProjectSettings가 모두 표시되는지 확인합니다. 다음 단계에서 생성할 Assets/Scripts/MotionController.cs를 이 폴더 안에서 편집합니다.

    완료 기준Unity에서 스크립트를 더블클릭하면 같은 프로젝트의 파일이 Cursor에서 열립니다.

첫 Debug.Log 실습에서 Debug. 뒤에 Log 자동완성 항목이 표시되는지 확인합니다. 저장 후 Unity Console에서 문법 오류 여부를 점검합니다. 실행 결과는 Unity의 Play Mode에서 확인합니다. Unity 외부 도구 설정 안내 ↗

파일은 열리지만 Unity 자동완성이 작동하지 않는 경우

Cursor에서 GameEngine1 프로젝트 폴더 전체를 열었는지 확인합니다. Unity의 External Tools에 Regenerate project files가 표시되면 실행하여 .sln과 .csproj를 갱신하고, Cursor 명령 팔레트에서 Developer: Reload Window를 실행합니다. Cursor 지원팀의 Unity 프로젝트 인식 안내 ↗

Cursor용 프로젝트 파일 생성 기능이 없다면 Cursor 연결 패키지를 사용할 수 있습니다. Unity 공식 패키지가 아닌 커뮤니티 패키지입니다. Package Manager의 + → Add package from git URL에서 https://github.com/boxqkrtm/com.unity.ide.cursor.git를 추가하고, External Script Editor를 Cursor로 다시 선택한 뒤 프로젝트 파일을 갱신합니다.

C# 스크립트를 생성하고 게임오브젝트에 추가합니다

2주차의 GameEngine1 프로젝트와 씬을 이어서 사용합니다. Play를 종료한 Edit Mode에서 준비합니다. 이번 실습은 Player 하나에 MotionController 컴포넌트를 하나 추가한 상태를 기준으로 로그 개수를 확인합니다.

  1. Assets/Scripts에 파일 생성

    Project 창에서 Assets/Scripts를 선택합니다. 폴더가 없는 경우 Assets 안에 Scripts 폴더를 생성합니다. 우클릭 메뉴의 Create → Scripting → MonoBehaviour Script를 선택하고 이름을 MotionController로 정합니다. 버전에 따라 C# Script로 표시될 수 있습니다. 동일한 파일이 이미 있는 경우 기존 파일을 엽니다.

    결과Project 창에 MotionController.cs 파일이 생성됩니다.
  2. 스크립트 기본 구조 확인

    파일을 더블클릭하여 연결된 Cursor에서 엽니다. 아래 코드와 같이 클래스(class) 이름이 MotionController인지 확인합니다. 파일 이름과 클래스 이름을 대소문자까지 일치시킵니다. 현재 Start와 Update의 중괄호 내부에는 코드가 없습니다.

    관찰점클래스는 값과 동작을 하나로 묶습니다. Start와 Update는 클래스 안의 함수인 메서드입니다.
  3. 게임오브젝트에 컴포넌트 추가

    Hierarchy에서 2주차의 Player를 선택합니다. Project의 MotionController.cs를 Player의 Inspector 빈 공간에 드래그합니다. MotionController가 이미 추가된 경우 중복으로 추가하지 않습니다. 씬을 저장합니다.

    결과Player의 Inspector에 MotionController 컴포넌트 하나가 표시됩니다.

Unity가 생성하는 기본 코드

실습은 아래 기본 코드에서 시작합니다. 자동 생성된 주석이나 private가 포함되어 있어도 동일하게 진행할 수 있습니다. 각 단계에서 코드를 추가할 위치와 교체할 범위를 안내합니다. 마지막에는 전체 코드와 비교하여 누락된 부분이 없는지 확인합니다.

MotionController.cs · 기본 템플릿
using UnityEngine;

public class MotionController : MonoBehaviour
{
    void Start()
    {
    }

    void Update()
    {
    }
}
  • using UnityEngine;MonoBehaviour, Debug 같은 Unity의 클래스 이름 앞에서 UnityEngine.을 생략할 수 있게 합니다.
  • public class MotionControllerMotionController라는 클래스를 정의합니다. 그 아래 중괄호 안에 변수와 메서드를 작성합니다.
  • : MonoBehaviourUnity의 MonoBehaviour를 상속한다는 뜻입니다. 이 클래스를 게임오브젝트의 컴포넌트로 사용할 수 있게 합니다.
  • Start() / Update()Unity가 호출하는 메서드입니다. 이번 예제에서 Start는 실행 시작 시 한 번 호출됩니다. Update의 반복 호출은 2교시에서 비교합니다.
파일이 표시되지 않거나 스크립트를 추가할 수 없는 경우

Project 검색어를 비우고 Assets/Scripts를 확인합니다. 편집기가 열리지 않으면 Edit → Preferences → External Tools에서 External Script Editor 연결을 확인합니다.

스크립트를 추가할 수 없다면 Console에 표시된 오류를 먼저 해결합니다. 파일 이름 MotionController.cs와 클래스 이름 MotionController가 같은지, 클래스가 MonoBehaviour를 상속하는지 확인합니다. 저장 후 Unity의 컴파일이 끝날 때까지 기다립니다.

첫 실습: Debug.Log로 실행을 확인합니다

추가한 스크립트의 실행 여부를 확인합니다. Debug.Log는 괄호 안의 내용을 Console에 출력하는 명령입니다. 먼저 이름이 포함된 메시지 한 줄을 출력하고, 이후 단계에서 예제를 확장합니다.

  1. Console 준비

    Window → General → Console을 엽니다. Clear로 이전 로그를 지우고, 같은 문장을 묶는 Collapse는 끕니다. 오른쪽 위의 로그 표시 토글을 켜고 검색어도 비웁니다.

    준비매번 실행 전에 Clear로 기존 로그를 지우고, 해당 실행에서 출력된 로그의 개수를 확인합니다.
  2. 기존 Start를 아래 코드로 교체

    MotionController.cs에서 빈 Start() 전체를 아래 코드로 교체합니다. Start를 중복으로 정의하지 않습니다. using, 클래스의 바깥 중괄호, 빈 Update()는 유지합니다. 파일을 저장한 뒤 Unity로 전환하여 컴파일 오류 여부를 확인합니다.

    작성 위치Debug.Log 한 줄은 Start의 중괄호 안에 작성합니다.
  3. 실행 후 이름 출력 확인

    Player와 MotionController가 활성화되어 있는지 확인하고 Play를 누릅니다. Console에 Player의 설정을 확인합니다.라는 메시지가 한 번 출력되는지 확인합니다. 다른 게임오브젝트에 추가한 경우 해당 게임오브젝트의 이름이 출력됩니다. 확인 후 Play를 종료합니다.

    예상 결과Player에서 메시지 한 줄이 출력되고 더 늘어나지 않습니다.
Start · 기존 메서드 교체
void Start()
{
    Debug.Log(name + "의 설정을 확인합니다.");
}
  • Debug.Log(...);괄호 안의 내용을 출력합니다. 줄 끝의 세미콜론(;)은 명령문이 끝났음을 표시합니다.
  • name이 컴포넌트가 추가된 게임오브젝트의 이름입니다.
  • +이 예제에서는 게임오브젝트의 이름과 따옴표 안의 문자열을 연결합니다.
로그가 출력되지 않거나 반복 출력되는 경우

메시지가 출력되지 않으면 Console 필터, 게임오브젝트와 컴포넌트의 활성화 상태, 스크립트 추가 여부를 확인합니다. 로그가 반복 출력되면 Debug.Log를 Update 안에 작성했는지 확인합니다. 실행 시작 시 같은 메시지가 여러 번 출력되면 MotionController를 추가한 게임오브젝트와 컴포넌트의 개수를 확인합니다. 로그를 더블클릭하면 출력한 코드 줄로 이동할 수 있습니다.

다음 단계 이름 출력에 이어 속도를 저장할 변수를 선언하고, 해당 값을 Console에 출력합니다.

변수에 값을 저장하고 이름으로 읽습니다

다음 교시에 사용할 속도를 moveSpeed라는 변수에 저장합니다. 클래스 안에서 메서드 밖에 선언한 변수를 필드(field)라고 합니다. 먼저 자료형, 이름, 초기값으로 이루어진 선언문 한 줄을 작성합니다.

float 종류와 moveSpeed 이름표가 붙은 같은 보관함의 변경 전후 모습. 안에 담긴 값만 2에서 5로 바뀌고 이름과 자료형은 유지됨
같은 보관함의 변경 전후입니다. float는 저장할 값의 자료형, moveSpeed는 이름, 안의 숫자는 현재 값입니다. 값이 2에서 5로 바뀌어도 같은 이름으로 읽습니다.

수정 위치: 클래스의 여는 중괄호 바로 아래에 float moveSpeed = 2f;를 추가합니다. 기존 Start를 아래의 출력문 두 줄이 포함된 코드로 교체합니다. 아래 코드는 클래스 내부의 일부이며, 빈 Update는 그대로 둡니다.

클래스 내부 · 필드 추가 + 기존 Start 교체
float moveSpeed = 2f;

void Start()
{
    Debug.Log(name + "의 설정을 확인합니다.");
    Debug.Log("moveSpeed=" + moveSpeed);
}
float moveSpeed = 2f; 한 줄 읽기
구성 요소역할이번 예제의 의미
float자료형소수 부분이 있는 수를 저장할 수 있습니다.
moveSpeed이름저장한 값을 읽을 때 사용할 이름입니다.
= 2f초기값초기값을 2로 지정합니다. 숫자 뒤의 f는 float 형식임을 나타냅니다.
;문장의 끝이 선언이 끝났음을 표시합니다.

실행 결과 확인: 파일을 저장하고 Clear로 로그를 지운 뒤 Play를 누르면 이름 메시지와 moveSpeed=2, 총 두 줄이 출력됩니다. Play를 종료하고 코드의 2f를 5f로 바꿔 다시 실행하면 두 번째 줄이 moveSpeed=5로 바뀝니다. 출력문을 수정하지 않아도 같은 변수 이름으로 변경된 값을 읽습니다. 확인 후 Play를 종료하고 초기값을 2f로 되돌려 저장합니다.

Inspector에서 값 조절

기존 필드 선언을 아래 한 줄로 교체합니다. moveSpeed를 두 번 선언하지 않습니다. 자료형, 이름, 초기값은 유지하고 앞에 [SerializeField]와 private를 추가합니다.

기존 moveSpeed 선언 한 줄 교체
[SerializeField] private float moveSpeed = 2f;
  • private이 필드에 직접 접근할 수 있는 범위를 클래스 내부로 제한합니다. 앞에서 private를 생략했을 때도 기본 접근 범위는 같았습니다.
  • [SerializeField]이 float 필드의 값을 Unity가 저장하고 Inspector에 표시하도록 지정합니다. 저장 후 Unity로 전환하면 MotionController에 Move Speed 입력란이 표시됩니다.

Edit Mode의 Inspector에서 Move Speed를 5로 변경하고 Play를 눌러 실행합니다. Console에도 moveSpeed=5가 출력되면 Inspector와 코드가 동일한 필드 값을 사용함을 확인할 수 있습니다. Play를 종료한 뒤 Inspector 값을 2로 되돌리고 씬을 저장합니다. [SerializeField]를 추가한 뒤에는 코드의 초기값을 고쳐도 이미 저장된 Inspector 값은 유지될 수 있습니다. 값의 저장 원리는 2교시에서 확인합니다.

값의 종류를 고르는 기준

앞의 예제에서는 float를 사용했습니다. 다음 조건문에서는 bool을 사용하고, 2교시의 위치와 방향에서는 Vector3를 사용합니다.

int

정수

개수나 점수와 같은 정수를 저장합니다.

lifeCount3
float

실수

속도나 시간과 같이 소수 부분이 있는 값을 저장합니다.

moveSpeed2f
bool

논리값

true 또는 false를 저장하여 실행 여부를 판단합니다.

shouldRotatetrue
Vector3

3차원 벡터

위치나 방향을 나타내는 x, y, z 값을 저장합니다. Transform의 Position도 이 형태입니다.

position(2, 1, 0)

자료형이 맞아야 저장할 수 있습니다

bool에 2.5f를 대입하거나 int에 소수 값을 그대로 대입하면 컴파일 오류가 발생합니다. float moveSpeed = 2.5;도 오른쪽 숫자의 자료형이 double이므로 오류가 발생합니다. float 형식의 소수는 2.5f와 같이 작성합니다.

다음 단계 필드는 값을 저장하고 Debug.Log는 그 값을 출력합니다. 다음 단계에서는 Start의 출력문 두 줄을 별도의 메서드로 묶습니다.

메서드는 실행할 코드를 하나로 묶습니다

C#에서 클래스 안에 정의한 함수를 메서드(method)라고 합니다. 현재 Start에 작성된 이름과 속도 출력문을 PrintStartMessage라는 메서드로 옮깁니다. 이 메서드를 호출하면 두 줄의 코드가 순서대로 실행됩니다.

PrintStartMessage 작업 장치의 정의 상태와 호출 상태 비교. 왼쪽은 출력 없이 대기하고, 오른쪽은 Start의 호출로 이름과 속도 메시지를 출력함
정의는 작업을 준비하는 것이고, 호출은 그 작업을 실행하는 것입니다. Start()가 PrintStartMessage()를 호출하면 메서드 안의 코드가 순서대로 실행되어 이름과 속도가 Console에 출력됩니다.

수정 위치: 기존 Start 전체를 아래 두 메서드로 교체합니다. PrintStartMessage는 Start의 중괄호 밖, 같은 클래스 안에 둡니다. 앞에서 선언한 moveSpeed 필드와 빈 Update는 유지합니다.

기존 Start 교체 + PrintStartMessage 추가
private void Start()
{
    PrintStartMessage();
}

private void PrintStartMessage()
{
    Debug.Log(name + "의 설정을 확인합니다.");
    Debug.Log("moveSpeed=" + moveSpeed);
}
  • private void PrintStartMessage()메서드를 정의하는 부분입니다. private는 클래스 내부에서만 호출할 수 있다는 뜻입니다. void는 값을 반환하지 않는다는 뜻이며, 빈 괄호는 전달받을 입력이 없음을 나타냅니다.
  • { ... }메서드를 호출했을 때 실행할 코드입니다. 현재는 앞에서 실행한 Debug.Log 두 줄이 포함되어 있습니다.
  • PrintStartMessage();메서드를 호출하는 문장입니다. Start가 이 줄을 실행하면 PrintStartMessage의 코드가 실행되고, 실행이 완료되면 호출한 위치인 Start로 복귀합니다.

Unity → Start() → PrintStartMessage() → Console 두 줄

실행 결과 확인: 파일을 저장하고 Clear로 로그를 지운 뒤 Play를 눌러 실행합니다. 이전과 동일하게 이름과 속도 두 줄이 출력되는지 확인합니다. 실행 결과는 같지만, 출력 코드를 별도의 메서드로 분리했습니다.

메서드는 정의한 뒤 호출해야 실행됩니다

Play를 종료하고 Start 안의 PrintStartMessage(); 한 줄을 임시로 삭제하고 저장합니다. Clear로 로그를 지운 뒤 Play를 눌러 실행하면 메시지가 출력되지 않습니다. 메서드의 정의가 있어도 호출하지 않았기 때문입니다. 확인 후 Play를 종료하고 호출 한 줄을 복원해 저장합니다. Unity가 호출하는 Start와 Start 내부에서 호출하는 PrintStartMessage를 구분합니다.

추가 학습: 입력과 반환값이 있는 메서드

메서드는 입력을 받아 계산한 값을 반환할 수도 있습니다. 아래 예제는 입력과 반환값의 구조를 확인하기 위한 코드입니다. 현재 파일에는 추가하지 않습니다.

구조 확인용 · 현재 파일에는 추가하지 않음
private float CalculateDistance(float speed, float seconds)
{
    return speed * seconds;
}

float speed와 float seconds는 입력을 받을 변수인 매개변수(parameter)입니다. 메서드 이름 앞의 float는 반환할 값의 자료형이고, return은 계산 결과를 호출한 위치로 반환합니다. CalculateDistance(2f, 3f)를 호출하면 2 × 3의 계산 결과인 6이 반환됩니다. Debug.Log(CalculateDistance(2f, 3f));처럼 반환값을 출력할 수도 있습니다.

void 메서드도 return;으로 실행을 중간에 종료할 수 있습니다. 이 경우 return 뒤에 값을 작성하지 않습니다. 2교시의 회전 메서드에서 이 형식을 사용합니다.

다음 단계 메서드를 정의하면 실행할 코드가 준비되고, 호출하면 그 코드가 실행됩니다. 다음 단계에서는 호출된 메서드 안에서 조건에 따라 출력할 메시지를 결정합니다.

조건문은 조건에 따라 코드를 실행합니다

2교시에는 회전 여부를 선택하는 기능을 구현합니다. 먼저 shouldRotate라는 bool 필드에 회전 허용 여부를 저장합니다. 이번에는 이 값이 true일 때만 Console에 메시지를 한 줄 더 출력합니다.

수정 위치 1: 클래스 안에서 moveSpeed 선언 바로 아래에 다음 필드를 추가합니다. 메서드의 중괄호 안에 작성하지 않습니다.

moveSpeed 아래에 필드 한 줄 추가
[SerializeField] private bool shouldRotate = true;

수정 위치 2: 기존 PrintStartMessage 전체를 아래 메서드로 교체합니다. Start의 PrintStartMessage(); 호출은 그대로 둡니다.

기존 PrintStartMessage 교체
private void PrintStartMessage()
{
    Debug.Log(name + "의 설정을 확인합니다.");
    Debug.Log("moveSpeed=" + moveSpeed);

    if (shouldRotate)
    {
        Debug.Log("회전이 허용되었습니다.");
    }
}

if는 괄호 안의 bool 값이 true일 때만 바로 뒤 중괄호 안의 코드를 실행합니다. false이면 해당 중괄호 안의 출력문은 실행되지 않습니다. 앞의 이름과 속도 출력문은 if 밖에 있으므로 두 경우 모두 실행됩니다.

이름과 속도 출력 장치를 차례로 지난 레일이 shouldRotate에서 나뉨. true 경로만 회전 허용 메시지를 출력하고, false 경로는 그 출력을 건너뛴 뒤 같은 끝점으로 합류함
이름과 속도는 분기 전에 항상 출력됩니다. true 경로만 회전 허용 메시지를 하나 더 출력하고, false 경로에서는 해당 출력문을 실행하지 않습니다. 두 경로는 if 다음으로 이어집니다.
Should Rotate 체크

true일 때는 세 줄

이름과 속도에 이어 회전이 허용되었습니다.라는 메시지가 한 번 더 출력됩니다.

Should Rotate 체크 해제

false일 때는 두 줄

회전 허용 메시지는 출력되지 않습니다. 이름과 속도는 두 경우 모두 한 번씩 출력됩니다.

실행 결과 확인: 저장 후 Edit Mode의 Inspector에서 Should Rotate를 켜고 Clear로 로그를 지운 뒤 Play를 눌러 실행합니다. 세 줄을 확인한 뒤 Play를 종료하고 체크를 끕니다. 다시 Clear로 로그를 지운 뒤 Play를 눌러 두 줄만 출력되는지 비교합니다. 값은 실행 전에 변경합니다. Start는 한 번만 실행되므로 Play 도중 체크를 바꿔도 메시지가 다시 출력되지는 않습니다.

관찰 기준 if가 제어하는 것은 바로 뒤 중괄호 안의 코드입니다. 현재는 메시지 한 줄의 출력 여부를 결정합니다. 2교시에는 같은 bool 값으로 실제 회전 여부를 결정합니다.

클래스의 전체 구조를 읽습니다

지금까지 같은 파일에 필드를 추가하고, 출력문을 메서드로 묶고, 조건문을 작성했습니다. 아래는 1교시 종료 시 저장할 MotionController.cs 전체 코드입니다. 작성한 파일과 비교하여 코드 위치와 중괄호 구조를 확인합니다. 수정이 필요한 경우 파일 전체를 아래 코드로 교체할 수 있습니다.

class MotionController 제어 상자 안에 moveSpeed와 shouldRotate 보관함, Start와 빈 Update 및 PrintStartMessage 작업 칸이 있음. if 판단 장치는 PrintStartMessage 칸 안에 포함됨
클래스 안에는 값을 저장하는 필드와 실행할 코드를 담은 메서드가 있습니다. Start()가 PrintStartMessage()를 호출하고, if는 이 메서드 안에서 마지막 메시지의 출력 여부를 결정합니다. 현재 Update()의 중괄호 내부에는 코드가 없습니다.
MotionController.cs · 1교시 완료 코드
using UnityEngine;

public class MotionController : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 2f;
    [SerializeField] private bool shouldRotate = true;

    private void Start()
    {
        PrintStartMessage();
    }

    private void Update()
    {
    }

    private void PrintStartMessage()
    {
        Debug.Log(name + "의 설정을 확인합니다.");
        Debug.Log("moveSpeed=" + moveSpeed);

        if (shouldRotate)
        {
            Debug.Log("회전이 허용되었습니다.");
        }
    }
}
  • 필드 · 값 저장moveSpeed는 속도를, shouldRotate는 회전 허용 여부를 저장합니다. Inspector에서 각 값을 확인합니다.
  • 메서드 · 실행할 코드Unity가 Start를 호출하고, Start가 PrintStartMessage를 호출합니다. 빈 Update에는 실행할 문장이 아직 없습니다.
  • if · 조건에 따른 실행PrintStartMessage는 이름과 속도를 출력한 뒤 shouldRotate 값에 따라 마지막 메시지의 출력 여부를 결정합니다.

2교시를 위한 저장과 확인

  1. 파일과 씬 저장Play를 종료합니다. MotionController.cs를 저장하고, Player에 해당 컴포넌트가 하나 추가되어 있는지 확인합니다. Inspector에서 Move Speed를 2, Should Rotate를 켠 상태로 맞춘 뒤 씬도 저장합니다.
  2. 실행 결과 확인Clear로 Console의 로그를 지우고 Play를 누릅니다. Player에서 Player의 설정을 확인합니다., moveSpeed=2, 회전이 허용되었습니다.라는 메시지가 한 번씩 출력되고 더 늘어나지 않으면 완료입니다. 확인 후 Play를 종료합니다.
  3. 다음 교시 준비이 파일과 씬을 연 상태로 유지합니다. 2교시는 이 코드로 Start와 Update의 호출 횟수를 비교한 뒤, moveSpeed와 shouldRotate를 실제 이동과 회전에 연결합니다.

현재 코드에는 이동과 회전 기능이 없습니다

현재 코드는 Console에 설정값만 출력합니다. Transform을 바꾸는 명령이 없으므로 위치와 회전은 그대로입니다. 2교시에는 Translate, Rotate와 시간 계산을 배운 뒤, 이 파일을 움직임이 포함된 전체 코드로 확장합니다.

1교시 정리 필드는 값을 저장하고, 메서드는 실행할 코드를 묶고, if는 조건에 따라 코드를 실행합니다. 세 요소가 어떻게 연결되는지 직접 작성하고 실행해 확인했습니다.

AI의 코드 설명을 실제 실행 결과와 비교합니다

직접 완성한 코드의 설명을 AI에 요청합니다. 이번 단계의 목표는 직접 예측한 결과, AI의 설명, 실제 Console 출력을 비교하는 것입니다. 현재 코드는 그대로 두고 설명만 요청합니다.

사용할 AI 도구 하나를 연결합니다

1주차에 확인한 계정과 도구를 사용합니다. 아래 도구 중 하나를 Cursor에 연결하고 로그인을 확인합니다. 선택한 도구에 동일한 MotionController.cs 파일을 전달하고 아래의 설명 요청문을 사용합니다.

Cursor에서 AI 코딩 도구 실행
도구시작 경로현재 파일 전달
Codex공식 Codex 확장 설치와 로그인 후 Codex 패널을 엽니다.MotionController.cs를 열고 요청에 해당 파일을 첨부하거나 경로를 지정합니다.
Claude Code공식 Claude Code 확장 설치와 로그인 후 패널을 엽니다.현재 파일을 요청에 첨부하고 분석 대상 경로를 Assets/Scripts/MotionController.cs로 명시합니다.
Gemini CLI공식 설치 안내로 준비한 뒤 Cursor의 통합 터미널에서 GameEngine1 폴더를 기준으로 gemini를 실행하고 로그인합니다.@Assets/Scripts/MotionController.cs를 요청에 포함합니다. Gemini CLI Companion으로 편집기에서 변경 내용을 확인할 수도 있습니다.

일반 Claude·Gemini 웹 채팅과 Claude Code·Gemini CLI는 사용 경로가 다릅니다. 웹 채팅으로 참여한다면 현재 코드와 Unity 버전을 붙여 넣고 설명을 요청합니다. 도구별 계정·이용 조건은 각 공식 안내에서 확인합니다. 접속이나 사용량 제한으로 AI를 사용할 수 없다면 먼저 자신의 예측과 실행 결과를 비교하고, 도구를 사용하지 못한 이유를 기록합니다.

설명 요청 · 현재 파일을 함께 전달
Unity 6.6의 GameEngine1 프로젝트입니다.
Assets/Scripts/MotionController.cs를 분석하고, 코드 수정 없이 다음 항목을 설명해 주십시오.
1. moveSpeed와 shouldRotate에 저장되는 값
2. Unity → Start → PrintStartMessage의 호출 순서
3. Player 하나에서 shouldRotate가 true/false일 때의 예상 로그
4. 현재 Player가 움직이지 않는 이유와 코드상의 근거
  1. 실행 결과 예측Player의 Move Speed가 2일 때, Should Rotate를 선택한 경우와 해제한 경우의 예상 메시지를 기록합니다.
  2. AI 설명과 비교Start가 PrintStartMessage를 호출하는 순서와 if가 제어하는 범위를 AI가 정확히 설명했는지 코드와 대조합니다. AI가 회전한다고 설명했다면 근거가 되는 Transform 변경 코드의 위치를 요청합니다.
  3. Unity에서 확인Edit Mode에서 값을 바꾸고 매번 Clear로 로그를 지운 뒤 Play를 눌러 실행합니다. 각각 세 줄과 두 줄이 출력되는지 확인하고, 설명과 다르면 실제 코드와 출력으로 판단합니다.
2교시로 연결 AI의 설명을 실행 결과와 비교했습니다. 다음에는 원하는 동작을 작은 작업으로 요청하고, 바뀐 코드를 읽은 뒤 직접 실행합니다.

학습 내용 점검

먼저 코드를 참조하지 않고 각 문항의 답을 작성합니다. 작성 후 항목별 설명과 비교하고, 이해가 불명확한 부분은 코드에서 다시 확인합니다.

같은 스크립트를 게임오브젝트 세 개에 각각 추가하면 무엇이 생성됩니까?

스크립트 파일은 하나이고, 각 게임오브젝트에 생성된 컴포넌트 인스턴스는 총 세 개입니다. 코드는 공유하지만 각 인스턴스의 값은 다르게 설정할 수 있습니다.

PrintStartMessage가 정의되어 있지만 출력이 없는 경우 무엇을 확인해야 합니까?

Start 안에 PrintStartMessage(); 호출이 있는지 확인합니다. 메서드는 정의만으로 실행되지 않습니다. Unity가 Start를 호출하고, Start 내부의 코드가 PrintStartMessage를 호출합니다.

shouldRotate가 false일 때 어떤 메시지가 출력됩니까?

if 안의 회전 허용 메시지는 출력되지 않습니다. if 밖의 이름과 속도는 출력되므로, 대상 하나에서는 세 줄 대신 두 줄이 출력됩니다.

자료형은 왜 필요합니까?

변수에 저장할 수 있는 값의 종류와 가능한 연산을 정합니다. 자료형에 맞지 않는 값을 대입하면 컴파일 과정에서 오류를 확인할 수 있습니다. 예를 들어 bool에는 실수를 대입할 수 없습니다.

스크립트 파일 이름과 클래스 이름을 일치시키는 이유는 무엇입니까?

파일에 정의된 클래스를 쉽게 식별하고, Unity가 스크립트를 인식할 때 생길 수 있는 혼동을 줄이기 위해서입니다. 이번 실습에서는 파일 이름을 MotionController.cs, 클래스 이름을 MotionController로 맞춥니다.

Debug.Log를 Start 대신 Update에 작성하면 출력 결과는 어떻게 달라집니까?

Update는 매 프레임 호출되므로 그 안에 작성한 Debug.Log도 반복 실행되어 Console에 로그가 누적됩니다. 현재 완성 코드에서는 Start가 PrintStartMessage를 한 번 호출해 메시지 두 줄 또는 세 줄을 출력합니다. 메서드 한 번의 호출로 여러 줄이 출력될 수 있습니다.

Unity와 C# 공식 문서

이 자료는 실습에 필요한 핵심 규칙을 설명합니다. 정확한 규칙을 다시 확인할 때는 아래 공식 문서를 참고합니다.

  • Methods ↗메서드의 정의와 호출, 입력과 반환값의 관계
  • Creating scripts ↗Assets → Create → Scripting에서 스크립트 파일을 만드는 방법
  • Naming scripts ↗스크립트 파일과 클래스의 이름을 정할 때 참고할 사항
  • MonoBehaviour ↗MonoBehaviour 스크립트가 게임오브젝트의 컴포넌트로 동작하는 방식
  • Debug.Log ↗실행 시점과 값을 Console에 남겨 관찰하는 기본 출력
  • Built-in types ↗int, float, bool을 포함한 C# 기본 자료형의 분류
  • Selection statements ↗if 문이 조건에 따라 실행 경로를 선택하는 규칙

질문이 남았다면

질문할 때는 이해한 부분과 추가 설명이 필요한 부분을 구분합니다. 예를 들어 “float는 자료형이고 moveSpeed는 변수 이름임을 이해했습니다. private로 지정한 접근 범위에 대한 추가 설명이 필요합니다”와 같이 작성합니다.

Next period2교시: 실행 순서와 시간 기반 움직임
메서드 호출 순서와 움직임 구현 →