Published on

섹션 2: 장애물 피하기 1

#전체 목차

  1. Unity C# 강의 2: Start와 Update 메서드 완전 정복
  2. 유니티 C# 강의 정리: 변수와 움직임 수정하기
  3. 유니티 C# 강의 정리: 변수를 직렬화하여 인스펙터에서 조작하기
  4. Unity 이동 시스템 강의 정리
  5. Time.deltaTime과 속도 조절하기
  6. 시네머신(Cinemachine)으로 추적 카메라 구현하기
  7. Cinemachine 옵션 상세 정리
  8. 벽 추가와 충돌 시스템 이해하기

#🎮{ Unity C# 강의 2: Start와 Update 메서드 완전 정복 }

Unity 스크립팅의 핵심인 Start와 Update 메서드의 차이점을 이해하고, 게임 오브젝트를 이동시키는 첫 번째 코드를 작성해보겠습니다.

#📋 목차

  1. 프로젝트 준비하기
  2. Start와 Update 메서드 이해하기
  3. Transform 컴포넌트와 Translate 메서드
  4. 코드 작성 실습
  5. 매개변수와 인수 개념
  6. Float와 Double 자료형
  7. 프레임과 게임 루프
  8. 실행 결과 확인하기

#🚀 프로젝트 준비하기

#1. 새 Unity 프로젝트 생성

// 프로젝트 설정
1. Unity Hub 실행
2. 새 프로젝트 (New Project) 클릭
3. Universal 3D 템플릿 선택
4. 프로젝트 이름: "Obstacle Dodge"
5. Unity Cloud 비활성화
6. Create Project 클릭

#2. 기본 게임 오브젝트 생성

// 지면 평면 생성
Hierarchy 우클릭 → 3D Object → Plane
이름을 "Ground"로 변경

// 플레이어 큐브 생성
Hierarchy 우클릭 → 3D Object → Cube
이름을 "Dodgy The Player"로 변경

#3. 프로젝트 폴더 구조 정리

// Assets 폴더에서 우클릭하여 폴더 생성
1. Materials 폴더 생성
2. Scripts 폴더 생성

#4. 머티리얼 생성 및 적용

// 지면용 어두운 머티리얼
Materials 폴더에서 우클릭 → Create → Material
이름: "Dark Color"
색상을 어둡게 설정
Smoothness를 0으로 설정 (무광 효과)


// 플레이어용 녹색 머티리얼
Materials 폴더에서 우클릭 → Create → Material
이름: "Green"
HEX 색상 코드 입력 (예: #00FF00)

Unity 프로젝트 생성

Unity 프로젝트 생성

#🔧 Start와 Update 메서드 이해하기

#Start 메서드의 특징

void Start()
{
    // 게임이 시작될 때 한 번만 실행되는 코드
    Debug.Log("게임이 시작되었습니다!");
}

Start 메서드 핵심 개념:

  • 스크립트가 활성화될 때 단 한 번만 호출
  • 게임 오브젝트가 씬에 존재하고 스크립트가 활성 상태일 때 실행
  • 초기화 작업에 주로 사용

#Update 메서드의 특징

void Update()
{
    // 매 프레임마다 실행되는 코드
    Debug.Log("매 프레임마다 실행됩니다!");
}

Update 메서드 핵심 개념:

  • 매 프레임마다 호출되는 메서드
  • 게임이 실행되는 동안 지속적으로 반복 실행
  • 움직임, 입력 처리, 상태 변화 등에 사용

#프레임(Frame)이란?

// 프레임의 개념
1프레임 = 게임이 화면을 한 번 갱신하는 단위

초당 60프레임 (60 FPS) = 1초에 60번 화면 갱신
초당 30프레임 (30 FPS) = 1초에 30번 화면 갱신

프레임이 높을수록 → 더 부드러운 움직임
프레임이 낮을수록 → 끊어지는 듯한 움직임

#🎯 Transform 컴포넌트와 Translate 메서드

#Transform 컴포넌트 이해하기

// Transform 컴포넌트는 모든 게임 오브젝트가 가지는 기본 컴포넌트
Transform 컴포넌트의 구성 요소:
- Position (위치): X, Y, Z 좌표
- Rotation (회전): X, Y, Z 축 회전값
- Scale (크기): X, Y, Z 축 크기 비율

#점 연산자(Dot Operator) 개념

// 점 연산자(.)의 의미
transform.Translate();
//    ^
//    이 점이 "점 연산자"

// 의미: transform이 가지고 있는 기능들에 접근하겠다는 뜻
transform.position;    // 위치에 접근
transform.rotation;    // 회전에 접근
transform.localScale;  // 크기에 접근
transform.Translate(); // 이동 함수 호출

#Translate 메서드 상세 분석

// Translate 메서드의 기본 구조
transform.Translate(x, y, z);

// 각 매개변수의 의미
x: X축 이동량 (좌우 이동)
y: Y축 이동량 (상하 이동)
z: Z축 이동량 (앞뒤 이동)

#💻 코드 작성 실습

#1. Mover 스크립트 생성

// Scripts 폴더에서 우클릭
Create → C# Script
이름: "Mover"

// 중요한 주의사항
파일 이름과 클래스 이름이 일치해야 함!
다른 곳을 클릭하기 전에 반드시 이름을 변경할 것!

#2. 스크립트를 게임 오브젝트에 연결

// 방법 1: 드래그 앤 드롭
Mover 스크립트를 Dodgy The Player 오브젝트로 드래그

// 방법 2: Add Component 사용
1. Dodgy The Player 선택
2. Inspector에서 Add Component 클릭
3. "Mover" 검색 후 선택

// 방법 3: Inspector에 직접 드래그
1. Dodgy The Player 선택
2. Mover 스크립트를 Inspector 빈 공간에 드래그

#3. Start 메서드에서 이동 코드 작성

using UnityEngine;

public class Mover : MonoBehaviour
{
    void Start()
    {
        // 게임 시작 시 한 번만 이동
        transform.Translate(1, 0, 0);
    }

    void Update()
    {
        // 현재는 비어있음
    }
}

코드 실행 결과:

  • 게임 시작 시 오브젝트가 X축으로 1만큼 이동
  • 한 번만 실행되므로 순간적으로 이동

#4. Update 메서드로 코드 이동

using UnityEngine;

public class Mover : MonoBehaviour
{
    void Start()
    {
        // 비어있음
    }

    void Update()
    {
        // 매 프레임마다 이동
        transform.Translate(1, 0, 0);
    }
}

코드 실행 결과:

  • 매 프레임마다 X축으로 1만큼 이동
  • 매우 빠르게 이동하여 화면 밖으로 사라짐

#📊 매개변수와 인수 개념

#매개변수(Parameter)와 인수(Argument)

// 메서드 정의에서는 "매개변수"
void Translate(float x, float y, float z)
{
    // x, y, z는 매개변수(Parameter)
}

// 메서드 호출에서는 "인수"
transform.Translate(1, 0, 0);
//                  ↑  ↑  ↑
//                  인수(Argument)

개념 정리:

  • 매개변수: 함수를 정의할 때 사용하는 변수
  • 인수: 함수를 호출할 때 전달하는 실제 값

#Transform.Translate의 매개변수

// Translate 메서드의 매개변수 상세
transform.Translate(x, y, z);

// 각 매개변수의 역할
float x: X축 이동량 (양수 = 오른쪽, 음수 = 왼쪽)
float y: Y축 이동량 (양수 = 위쪽, 음수 = 아래쪽)
float z: Z축 이동량 (양수 = 앞쪽, 음수 = 뒤쪽)

// 예시
transform.Translate(1, 0, 0);    // 오른쪽으로 1만큼
transform.Translate(-1, 0, 0);   // 왼쪽으로 1만큼
transform.Translate(0, 1, 0);    // 위쪽으로 1만큼
transform.Translate(0, 0, 1);    // 앞쪽으로 1만큼

#🔢 Float와 Double 자료형

#소수점 숫자의 자료형

// Double과 Float의 차이
double number1 = 0.01;  // 높은 정밀도 (64비트)
float number2 = 0.01f;  // 일반 정밀도 (32비트)

// Unity에서는 주로 float 사용
// float 표기법: 숫자 뒤에 'f' 붙이기

#자료형 변환 오류 해결

// 오류가 발생하는 코드
transform.Translate(0.01, 0, 0);
// 오류 메시지: "cannot convert double to float"

// 올바른 코드
transform.Translate(0.01f, 0f, 0f);
// 또는
transform.Translate(0.01f, 0, 0);  // 정수는 자동 변환됨

float 사용 이유:

  • Unity는 성능상 float를 선호
  • 게임 개발에서는 극도의 정밀도가 필요하지 않음
  • 메모리 사용량이 적음

#⚡ 프레임과 게임 루프

#게임 루프의 개념

// 게임 루프의 기본 구조
while (게임이 실행 중)
{
    1. 입력 처리
    2. 게임 로직 실행 (Update 호출)
    3. 렌더링 (화면에 그리기)
    4. 다음 프레임으로
}

#프레임 속도에 따른 이동 차이

// 문제가 있는 코드
void Update()
{
    transform.Translate(1f, 0f, 0f);  // 매 프레임마다 1만큼 이동
}

// 문제점:
// 60 FPS: 1초에 60만큼 이동
// 30 FPS: 1초에 30만큼 이동
// → 프레임 속도에 따라 이동 속도가 달라짐!

#적절한 이동 속도 설정

void Update()
{
    // 느린 이동을 위해 작은 값 사용
    transform.Translate(0.01f, 0f, 0f);
}

// 더 나은 방법 (시간 기반 이동)
void Update()
{
    float speed = 5f;  // 초당 5 유닛 이동
    transform.Translate(speed * Time.deltaTime, 0f, 0f);
}

#🎮 실행 결과 확인하기

#카메라 위치 조정

// 게임 뷰에서 오브젝트를 잘 보기 위한 카메라 설정
1. Main Camera 선택
2. F키를 눌러 오브젝트에 포커스
3. 마우스 휠로 줌 조정
4. E키 + 마우스 드래그로 카메라 회전

#Start 메서드 실행 결과

void Start()
{
    transform.Translate(1f, 0f, 0f);
}

// 결과:
// - 게임 시작 시 순간적으로 오른쪽으로 이동
// - 한 번만 실행되므로 이후 정지
// - Transform의 X Position이 0에서 1로 변경됨

#Update 메서드 실행 결과

void Update()
{
    transform.Translate(0.01f, 0f, 0f);
}

// 결과:
// - 매 프레임마다 조금씩 오른쪽으로 이동
// - 부드럽고 지속적인 움직임
// - 게임을 정지할 때까지 계속 이동

#🔍 디버깅과 문제 해결

#자주 발생하는 실수들

// 실수 1: 저장하지 않고 실행
// 해결: Ctrl+S로 스크립트 저장 후 Unity로 돌아가기

// 실수 2: 세미콜론 누락
transform.Translate(1f, 0f, 0f)  // 오류!
transform.Translate(1f, 0f, 0f); // 올바름

// 실수 3: 스크립트 연결 안 함
// 해결: 스크립트를 게임 오브젝트에 반드시 연결

// 실수 4: 컴파일 오류 무시
// 해결: Console 창에서 오류 메시지 확인 및 수정

#Transform 값 확인하기

// Inspector에서 Transform 값 실시간 확인
게임 실행 중 → Inspector → Transform → Position 값 관찰

// 코드로 현재 위치 출력
void Update()
{
    transform.Translate(0.01f, 0f, 0f);
    Debug.Log("현재 위치: " + transform.position);
}

#📚 핵심 개념 정리

#Start vs Update 비교표

구분 Start Update
호출 빈도 한 번만 매 프레임
사용 용도 초기화 지속적 작업
실행 시점 게임 시작 시 게임 실행 중
예시 용도 변수 설정, 컴포넌트 가져오기 이동, 입력 처리, 상태 변경

#Transform.Translate 문법

// 기본 문법
transform.Translate(x, y, z);

// 실제 사용 예시
transform.Translate(1f, 0f, 0f);     // 오른쪽 이동
transform.Translate(-1f, 0f, 0f);    // 왼쪽 이동
transform.Translate(0f, 1f, 0f);     // 위쪽 이동
transform.Translate(0f, -1f, 0f);    // 아래쪽 이동
transform.Translate(0f, 0f, 1f);     // 앞쪽 이동
transform.Translate(0f, 0f, -1f);    // 뒤쪽 이동

#C# 기본 문법 요소

// 세미콜론: 문장의 끝을 표시
Debug.Log("Hello");

// 점 연산자: 객체의 멤버에 접근
transform.position;

// 괄호: 메서드 호출 시 인수 전달
Translate(1f, 0f, 0f);

// 중괄호: 코드 블록 정의
void Start()
{
    // 이 안의 코드들이 하나의 블록
}

#🚀 다음 단계 미리보기

다음 강의에서는 다음 내용들을 학습할 예정입니다:

  • Time.deltaTime을 활용한 프레임 독립적 이동
  • Input 시스템을 이용한 플레이어 조작
  • 변수(Variables) 사용법
  • 조건문(if) 기초
  • 충돌 감지(Collision Detection) 기초



#{ 🎮 유니티 C# 강의 정리: 변수와 움직임 수정하기 }

#📋 목차

  1. 변수란 무엇일까?
  2. 변수의 자료형
  3. 변수 선언 규칙
  4. Mover.cs에 변수 적용하기
  5. 하드 코딩 vs 변수 사용
  6. 도전 과제: 공중으로 이동시키기
  7. 정리

#1. 변수란 무엇일까?

  • 변수는 정보를 저장하는 상자 같은 것.
  • 예:
    • 이름: hitPoints
    • 값: 20
    • 의미: 체력(HP) 20이라는 정보가 들어 있음.

➡️ 값은 바뀔 수 있음 → 체력팩을 먹으면 증가, 적 공격을 받으면 감소.


#2. 변수의 자료형

변수는 데이터의 종류(타입) 에 따라 나뉩니다.

  • int (정수)

    • 예: int hitPoints = 20;
  • float (소수점 있는 숫자)

    • 예: float speed = 0.01f;
    • 뒤에 f를 붙여야 함.
  • bool (참/거짓)

    • 예: bool isAlive = true;
    • 흔히 isSomething 형태로 이름 짓기 (isAlive, isEnemy).
  • string (문자열: 글자 묶음)

    • 예: string name = "Rick";

#3. 변수 선언 규칙

  • 자료형 → 변수명 → 값 → 세미콜론(;)

    int hitPoints = 20;
    float moveSpeed = 0.05f;
    bool isAlive = true;
    string playerName = "Rick";
    
  • 이름 규칙:

    • 첫 글자는 소문자
    • 이어지는 단어 첫 글자는 대문자 (camelCase)
    • 예: hitPoints, moveSpeed

#4. Mover.cs에 변수 적용하기

원래는 이렇게 작성했음 👇 (숫자를 직접 넣음 → 하드 코딩)

transform.Translate(0.01f, 0f, 0f);

변수로 바꾸면 👇

float xValue = 0.01f;

transform.Translate(xValue, 0f, 0f);

➡️ 이제 xValue만 수정하면 이동 속도가 바뀜.


#5. 하드 코딩 vs 변수 사용

  • 하드 코딩: 숫자를 직접 넣는 방식. (나중에 수정하기 어려움)
  • 변수 사용: 한 번만 수정해도 여러 곳에 적용 가능.

예:

  • xValue를 0.01 → 0.05로 바꾸면,
  • 코드 전체에서 자동으로 적용됨.

#6. 도전 과제: 공중으로 이동시키기

#🎯 과제

  • yValue, zValue 변수를 추가
  • X축이 아닌 Y축 방향(공중) 으로만 이동시키기

#📝 코드 예시

float xValue = 0f;
float yValue = 0.05f;
float zValue = 0f;

void Update()
{
    transform.Translate(xValue, yValue, zValue);
}

➡️ 실행하면 플레이어가 공중으로 곧바로 올라감 🚀


#7. 정리

  • 변수는 정보를 담는 상자
  • C#에서 자주 쓰는 자료형: int, float, bool, string
  • 변수를 사용하면 코드 관리가 쉬워지고, 수정도 간편함
  • 이번 실습: xValue, yValue, zValue 변수를 만들어 플레이어 이동 방향을 제어함

👉 이렇게 변수 개념을 배우고 실습하면, 앞으로 더 복잡한 프로젝트에서도 효율적인 코드 작성이 가능해집니다.




#{ 🎮 유니티 C# 강의 정리: 변수를 직렬화하여 인스펙터에서 조작하기 }

#📋 목차

  1. 플레이 모드 설정 최적화
  2. 직렬화란 무엇일까?
  3. 변수를 직렬화하는 방법
  4. 인스펙터에서 변수 조작하기
  5. 도전 과제: 플레이어 이동 제어하기
  6. 정리

#1. 플레이 모드 설정 최적화

  • 문제: 유니티에서 재생 버튼(▶)을 누르면 매번 도메인/씬이 다시 로드됨 → 기다려야 해서 불편함.

  • 해결 방법:

    • 메뉴에서 Edit → Project Settings → Editor로 이동
    • Enter Play Mode Settings에서
      • Reload Domain
      • Reload Scene
        체크 해제 가능
      • Do not reload Domain or Scene*
  • 효과: 재생할 때마다 불필요한 초기화 과정이 줄어듦.


#2. 직렬화란 무엇일까?

  • 직렬화(Serialize): 변수를 코드 안에만 두는 것이 아니라, 유니티 인스펙터(Inspector) 창에서도 볼 수 있고, 수정할 수 있도록 만드는 것.
  • 왜 필요할까?
    • 코드 → 수정 → 저장 → 다시 실행 → 확인 … 이 과정을 매번 반복하기 번거롭기 때문.
    • 직렬화를 하면 인스펙터에서 값을 바로 수정하면서 실험할 수 있음.

#3. 변수를 직렬화하는 방법

  • float yValue = 0.001f; 라는 변수가 있을 때,

  • 앞에 [SerializeField]를 붙이면 됨:

    [SerializeField] float yValue = 0.001f;
    
  • 이렇게 하면 스크립트 코드에는 기본값이 남아 있고,

  • 유니티 인스펙터에서 해당 값을 직접 조정할 수 있음.


#4. 인스펙터에서 변수 조작하기

  • 직렬화된 변수를 인스펙터에서 보면 슬라이더/숫자 입력칸으로 나타남.

  • 장점:

    • 실시간으로 값을 바꿔보고, 플레이하면서 결과를 확인 가능.
    • 0.001 → 0.123 → -0.001 같은 값 변경을 코드 수정 없이 바로 테스트 가능.
  • 주의할 점:

    • 인스펙터에서 값을 바꿔도 원본 코드 값은 변하지 않음.
    • 즉, 코드에는 여전히 0.001이 남아 있음.

#5. 도전 과제: 플레이어 이동 제어하기

#🎯 과제

  1. 세 개의 변수를 모두 직렬화해서 인스펙터에서 접근 가능하게 만들기.

    [SerializeField] float xValue = 0f;
    [SerializeField] float yValue = 0f;
    [SerializeField] float zValue = 0f;
    
  2. 플레이 모드에서 플레이어가 카메라에서 멀어졌다가 다시 돌아오게 해보기.

#📝 예시 코드

[SerializeField] float xValue = 0.005f;
[SerializeField] float yValue = 0f;
[SerializeField] float zValue = 0f;

void Update()
{
    transform.Translate(xValue, yValue, zValue);
}
  • X값을 양수로 → 카메라에서 멀어짐
  • X값을 음수로 → 카메라 쪽으로 돌아옴

➡️ 인스펙터에서 값을 실시간으로 조정하면 캐릭터 움직임을 바로 확인 가능.


#6. 정리

  • 플레이 모드 설정 최적화: 불필요한 도메인/씬 리로드를 줄여서 빠르게 테스트 가능.
  • 직렬화(SerializeField): 변수를 인스펙터에서 조작 가능하게 만듦.
  • 장점: 코드 수정 없이 실시간 값 조절 & 테스트 가능.
  • 실습: X, Y, Z 변수를 직렬화하여 플레이어가 카메라에서 멀어졌다가 다시 돌아오도록 구현.

👉 다음 강의에서는 키보드 입력을 활용해 직접 플레이어를 조종하는 방식으로 발전시켜 나갑니다.




#{ 📌 C# 포맷 원칙 정리 (Unity Mover 스크립트 예제 기반) }

#1. 주석 (Comment)

  • 정의: 코드 실행에는 영향을 주지 않는 메모. // 뒤에 작성.

  • 용도:

    • 6개월 뒤에 코드를 다시 보더라도 “내가 여기서 뭘 하려고 했지?”라는 질문에 답할 수 있도록 설명을 남김.
    • 코드의 의도를 보충 설명.
  • 주의점:

    • “주석을 쓰지 말라”는 의견도 있음 → 코드 자체가 잘 읽히도록 이름을 명확하게 짓는 것이 이상적.
    • 그러나 초보자라면 주석을 활용해도 좋음 → 학습 과정에서 유용.

#2. 공백 (Whitespace)

  • 코드 실행에는 영향 없음.
    → 가독성을 높이기 위한 용도로 사용.

  • 예외: 단어를 잘못 쪼개면 오류 발생

    • float yValue; (정상)
    • flo at yValue; (오류)
  • IDE 도움:

    • 잘못된 경우 빨간 물결선(에러 표시)이 나타남.
    • 빨간 줄이 없다면 문법적으로 문제 없음.

#3. 중괄호 `{ }`와 들여쓰기

  • 중괄호의 역할: 코드 블록(Block)의 시작과 끝을 정의.

  • 스타일 차이:

    void Update()
    {
        // 보통 이렇게 씀
    }
    

    또는

    void Update() {
        // 이렇게도 가능
    }
    

    → 기능적으로는 동일, 팀 스타일 가이드에 맞추는 것이 중요.

  • 들여쓰기:

    • 중괄호 안에 들어가면 한 칸 들여쓰기.
    • 블록이 중첩될수록 단계적으로 들여쓰기.

#4. 클래스와 메소드의 중괄호 구조

  • 클래스:

    • 예: class Mover { ... }
    • 클래스는 스크립트의 큰 틀. (Mover, Shooter, Explosion 등)
    • 클래스 안에 변수, 메소드가 포함됨.
  • 메소드:

    • 예: void Start() { ... }, void Update() { ... }
    • 각각의 메소드가 독립된 블록을 가짐.
    • 특정 블록 안에서 선언된 것들은 다른 블록이 자동으로 알지 못함.

#5. 변수와 스코프(Scope)

  • 클래스 레벨 변수:

    • x, y, z 같이 클래스 안에 선언된 변수는 여러 메소드에서 공유 가능.
  • 메소드 안 변수:

    • 특정 메소드 블록 { } 안에 선언된 변수는 그 메소드 안에서만 사용 가능.
  • 중요한 점:

    • Update()가 실행될 때, x, y, z의 최신 값을 가져와 움직임에 반영해야 함.
    • 컨트롤러 입력을 받아 변수를 변경하면, Update()에서 이를 알아야 캐릭터를 움직일 수 있음.

#6. 다음 강의 예고

  • 목표:
    • Update()가 입력(왼쪽/오른쪽 이동 등)을 감지하고
    • 이를 바탕으로 캐릭터 이동이 가능하도록 구현.

정리 포인트:

  • 주석 → 메모 용도 (초보자는 적극 활용해도 OK)
  • 공백 → 가독성용 (문법만 깨지 않으면 자유롭게)
  • 중괄호 { } → 코드 블록을 구분 (들여쓰기로 가독성 유지)
  • 클래스와 메소드 구조 → 스코프 개념 이해 필수
  • 변수는 어디에 선언되었는지에 따라 접근 가능 범위 달라짐

#{ 🎮 Unity 이동 시스템 강의 정리 }

이 강의에서는 구 입력 시스템(Input Manager) 을 사용하여
키보드 입력으로 오브젝트를 움직이는 방법을 배웁니다.


#📋 목차

  1. 프로젝트 준비하기
  2. 구 입력 시스템과 신 입력 시스템
  3. Start와 Update 메서드
  4. 위치 이동 방법: 직접 변경 vs 물리 힘
  5. Input Manager와 축(Axis)
  6. 코드 작성 과정
  7. 실행 결과
  8. 다음 단계 예고

#1. 프로젝트 준비하기

  • 이번 프로젝트에서는 간단한 이동 장면을 구현합니다.
  • 오브젝트를 왼쪽, 오른쪽, 위, 아래로 움직일 수 있도록 합니다.

#2. 구 입력 시스템과 신 입력 시스템

  • 구 입력 시스템(Input Manager)
    • 오래된 방식이지만 간단하고 배우기 쉽습니다.
    • 빠르게 결과를 보고 싶을 때 유용합니다.
  • 신 입력 시스템(Input System)
    • 최근에 추가된 새로운 방식.
    • 더 강력하고 다양한 기능 제공.
  • 이번 강의에서는 구 입력 시스템을 사용합니다.

#3. Start와 Update 메서드

  • Start() : 게임 시작 시 한 번만 실행됩니다.
  • Update() : 매 프레임마다 실행됩니다.
    • 키보드 입력은 매 순간 바뀌므로 Update() 안에서 확인해야 합니다.

#4. 위치 이동 방법: 직접 변경 vs 물리 힘

  • Unity에서 오브젝트를 움직이는 방법은 크게 두 가지가 있습니다.
    1. 직접 위치 변경
      • x, y, z 값을 직접 바꿔서 이동.
      • 단순하고 빠름.
    2. 물리 힘 적용
      • Rigidbody에 힘(force)을 가해 움직임.
      • 중력, 마찰 같은 물리 효과를 함께 사용 가능.
  • 강의에서는 직접 위치 변경 방법을 사용합니다.

#5. Input Manager와 축(Axis)

  • Edit → Project Settings → Input Manager 에서 확인 가능.
  • Horizontal (좌우)
    • A 키 → -1
    • D 키 → +1
    • 방향키 좌/우 → 동일 동작
  • Vertical (상하)
    • W 키 → +1
    • S 키 → -1
    • 방향키 상/하 → 동일 동작
  • 입력값은 -1 ~ 1 사이의 부드러운 값을 가집니다.

#6. 코드 작성 과정

  1. Update() 안에서 키보드 입력을 받습니다.
  2. Input.GetAxis("Horizontal") → 좌우 움직임 값 가져오기
  3. Input.GetAxis("Vertical") → 위/아래 움직임 값 가져오기
  4. transform.Translate(x, y, z) 로 위치 이동
using UnityEngine;

public class Mover : MonoBehaviour
{
    void Update()
    {
        float xValue = Input.GetAxis("Horizontal");  // 좌우
        float yValue = 0f;                          // 위로는 이동 안 함
        float zValue = Input.GetAxis("Vertical");   // 앞뒤

        transform.Translate(xValue, yValue, zValue);
    }
}

#7. 실행 결과

  • ▶️ 실행 후 A/D 키 또는 좌우 화살표 → 오브젝트가 좌우로 이동
  • W/S 키 또는 상하 화살표 → 오브젝트가 앞뒤로 이동
  • 현재는 속도가 매우 빠르며, 자연스러운 이동은 다음 단계에서 다룹니다.

#8. 다음 단계 예고

  • Time.deltaTime을 사용해 프레임 속도와 상관없는 일정한 움직임 구현.
  • 이동 속도를 조절할 수 있는 변수(speed) 추가.

✅ 이번 강의 핵심 정리

  • 구 입력 시스템(Input Manager)을 사용.
  • Horizontal → 좌우 입력, Vertical → 위/아래 입력.
  • Update() 안에서 Input.GetAxis() 로 입력을 감지.
  • transform.Translate() 로 오브젝트를 이동.

#{ 🎮 Time.deltaTime과 속도 조절하기 }

이번 강의에서는 Time.deltaTime과 변수를 사용해 플레이어가 컴퓨터 성능(빠른 PC, 느린 노트북 등)에 상관없이 일관된 속도로 움직이도록 만드는 방법을 배웁니다.


#📋 목차

  1. 프로젝트 준비하기
  2. 프레임과 게임 루프
  3. Update 메서드와 문제점
  4. Time.deltaTime 개념
  5. 속도 조절을 위한 변수 선언
  6. 코드 작성 실습
  7. 실행 결과 확인하기

#1. 프로젝트 준비하기

  • 플레이어 오브젝트를 이동시키는 스크립트를 작성합니다.
  • Update() 메서드를 사용해 키 입력에 따라 캐릭터를 움직이게 만듭니다.

#2. 프레임과 게임 루프

  • 게임은 프레임 단위로 실행됩니다.

  • FPS(Frame Per Second, 초당 프레임 수): 컴퓨터 성능에 따라 달라집니다.

    • 빠른 컴퓨터 → FPS 150
    • 느린 컴퓨터 → FPS 30
  • 문제점: Update()프레임마다 실행되므로, FPS가 다르면 같은 코드라도 속도가 달라져 버립니다.


#3. Update 메서드와 문제점

  • 예시: 키를 눌렀을 때 transform.Translate(1, 0, 0); 이라고 하면

    • FPS 150 → 1초에 150번 이동 → 엄청 빠르게 움직임
    • FPS 30 → 1초에 30번 이동 → 느리게 움직임
  • 따라서 FPS가 다른 컴퓨터에서는 플레이어 속도가 제각각 달라지는 문제가 발생합니다.


#4. Time.deltaTime 개념

  • Time.deltaTime: 이전 프레임과 현재 프레임 사이에 걸린 시간(초 단위)

  • 예시:

    • FPS 10 → deltaTime = 0.1초
    • FPS 100 → deltaTime = 0.01초
  • 코드에 * Time.deltaTime을 곱해주면 → 프레임 속도에 상관없이 일정한 속도를 유지할 수 있습니다.


#5. 속도 조절을 위한 변수 선언

  • 단순히 Time.deltaTime만 쓰면 너무 느리거나 빠를 수 있음.
  • 따라서 **속도 변수(moveSpeed)**를 만들어 원하는 대로 조절합니다.
  • 변수 선언 방법:
[SerializeField] float moveSpeed = 10f;
  • SerializeField → Unity 인스펙터 창에서 값을 직접 조절할 수 있도록 함.

#6. 코드 작성 실습

using UnityEngine;

public class Mover : MonoBehaviour
{
    [SerializeField] float moveSpeed = 10f;

    void Update()
    {
        float xValue = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
        float zValue = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;

        transform.Translate(xValue, 0, zValue);
    }
}
  • Input.GetAxis("Horizontal") → -1(왼쪽), 0(안눌림), 1(오른쪽)
  • Input.GetAxis("Vertical") → -1(뒤), 0(안눌림), 1(앞)
  • Time.deltaTime → 프레임 보정
  • moveSpeed → 속도 조절 가능

#7. 실행 결과 확인하기

  • moveSpeed = 10 → 기본 속도
  • moveSpeed = 3 → 느리게 이동
  • moveSpeed = 23 → 빠르게 이동
  • 장점:
    • 빠른 PC, 느린 PC에서 모두 동일한 속도로 움직임
    • 원하는 대로 속도 조절 가능

👉 이제 플레이어 이동은 프레임 독립적이 되어서, 어떤 환경에서도 일관되게 동작합니다.


#{ 🎥 시네머신(Cinemachine)으로 추적 카메라 구현하기 }

#📋 목차

  1. 왜 카메라가 필요할까?
  2. 시네머신(Cinemachine)이란?
  3. 프로젝트 준비하기
  4. 가상 카메라(Virtual Camera) 추가하기
  5. 플레이어 추적 설정하기
  6. 카메라 위치와 회전 조정하기
  7. Damping(감쇠) 이해하기
  8. 마무리와 응용

#1. 왜 카메라가 필요할까?

  • 유니티 씬(Scene)에는 기본적으로 메인 카메라가 있음.
  • 하지만 플레이어가 이동할 때 기본 카메라는 따라오지 않음 → 쉽게 화면 밖으로 벗어남.
  • 따라서 플레이어를 자동으로 따라오는 추적 카메라가 필요함.

#2. 시네머신(Cinemachine)이란?

  • 유니티에서 제공하는 무료 패키지.

  • 기능:

    • 여러 카메라를 쉽게 관리 (컷신, 전투, 달리기 등 상황별 카메라 전환 가능).
    • 카메라 움직임(위치, 회전, 추적, 줌 등)을 코드 없이 설정 가능.
  • 핵심 컴포넌트:

    • Cinemachine Brain → 메인 카메라에 붙음, 어떤 가상 카메라를 보여줄지 결정.
    • Virtual Camera → 실제로 플레이어를 따라다니거나 특정 연출을 담당.

#3. 프로젝트 준비하기

  1. 상단 메뉴 → Window > Package Manager 열기.
  2. Unity Registry에서 Cinemachine 검색.
  3. Install 클릭 → 설치 완료 후 Project에 패키지 추가됨.

#4. 가상 카메라(Virtual Camera) 추가하기

  1. Hierarchy(계층창)에서 우클릭 → Cinemachine → Virtual Camera 선택.

  2. 생성된 Virtual Camera는 Main Camera 바로 아래로 이동.

    • 이유: Main Camera는 화면 출력을 담당, Virtual Camera는 동작 설정 담당.
  3. Main Camera에 자동으로 Cinemachine Brain이 추가됨.


#5. 플레이어 추적 설정하기

  1. Virtual Camera 선택.

  2. Inspector → Follow(Target) 에 플레이어 GameObject 드래그.

    • 카메라가 플레이어를 따라감.
  3. 필요하다면 Look At(Target) 도 플레이어로 설정.

    • 카메라가 항상 플레이어를 바라보게 됨.

#6. 카메라 위치와 회전 조정하기

  • Virtual Camera Inspector → BodyAim 설정 가능.

  • 자주 쓰는 설정:

    • Follow : 단순히 플레이어 따라오기.
    • Third Person Follow : 3인칭 시점처럼 따라오기.
    • Hard Look At : 항상 플레이어를 바라보게 하기.
  • Follow Offset 값 조절:

    • Y값 ↑ : 카메라를 위로 올려 내려다보는 느낌.
    • Z값 ± : 카메라를 앞뒤로 움직여 거리 조절.

#7. Damping(감쇠) 이해하기

  • 플레이어가 움직일 때 카메라가 즉시 따라오지 않고 부드럽게 따라오는 효과.

  • Damping 값 조절:

    • 0 → 카메라가 즉시 따라옴 (딱딱한 느낌).
    • 값이 클수록 → 카메라가 천천히 따라옴 (부드럽지만 약간 지연됨).
  • 보통 0.1 ~ 0.3 사이 값이 자연스러움.


#8. 마무리와 응용

  • 이제 플레이어가 이동할 때 카메라가 자연스럽게 따라옴.

  • 이후에는 상황에 따라 여러 Virtual Camera를 만들어 전환 가능:

    • 달리기 전용 카메라
    • 컷신 전용 카메라
    • 전투 전용 카메라
  • 이번 강의는 Cinemachine의 기초 (추적 카메라 구현)에 집중.


👉 정리:

  • Cinemachine 설치 → Virtual Camera 추가 → 플레이어 Follow 설정 → 위치/회전 조정 → Damping으로 부드러운 움직임 → 추적 카메라 완성 ✅

#{ 🎥 Cinemachine 옵션 상세 정리 }

#📋 목차

  1. Cinemachine Brain

  2. Virtual Camera

  3. Follow / Look At (추적 & 바라보기)

  4. Body 옵션

    • Hard Lock To Target
    • Follow
    • Third Person Follow
  5. Aim 옵션

    • Hard Look At
    • Do Nothing
  6. Follow Offset

  7. Damping (감쇠)

  8. 응용 예시


#1. 🎛 Cinemachine Brain

  • 위치: Main Camera에 자동으로 붙음.

  • 역할: 여러 개의 Virtual Camera 중 "어떤 카메라를 현재 보여줄지" 결정.

  • 동작 방식:

    • Virtual Camera 1이 활성화되면 → Brain이 화면에 그것을 출력.
    • Virtual Camera 2가 켜지면 → Brain이 자연스럽게 전환.
  • 👉 강의에서는 Virtual Camera 하나만 사용하므로 복잡한 전환은 없음.


#2. 🎥 Virtual Camera

  • 실제 카메라 움직임과 동작을 담당.
  • 플레이어를 따라다니거나 특정 구도를 잡는 역할.
  • Brain은 Virtual Camera가 만든 "화면"을 가져와 보여줄 뿐임.

#3. 🎯 Follow / Look At (추적 & 바라보기)

  • Follow: 카메라가 대상(플레이어)을 따라다님.
  • Look At: 카메라가 항상 대상(플레이어)을 바라봄.

👉 둘 다 플레이어를 드래그 앤 드롭으로 넣으면 됨.

  • Follow만 넣으면 → 카메라가 따라다니긴 하지만 바라보지는 않을 수 있음.
  • Look At만 넣으면 → 카메라가 바라보지만 따라오진 않음.
  • 보통 둘 다 설정해야 원하는 “추적 카메라” 완성.

#4. 🧩 Body 옵션

카메라의 위치(어디에 있을지) 를 결정하는 기능.
강의에서 실험했던 것들 정리해보면:

#① Hard Lock To Target

  • 카메라가 대상에 딱 붙어서 고정됨.
  • 마치 대상 위에 GoPro 카메라를 붙인 것 같은 느낌.
  • 단점: 너무 가까워서 전체 화면을 보기 힘듦.

#② Follow

  • 카메라가 대상을 따라가되, 일정한 오프셋(거리/위치 차이)을 유지.
  • 가장 기본적인 추적 방식.
  • Follow Offset으로 거리/높이/각도를 조정 가능.

#③ Third Person Follow

  • 3인칭 시점 게임(예: GTA, 배틀로얄 게임)에 많이 사용.
  • 캐릭터 뒤쪽 위에서 따라다님.
  • 기본 Follow보다 자연스러운 시야 제공.
  • 단, 캐릭터에 너무 가까워질 수 있어 조정 필요.

#5. 🎯 Aim 옵션

카메라의 회전(어디를 볼지) 를 결정하는 기능.

#① Hard Look At

  • 대상(플레이어)을 항상 바라봄.
  • 캐릭터가 어디로 움직이든 카메라가 시선을 맞춤.
  • 강의에서는 이걸 사용 → 카메라가 항상 플레이어를 보게 만듦.

#② Do Nothing

  • 카메라가 바라보는 방향을 따로 지정하지 않음.
  • 수동으로 회전 설정해야 할 때 사용.

#6. 📐 Follow Offset

  • 카메라와 대상 사이의 거리/높이/앞뒤 간격을 조절하는 값.

  • (X, Y, Z) 값으로 조정:

    • X: 좌우로 이동 (왼쪽/오른쪽 카메라 위치).
    • Y: 높이 (올리면 내려다보는 느낌).
    • Z: 앞뒤 거리 (플레이어와 카메라 사이 간격).
  • 강의에서:

    • Y값 올려서 → 카메라를 위로 올림.
    • Z값 조절해서 → 가까운 뷰 ↔ 멀리서 보는 뷰 변경.

#7. 🌀 Damping (감쇠)

  • 카메라가 대상(플레이어)을 따라갈 때 지연 시간을 주어 자연스럽게 움직이게 함.
  • 3가지 축(X, Y, Z) 각각에 적용 가능.

예시:

  • 0 → 즉각 반응 (딱딱하고 로봇 같은 느낌).
  • 0.2 → 살짝 지연, 부드럽고 자연스러움 (보통 많이 사용).
  • 10 이상 → 카메라가 너무 늦게 따라와서 플레이어가 화면 밖으로 벗어나기도 함.

👉 강의에서는 0.2 정도로 조정해서 적절한 추적 효과를 만듦.


#8. 💡 응용 예시

  • 탑다운 게임: Y값 크게 올려서 위에서 내려다보는 느낌.
  • 3인칭 RPG: Third Person Follow + Z값 뒤로 멀리 설정.
  • 컷신: 여러 Virtual Camera를 배치해서 상황마다 전환.
  • 레이싱 게임: Follow + 낮은 Y값, 뒤쪽 Z값 크게 해서 차량 뷰 연출.

✅ 정리하면:

  • Body → 카메라 위치를 결정.
  • Aim → 카메라 회전을 결정.
  • Follow Offset → 거리·각도 조정.
  • Damping → 움직임의 부드러움.

#{ 🚧 벽 추가와 충돌 시스템 이해하기 }

#📋 목차

  1. 플레이 영역 설정하기
  2. 벽(Obstacle) 만들고 배치하기
  3. 재질(Material) 적용해서 색상 변경하기
  4. 오브젝트 정리와 그룹화
  5. Collider(콜라이더) 이해하기
  6. Rigidbody(리지드바디) 이해하기
  7. Constraints(제약) 옵션 사용하기
  8. Collider 편집과 Trigger 기능

#1. 플레이 영역 설정하기

  • 게임이 진행될 바닥 평면의 크기를 설정해요.
  • 너무 크면 장애물을 많이 배치해야 하고, 너무 작으면 재미가 줄어요.
  • 예시: 바닥 크기를 (3.5, 3.5, 3.5)로 정리해서 깔끔하게 맞춤.
  • Y값은 두께가 없는 평면이라서 사실상 영향 없음.

#2. 벽(Obstacle) 만들고 배치하기

  • **Cube(큐브)**를 이용해서 장애물이나 벽을 만듦.
  • 이름을 Obstacle 1, Obstacle 2... 또는 Wall 1, Wall 2...로 정리하면 관리하기 편함.
  • Ctrl + D → 오브젝트 복제.
  • W → 이동, R → 크기 조절, E → 회전.
  • 벽은 플레이 영역 가장자리를 둘러싸도록 배치해야 플레이어가 밖으로 못 나감.

#3. 재질(Material) 적용해서 색상 변경하기

  • Assets → Create → Material

  • 색상(Color)과 **Smoothness(매끄러움)**을 조절할 수 있음.

  • 벽을 다른 색으로 칠해 구분하기 쉽게 만들 수 있음.

    • 예시: 벽을 어두운 파란색으로 설정.
  • Material을 오브젝트에 드래그해서 적용 가능.


#4. 오브젝트 정리와 그룹화

  • 많은 오브젝트가 생기면 계층(Hierarchy) 창이 복잡해짐.
  • 빈 오브젝트(GameObject → Create Empty)를 만들고 이름을 Environment로 변경.
  • 벽과 장애물을 모두 선택해서 Environment에 넣으면 깔끔하게 그룹화 가능.
  • Hierarchy에서 그룹을 접었다 펼 수 있어 관리가 쉬워짐.

#5. Collider(콜라이더) 이해하기

  • Collider = 충돌 영역을 담당하는 보이지 않는 경계.

  • 대표적인 종류:

    • Box Collider → 네모난 물체
    • Sphere Collider → 구형 물체
    • Capsule Collider → 사람/기둥 모양
  • 콜라이더가 있어야 오브젝트끼리 충돌 감지 가능.

  • Edit Collider 기능 → 콜라이더의 크기와 위치를 직접 조절 가능.


#6. Rigidbody(리지드바디) 이해하기

  • 물리 엔진이 오브젝트를 진짜 물체처럼 인식하게 만드는 컴포넌트.

  • 주요 옵션:

    • Mass (질량) → 무게. 충돌할 때 영향.
    • Drag (저항) → 속도가 줄어드는 정도.
    • Angular Drag (회전 저항) → 회전이 얼마나 빨리 멈추는지.
    • Use Gravity (중력 적용) → 체크하면 바닥으로 떨어짐.
  • 플레이어에 Rigidbody를 추가해야 벽에 부딪히고 멈출 수 있음.


#7. Constraints(제약) 옵션 사용하기

  • Rigidbody 안에 있는 기능.

  • 물리 엔진이 이상하게 움직이는 걸 방지할 수 있음.

  • Freeze Position: 특정 축의 이동을 막음.

    • Y축을 고정 → 점프처럼 위로 튀는 걸 막음.
  • Freeze Rotation: 특정 축의 회전을 막음.

    • 모든 회전 고정(X, Y, Z) → 캐릭터가 부딪혀도 옆으로 쓰러지지 않음.

#8. Collider 편집과 Trigger 기능

  • 기본 충돌은 오브젝트끼리 부딪히고 멈춤.

  • Is Trigger 체크 → 충돌하지 않고 그냥 통과함.

    • 하지만 "통과했는지" 이벤트를 코드에서 감지할 수 있음.
    • 예시: 문을 통과할 때 이벤트 발생, 아이템 획득 구역 만들기 등.
  • 즉,

    • Collider → 벽, 바닥처럼 막는 용도.
    • Trigger → 눈에 안 보이는 "이벤트 발동 구역" 용도.

✅ 정리하자면:

  • Collider = 충돌 감지
  • Rigidbody = 물리 법칙 적용
  • Constraints = 이상한 움직임 방지
  • Trigger = 통과 이벤트 발생