Published on

섹션 2: Delivery Driver

#섹션 2: Delivery Driver

#📋 목차

  1. Transform.rotate 메서드를 이용한 회전
  2. C#에서의 메서드(Method)
  3. Transform.rotate와 transform.translate 활용
  4. 변수를 사용하여 게임 오브젝트의 움직임 조절
  5. Unity에서 변수 직렬화(Serialize)
  6. Unity 인풋 시스템을 활용한 차량 조작
  7. Time.deltaTime을 사용한 프레임률 독립성
  8. Unity 물리 시스템에서 게임 오브젝트 충돌
  9. 충돌 시 콘솔에 메시지 출력
  10. 트리거와 콜라이더의 개념
  11. Unity에서 에셋 추가 및 크기 조정
  12. 게임에서 차량 운전 환경 만들기
  13. Unity에서 팔로우 카메라 만들기
  14. 태그 활용하기
  15. Unity 2D에서 배달 시스템 구현
  16. 배달 시스템 – 물품 픽업과 삭제
  17. Unity에서 자동차 색상 변경
  18. Unity에서 자동차 속도 조절

#{ Transform.rotate 메서드를 이용한 회전 }

이번 강의에서는 **메서드(method)**의 개념을 배우고,

Transform.rotate 메서드를 이용해 Unity에서 캡슐 오브젝트를 회전시키는 방법을 알아봅니다.

#1. 프로젝트 설정

(1) Unity 2D 프로젝트 생성

		Unity Hub에서 새 2D 프로젝트를 생성합니다.

		프로젝트 이름은 자유롭게 설정합니다. (예: delivery driver)

		프로젝트를 생성한 후, Unity 편집기를 실행합니다.

(2) 캡슐 스프라이트 추가

		Hierarchy 창에서 우클릭 → 2D Objects → Sprites → Capsule 추가

		캡슐의 이름을 원하는 이름으로 변경 (예: Cruisy McDrive)

(3) 스크립트 추가

		Assets 창에서 우클릭 → Create → C# Script

		스크립트 이름을 Driver로 지정

		캡슐 오브젝트에 스크립트를 추가

		캡슐 오브젝트를 선택 후, Add Component → Driver 스크립트 추가

		또는, Driver.cs 파일을 드래그하여 캡슐 오브젝트에 추가
Unity 게임 스크린샷

#2. C#에서의 메서드(Method)

(1) 메서드란?

		특정한 작업을 수행하는 코드 블록

		메서드는 호출(call) 되어야 실행됨

		Unity에는 미리 정의된 메서드가 있으며, 직접 메서드를 만들어 사용할 수도 있음
(2) 기본 제공 메서드

		Start()

				게임이 시작될 때 한 번만 실행됨

				void Start()
				{
				    Debug.Log("게임이 시작되었습니다!");
				}



		Update()

				매 프레임마다 실행됨 (초당 60프레임이면 1초에 60번 호출됨)

				void Update()
				{
				    Debug.Log("한 프레임이 지났습니다.");
				}

#3. `Transform.rotate`를 이용한 회전

#(1) `Transform` 컴포넌트란?

게임 오브젝트의 위치(Position), 회전(Rotation), 크기(Scale) 를 조작하는 컴포넌트

transform.rotate() 메서드를 사용하면 회전을 조작할 수 있음

#(2) `Transform.rotate()` 기본 문법

transform.Rotate(x, y, z)
x, y, z: 각 축의 회전 각도(도 단위)

x, y는 그대로 두고 z축만 회전할 예정

#회전 속도 조절하기

너무 빠르게 회전하지 않도록 속도를 조절하려면 프레임 속도에 따라 조정해야 함

Time.deltaTime을 곱해주면 컴퓨터 속도에 관계없이 일정한 속도로 회전 가능
using UnityEngine;

public class Driver : MonoBehaviour
{
    public float rotationSpeed = 45f; // 회전 속도

    void Update()
    {
        transform.Rotate(0, 0, rotationSpeed * Time.deltaTime);
    }
}
초당 45도 회전 (컴퓨터 성능과 관계없이 일정한 속도로 회전)

#Local Rotation과 Global Rotation의 차이

유니티에서 오브젝트를 회전할 때, Global Rotation(월드 좌표 기준 회전) 과

Local Rotation(오브젝트 기준 회전) 두 가지 방식이 있어요. 각각 어떻게 다른지 쉽게 설명해볼게요.

#1. Global Rotation (월드 좌표 기준 회전)

오브젝트가 세계 좌표계(Global Space) 를 기준으로 회전해요.

X, Y, Z축이 고정되어 있음 → 오브젝트가 돌아도 축 방향은 변하지 않음.

예를 들어, 우주에서 지구가 태양 주위를 도는 것처럼 고정된 축을 중심으로 회전하는 거예요.

유니티에서 확인하는 방법:

Inspector에서 Global 모드 선택

씬(Scene) 창에서 회전 축이 항상 같은 방향으로 유지됨.

엘리베이터: 엘리베이터가 위아래로 움직일 때, 맵의 "위" 방향을 따라 올라가야 해. 맵에 고정된 느낌!

태양과 달: 하늘이나 태양이 게임 맵에서 "동쪽에서 서쪽"으로 돌 때, 맵 전체를 기준으로 움직여야 플레이어가 보기 좋아.

다리 회전: 강 위의 회전 다리가 플레이어가 지나가게 열릴 때, 맵의 방향에 맞춰서 돌아야 자연스러워.
transform.rotation = Quaternion.Euler(0, 45, 0) // 월드 기준으로 Y축 45도 회전

#2. Local Rotation (오브젝트 좌표 기준 회전)

오브젝트의 자신의 축(Local Space) 을 기준으로 회전해요.

오브젝트가 회전할 때마다 축 방향이 같이 회전함.

예를 들어, 비행기가 방향을 바꿀 때 기체 자체의 방향을 기준으로 기울어지는 것과 같아요.

유니티에서 확인하는 방법:

Inspector에서 Local 모드 선택

씬(Scene) 창에서 오브젝트가 회전할 때마다 축 방향도 같이 회전함.

선풍기: 선풍기 날개가 돌 때, 선풍기 몸을 기준으로 빙글빙글 돌아야 해. 맵 방향은 신경 안 써!

캐릭터 머리: 캐릭터가 고개를 좌우로 돌릴 때, 몸을 중심으로 돌아야지, 맵 방향 따라 돌면 이상하지.

드릴: 드릴이 땅을 팔 때, 드릴 자체가 제자리에서 빙빙 돌면서 파 들어가야 맞아.
transform.localRotation = Quaternion.Euler(0, 45, 0) // 오브젝트 기준 Y축 45도 회전

#C#에서 숫자 뒤에 `f`를 붙이는 이유

C#에서 숫자 뒤에 f를 붙이는 것은 "이 숫자는 float 타입이다!" 라고 컴파일러에게 알려주는 역할을 해요.
C#에서는 숫자를 기본적으로 double 타입으로 인식해요.

즉, 3.14 같은 숫자는 자동으로 double로 처리돼요.

하지만 float 타입을 원할 경우 숫자 뒤에 f를 붙여야 해요.
float num1 = 3.14f;  // float 타입 (정상)

double num2 = 3.14;   // double 타입 (정상)

float num3 = 3.14;    // 오류 발생! (3.14는 기본적으로 double이므로 float에 넣을 수 없음)

#{ `transform.translate`과 `transform.rotate` 활용 개념 정리 }

이번 강의에서는 Unity에서 transform.translate을 사용하여 오브젝트(자동차)를 앞으로 이동시키는 방법을 배웠습니다.

이전 강의에서는 transform.rotate를 활용하여 회전하는 방법을 익혔고,

이번에는 이동 기능을 추가하여 자동차가 회전하면서 앞으로 나아가도록 만들었습니다.

#1. `transform.rotate`와 `transform.translate`의 차이

📌 transform.Rotate(x, y, z);

		오브젝트를 지정한 각도로 회전시킵니다.

		(x, y, z) 각각의 값은 오일러(Euler) 회전 값으로 적용됩니다.

		예제 코드에서는 transform.Rotate(0, 0, 0.1f);로 매 프레임마다 z축을 기준으로 회전하도록 설정했습니다.

📌 transform.Translate(x, y, z);

		오브젝트를 지정한 방향으로 이동시킵니다.

		(x, y, z) 각각의 값은 해당 축을 따라 이동하는 거리입니다.

		예제 코드에서는 transform.Translate(0, 0.01f, 0);을 사용하여 y축 방향으로 자동차를 이동시켰습니다.

#{`transform.Translate()`랑 `transform.position` 의 차이 }

#1. `transform.Translate(...)`

#현재 위치를 기준으로 상대적인 이동

transform.Translate(0, moveSpeed, 0);
의미: "지금 위치에서 위로 moveSpeed만큼 이동해라."

상대적 이동이야.

내부적으로는 이렇게 작동해:

transform.position += new Vector3(0, moveSpeed, 0);

보통 Time.deltaTime 곱해서 프레임 보정해줘야 해:

transform.Translate(0, moveSpeed * Time.deltaTime, 0);

#2. `transform.position = ...`

#절대 위치를 직접 지정

transform.position = new Vector3(5, 3, 0);
의미: "무조건 이 위치로 텔레포트해라."

기존 위치는 상관없고, 절대 좌표값으로 이동함.

📌 이동도 할 수 있지만, 이동량을 계산해서 직접 더해줘야 해:

transform.position += new Vector3(0, moveSpeed * Time.deltaTime, 0);

#주요 차이 요약

Unity 게임 스크린샷

#언제 뭘 써야 할까?

Unity 게임 스크린샷

#{ 변수를 사용하여 게임 오브젝트의 움직임 조절하기 }

오늘은 변수(Variable) 를 사용하여 게임 오브젝트의 움직임을 조절하는 방법을 배워보겠습니다.

지금까지는 숫자를 직접 코드에 입력하는 방식(하드코딩)으로 자동차를 움직였는데요,

이 방법은 속도를 조절하거나 방향을 변경할 때 불편합니다.

변수를 사용하면 보다 쉽게 값을 변경하고 조작할 수 있습니다.

#1. 변수란 무엇인가요?

변수는 정보를 저장하는 상자 라고 생각하면 됩니다.

이 상자에는 숫자, 문자, 참/거짓 같은 데이터를 담을 수 있습니다.

우리는 변수를 사용하여 게임에서 필요한 값들을 저장하고 필요할 때 꺼내서 사용할 수 있습니다.

변수는 다음과 같은 세 가지 특징을 가집니다.

이름(Name) : 변수를 구별하기 위한 고유한 이름이 필요합니다.

값(Value) : 변수 안에 저장된 실제 데이터입니다.

유형(Type) : 변수에 저장될 데이터의 종류(숫자, 문자 등)를 나타냅니다.
int hitPoints = 20;
이름: hitPoints

값: 20

유형: int(정수형)

#2. 자주 사용하는 변수 유형

Unity 게임 스크린샷
float 값을 사용할 때는 숫자 뒤에 f 를 붙여야 합니다.

예) float speed = 3.8f;

double은 더 높은 정밀도를 제공하지만, 일반적인 게임 개발에서는 float로 충분합니다.

#3. 자동차의 움직임을 변수로 조절하기

public class Driver : MonoBehaviour
{
    float steerSpeed = 0.1f;  // 회전 속도
    float moveSpeed = 0.01f;  // 이동 속도

    void Update()
    {
        transform.Rotate(0, 0, steerSpeed);  // steerSpeed 변수를 사용
        transform.Translate(0, moveSpeed, 0);  // moveSpeed 변수를 사용
    }
}
steerSpeed 변수를 사용하여 회전 속도를 조절합니다.

moveSpeed 변수를 사용하여 이동 속도를 조절합니다.

이제 steerSpeed 와 moveSpeed 값을 변경하면 자동차의 움직임을 조절할 수 있습니다!

#{ Unity에서 변수 직렬화(Serialize)하기 }

#1. **직렬화(Serialization)란?**

직렬화는 데이터를 저장하거나 전송하기 쉽게 변환하는 과정입니다.

Unity에서는 [SerializeField] 어트리뷰트를 사용하여 private 변수도 Inspector 창에서 조정할 수 있도록 직렬화할 수 있습니다.

이를 활용하면 개발자가 아닌 디자이너도 코드 수정 없이 변수 값을 조정할 수 있습니다.
Unity 게임 스크린샷

#2. **Inspector에서 변수를 조정하는 이유**

Inspector 창에서 변수 값을 직접 조정하면, 게임을 실행하면서도 변화를 실시간으로 확인할 수 있습니다.

예를 들어, 자동차 게임에서 **이동 속도(moveSpeed)**와 **조향 속도(steerSpeed)**를

바꿔보면서 어떤 값이 적절한지 실험할 수 있습니다.

개발자가 아니라도 디자이너나 기획자가 직접 게임의 움직임을 조정할 수 있어 협업이 쉬워집니다.

#3. **Unity에서 `[SerializeField]` 사용법**

moveSpeed를 Inspector에서 조정할 수 있도록 변경하기

#1. 변수 앞에 `[SerializeField]` 추가하기

public class Driver : MonoBehaviour
{
    [SerializeField] float moveSpeed = 0.01f;
}
기존에는 private 변수이기 때문에 Inspector 창에서 보이지 않았지만,

[SerializeField]를 추가하면 Inspector 창에서 값을 변경할 수 있습니다.

#2. Unity에서 확인하기

Ctrl + S를 눌러 저장한 후 Unity로 돌아갑니다.

자동차 오브젝트를 클릭하면 Inspector 창에 moveSpeed가 나타남을 볼 수 있습니다.

moveSpeed 값을 0.03으로 바꾼 후 게임을 실행하면, 자동차가 더 빠르게 움직이는 것을 확인할 수 있습니다.

#4. Inspector에서 변경된 값은 어떻게 적용될까?

moveSpeed를 코드에서 0.01로 설정했더라도, Inspector에서 변경하면 Unity는 변경된 값을 사용합니다.

예를 들어, Inspector에서 0.03으로 바꾸면, 코드를 다시 실행하더라도 0.03이 적용됩니다.

따라서, 코드에서 기본값을 설정하더라도 Inspector에서 덮어씌워질 수 있다는 점을 기억하세요.

#{ Unity에서 인풋 시스템을 활용한 차량 조작 개념 정리 }

#1. **인풋 시스템이란?**

인풋 시스템(Input System)이란, 플레이어가 키보드, 마우스,

게임패드 등의 입력 장치를 통해 게임 내에서 캐릭터나 오브젝트를 조작할 수 있도록 하는 시스템입니다.
Unity 게임 스크린샷

#Unity의 인풋 시스템 종류

#올드 시스템 (Old Input System)

Input.GetAxis() 또는 Input.GetKey() 같은 함수를 사용하여 키보드, 마우스 등의 입력을 감지

기존 Unity 버전에서 기본적으로 제공하는 방식

간단한 프로젝트에 적합

#뉴 시스템 (New Input System)

최신 Unity에서는 더 정교한 입력 처리를 위한 새로운 Input System이 도입됨

보다 복잡한 입력 처리와 사용자 지정이 가능
이 강의에서는 올드 시스템을 사용하여 기본적인 차량 조작을 구현합니다.

#2. **Unity의 인풋 매니저 이해하기**

Unity는 기본적으로 Project Settings > Input Manager에서 여러 축(axis)에 대한 정보를 제공하며,

기본적으로 사용 가능한 축에는 다음과 같은 것들이 있습니다.

#주요 축 (Axes)

Horizontal (수평축)

		키보드의 A 또는 왼쪽 방향키(←) → -1

		키보드의 D 또는 오른쪽 방향키(→) → +1

		기본적으로 좌우 이동을 담당

Vertical (수직축)

		키보드의 W 또는 위쪽 방향키(↑) → +1

		키보드의 S 또는 아래쪽 방향키(↓) → -1

		기본적으로 앞뒤 이동을 담당
Unity는 이러한 축을 통해 조이스틱이나 게임패드도 지원하므로,

추가적인 설정 없이도 기본적인 입력 처리가 가능합니다.

#3. **차량 이동을 위한 코드 분석**

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Driver : MonoBehaviour
{
    [SerializeField] float steerSpeed = 0.1f;  // 회전 속도
    [SerializeField] float moveSpeed = 0.01f;  // 이동 속도

    void Update()
    {
        // 입력 값 가져오기
        float steerAmount = Input.GetAxis("Horizontal") * steerSpeed;
        float moveAmount = Input.GetAxis("Vertical") * moveSpeed;

        // 차량 회전
        transform.Rotate(0, 0, -steerAmount);

        // 차량 이동
        transform.Translate(0, moveAmount, 0);
    }
}
위 코드에서 -steerAmount를 사용하면 반대 방향 문제 해결 가능.

왼쪽(←)을 누르면 steerAmount가 -1이므로 -(-1) = +1 → 올바른 방향 회전

오른쪽(→)을 누르면 steerAmount가 +1이므로 -(+1) = -1 → 올바른 방향 회전

Unity의 Rotate() 메서드에서 z 축을 기준으로 회전할 때,

양수(+) 값을 주면 반시계 방향(왼쪽 회전)

음수(-) 값을 주면 시계 방향(오른쪽 회전)

즉 오른쪽을 누르면 음수가 되어야 오른쪽으로 이동 한다는 것

#{ Unity에서 Time.deltaTime을 사용한 프레임률 독립성 개념 정리 }

#1. 문제점: 컴퓨터 성능에 따른 움직임 차이

게임을 만들 때 가장 중요한 개념 중 하나는 프레임률 독립성입니다.

즉, 게임이 실행되는 컴퓨터가 느리든 빠르든, 모든 플레이어가 같은 경험을 해야 한다는 것입니다.

하지만 현재 코드에서 자동차는 매 프레임마다 움직이도록 설정되어 있습니다.

이렇게 되면 빠른 컴퓨터에서는 더 자주 프레임이 실행되므로 자동차가 더 빠르게 움직이고,

반대로 느린 컴퓨터에서는 프레임이 적게 실행되어 자동차가 느리게 움직이게 됩니다.

결국, 컴퓨터의 성능에 따라 게임 플레이가 달라지는 문제가 발생합니다.

#2. Time.deltaTime이란?

이 문제를 해결하기 위해 Unity는 Time.deltaTime이라는 개념을 제공합니다.

Time.deltaTime은 이전 프레임이 끝나고 현재 프레임이 시작될 때까지 걸린 시간을 의미합니다.

즉, 한 프레임이 실행되는 데 걸리는 시간을 초 단위로 반환합니다.

		예시

				느린 컴퓨터 (초당 10프레임)

						1초에 10프레임 → 1프레임당 0.1초 소요 (1 / 10 = 0.1)

				빠른 컴퓨터 (초당 100프레임)

						1초에 100프레임 → 1프레임당 0.01초 소요 (1 / 100 = 0.01)

이 값을 곱해주면 컴퓨터의 성능에 관계없이 동일한 결과를 얻을 수 있습니다.

#3. Time.deltaTime을 활용한 해결 방법

기존 코드에서 steerAmount와 moveAmount에 Time.deltaTime을 곱하면

컴퓨터가 빠르든 느리든 동일한 결과를 얻게 됩니다.
public class Driver : MonoBehaviour
{
    [SerializeField] float steerSpeed = 300f;
    [SerializeField] float moveSpeed = 20f;

    void Update()
    {
        float steerAmount = Input.GetAxis("Horizontal") * steerSpeed * Time.deltaTime;
        float moveAmount = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;
        transform.Rotate(0, 0, -steerAmount);
        transform.Translate(0, moveAmount, 0);
    }
}

#4. Time.deltaTime을 적용하면 왜 속도가 느려질까?

기존에는 steerSpeed와 moveSpeed를 그냥 곱했기 때문에 프레임이 많아지면 속도도 더 빨라졌습니다.

하지만 Time.deltaTime을 추가하면 속도가 줄어들어 보일 수 있습니다.

이유는 Time.deltaTime이 **0보다 작은 값(예: 0.01)**을 곱하기 때문입니다.

#**{ Unity 물리 시스템에서 게임 오브젝트 충돌 구현 }**

이번 강의에서는 Unity에서 두 개의 게임 오브젝트를 추가하고,

콜라이더(Collider) 와 리지드 바디(Rigidbody) 를 이용하여 충돌하는 동작을 구현하는 방법을 배웁니다.

#**1. 부딪힐 대상 추가하기**

#**새로운 게임 오브젝트 추가**

1. Hierarchy 창에서 [2D 오브젝트] - [스프라이트] 선택

2. 원(circle) 또는 사각형(square) 모양의 스프라이트 추가

3. 적절한 이름 지정 (예: "CircleObject")

4. 위치 조정: W 키를 눌러 이동, R 키를 눌러 크기 조정

5. 색상 변경: Inspector 창에서 Sprite Renderer의 색상 필드 클릭 후 원하는 색상 선택

#**2. 충돌 감지를 위한 콜라이더 추가**

콜라이더(Collider) 는 Unity에서 물체의

물리적 충돌을 감지하는 경계 영역을 정의하는 구성 요소입니다.
Unity 게임 스크린샷 Unity 게임 스크린샷

#**콜라이더 추가 방법**

1. 자동차(Player) 오브젝트 선택

2. Inspector 창에서 [Add Component] 클릭 후 collider 검색

3. 2D 용 콜라이더 선택 (예: Capsule Collider 2D)

4. 추가된 콜라이더 확인 (녹색 테두리 형태)

5. Sprite Renderer 비활성화하여 충돌 영역만 확인 가능

#**부딪힐 대상에도 콜라이더 추가**

1. 원(circle)을 선택하고 [Add Component]에서 Circle Collider 2D 추가

2. 사각형(square)이라면 Box Collider 2D 추가

3. 충돌 영역이 오브젝트 크기에 맞게 생성됨을 확인

이제 Unity는 이 두 오브젝트가 충돌하는 것을 감지할 수 있음

#**3. 리지드 바디(Rigidbody) 추가**

리지드 바디(Rigidbody) 는 Unity의 물리 시스템에서

오브젝트를 실제 물체처럼 동작하게 만드는 구성 요소입니다. ( 중력등 물리 효과 추가 )
Unity 게임 스크린샷

#**리지드 바디 추가 방법**

Unity 게임 스크린샷
1. 자동차(Player) 오브젝트 선택

2. Inspector 창에서 [Add Component] 클릭 후 Rigidbody 2D 추가

3. 추가 후 자동차가 아래로 떨어지는 현상 발생 (중력 때문)

4. 중력(Gravity Scale)을 0으로 변경하여 중력 영향 제거

#**부딪힌 오브젝트도 움직이게 만들기**

1. 원(circle) 오브젝트 선택 후 Rigidbody 2D 추가

2. 중력(Gravity Scale)을 0으로 설정

3. 자동차가 부딪힐 때 원이 밀리는 것을 확인 가능

#Unity에서 충돌을 감지하는 방법

Unity에서 충돌을 감지하려면 두 가지 요소가 필요합니다.

#리지드바디(Rigidbody 2D)

물리 엔진을 적용하여 오브젝트가 중력, 충돌, 힘의 영향을 받도록 합니다.

하나 이상의 오브젝트에 반드시 Rigidbody 2D가 있어야 충돌이 감지됩니다.

(적어도 한 개의 오브젝트에는 꼭 Rigidbody 2D가 있어야 합니다!)

#콜라이더(Collider 2D)

오브젝트가 충돌 가능한 경계를 정의하는 컴포넌트입니다.

Box Collider 2D, Circle Collider 2D, Polygon Collider 2D 등 여러 종류가 있습니다.

콜라이더끼리 겹치는 순간 충돌이 발생합니다.

#{ 충돌 시 콘솔에 메시지를 출력 }

이번에는 간단하게 충돌 시 콘솔에 메시지를 출력하는 기능을 만들어보겠습니다.

#충돌 감지 코드 작성하기

#새로운 스크립트 파일 만들기

1. Assets 창에서 우클릭 → Create → C# Script 클릭

2. 파일 이름을 Collision으로 저장

3. 파일을 더블 클릭하여 Visual Studio 또는 Rider에서 엽니다.

#기본적인 충돌 감지 코드

using UnityEngine;

public class Collision : MonoBehaviour
{
    void OnCollisionEnter2D(Collision2D collision)
    {
        Debug.Log("충돌 발생!");
    }
}
Unity 게임 스크린샷

#핵심 개념 정리

MonoBehaviour : Unity에서 스크립트를 적용하기 위해 반드시 필요한 기본 클래스

OnCollisionEnter2D(Collision2D collision) : 오브젝트가 다른 오브젝트와 부딪힐 때 실행되는 Unity 내장 함수

Debug.Log("충돌 발생!");	충돌이 감지되면 콘솔 창에 메시지 출력

#Unity에서 스크립트 적용하기

코드를 작성했으면, 플레이어 캐릭터에 스크립트를 추가해야 합니다.

		🎯 적용 방법

		1. 플레이어 오브젝트를 클릭합니다.

		2. Inspector 창에서 Add Component 버튼을 클릭합니다.

		3. Collision 스크립트를 검색하여 추가합니다.
			 (또는 Assets 창에서 드래그해서 추가할 수도 있습니다.)

		4. Play 버튼을 눌러 테스트합니다.

		5. 오브젝트가 다른 오브젝트와 부딪힐 때 콘솔 창에 "충돌 발생!" 메시지가 뜨는지 확인합니다.
Unity 게임 스크린샷

#추가 개념: `private` 키워드

private void OnCollisionEnter2D(Collision2D collision)
private 키워드는 해당 클래스 내부에서만 사용 가능하다는 의미입니다.

OnCollisionEnter2D는 Unity에서 자동으로 호출하는 함수이기 때문에, private을 생략해도 정상 작동합니다.

✔️ private을 삭제해도 충돌 감지는 정상적으로 동작합니다.

✔️ public으로 변경해도 문제없지만, 이 함수는 Unity 엔진에서 내부적으로 호출하는 것이므로 굳이 public으로 만들 필요는 없습니다.

#{ 트리거와 콜라이더의 개념 및 사용법 정리 }

게임 개발에서 충돌(Collision) 과 트리거(Trigger) 는 중요한 개념입니다.

이를 활용하면 플레이어가 장애물에 부딪히거나 특정 영역을 지나갈 때 원하는 동작을 수행할 수 있습니다.

#1. 콜라이더(Collider)란?

콜라이더(Collider)는 게임 오브젝트(GameObject)의 물리적인 경계를 정의하는 컴포넌트입니다.

게임에서 충돌 감지를 위해 필수적으로 사용됩니다.

콜라이더는 크게 두 가지 종류가 있습니다.

#1. 일반 콜라이더 (충돌 감지)

물체가 부딪히면 멈추거나 튕겨 나가는 등의 물리적 반응이 발생합니다.

예시: 벽, 바닥, 장애물 등의 역할을 하는 오브젝트.

#2. 트리거(Trigger) (통과 가능, 이벤트 발생)

충돌하지 않고 오브젝트를 통과할 수 있지만, 특정 이벤트를 감지할 수 있음.

예시: 체크포인트, 문을 통과하는 이벤트, 특정 지역에 들어갔을 때 발생하는 효과 등.
Unity 게임 스크린샷

#2. 트리거 설정 방법

#1. 트리거 오브젝트 만들기

1. 새로운 2D 오브젝트 추가

		Hierarchy 창 → 우클릭 → [2D Object] - [Physics] - [Square]

2. 위치와 크기 조정

		오브젝트를 위쪽으로 이동하고, 크기를 적절히 키웁니다.

3. 색상 변경

		Inspector 창 → Sprite Renderer → 색상을 원하는 색상(예: 핑크)으로 변경.

#2. Box Collider 2D 추가

1. Inspector 창에서 Add Component 클릭

2. Box Collider 2D 추가

3. Is Trigger 옵션 체크 ✅

이제 이 오브젝트는 플레이어가 부딪히지 않고 통과할 수 있음.

#3. 트리거 이벤트 감지하는 코드

Unity에서 트리거를 감지하는 함수는 OnTriggerEnter2D입니다.

아래 코드를 Collision.cs 스크립트에 추가하면 트리거 영역을 지나갈 때 콘솔에 메시지가 출력됩니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Collision : MonoBehaviour
{
    // 충돌 감지 (일반 충돌)
    void OnCollisionEnter2D(Collision2D collision)
    {
        Debug.Log("충돌 발생");
    }

    // 트리거 감지 (통과 가능한 충돌)
    void OnTriggerEnter2D(Collider2D collision)
    {
        Debug.Log("방금 뭐야!?");  // 플레이어가 트리거에 닿았을 때 출력
    }
}
Unity 게임 스크린샷

#4. 트리거 활용 예시

1. 체크포인트 시스템

		트리거를 지나가면 체크포인트가 저장되어 플레이어가 죽었을 때 해당 지점에서 다시 시작할 수 있음.

2. 문을 통과할 때 이벤트 발생

		특정 지역에 들어가면 문이 자동으로 열림.

3. 적 인공지능(AI) 감지 시스템

		적이 플레이어의 위치를 감지할 때 트리거를 활용 가능.

4. 스테이지 변경

		특정 위치에 도달하면 다음 스테이지로 이동하는 기능 구현.

#{ 유니티에서 에셋 추가 및 크기 조정 개념 정리 }

#1. **에셋 추가하기**

제공된 에셋을 다운로드하고 압축을 해제한다.

압축을 풀면 차, 도로 등의 에셋이 들어있는 폴더가 보인다.

유니티에서 에셋 폴더로 드래그하여 가져온다. (폴더째로 옮기는 것이 효율적)

#2. **유니티에서 에셋 크기 확인하기**

에셋을 **씬(Scene)**에 드래그하여 추가하고 크기를 확인한다.

각 에셋이 적절한 크기인지 비교하고 조정한다.

기본적으로 유니티에서 오브젝트 크기를 조정하는 방법:

		스케일(Scale) 툴을 사용하거나 R 키를 눌러 크기 조정

		하지만 모든 오브젝트를 하나씩 조정하는 것은 비효율적

#3. **픽셀과 스프라이트 개념**

스프라이트(Sprite): 픽셀로 이루어진 이미지

픽셀(Pixel): 디지털 이미지에서 가장 작은 단위

해상도(Resolution): 픽셀 개수에 따라 달라지며, 많을수록 선명함

예제: 8x8 픽셀 크기의 하트는 총 64개의 픽셀로 구성됨

#4. **유니티 단위(Unity Unit)란?**

Unity 게임 스크린샷
유니티에서 오브젝트의 크기를 정하는 단위 (실제 단위와 상관없음)

기본적으로 1 유니티 단위 = 100픽셀

개발자가 원하는 단위로 가정할 수 있음 (예: 1 유니티 단위 = 1m)

#5. **유니티에서 오브젝트 크기 측정**

Unity 게임 스크린샷
씬에서 오브젝트를 클릭하면 Transform 창에서 위치와 크기 확인 가능

예제:

자동차의 너비 ≈ 2 유니티 단위

자동차의 높이 ≈ 3 유니티 단위

실제 자동차 크기(3m x 2m)와 비슷

#6. **단위당 픽셀(Pixels Per Unit, PPU) 조정**

기본값: 100 PPU (1 유니티 단위 = 100픽셀)

값을 줄이면 이미지가 커지고, 늘리면 작아짐

		예제:

		100 → 50 PPU: 2배 커짐

		100 → 200 PPU: 2배 작아짐

		100 → 25 PPU: 4배 커짐
Unity 게임 스크린샷

#7. **여러 개의 스프라이트 크기 조정**

여러 개를 한꺼번에 선택해서 PPU 값을 변경 가능

도로, 나무, 집 등의 오브젝트를 한 번에 조정하면 효율적

예제:

집: 25 PPU

나무: 50 → 25 PPU (크기 조정)

도로: 75 PPU

#8. **추가적인 크기 조정**

단위 당 픽셀을 조정한 후에도 스케일 기능으로 개별 크기 변경 가능

같은 에셋이라도 크기를 다르게 만들어 변화를 줄 수 있음
Unity 게임 스크린샷

#{ 게임에서 차량 운전 환경 만들기 }

이번 강의에서는 게임에서 차량을 운전할 수 있는 환경을 설정하는 방법을 배웁니다.

#1. 차량 오브젝트 설정

#(1) 기존 캡슐 오브젝트에서 차량으로 변경

현재 게임에서는 캡슐 모양 오브젝트가 운전되고 있습니다.

이를 실제 차량 스프라이트로 변경해봅시다.

#(2) 차량 스프라이트 변경하기

1. 운전할 게임 오브젝트 선택

		"맥드라이브" 오브젝트를 선택합니다.

		Sprite Renderer 컴포넌트를 확인합니다.

2. 새로운 차량 이미지 적용

		"Target Selector"를 클릭하여 사용 가능한 스프라이트 리스트를 확인합니다.

		검색창에서 '차'를 검색해 원하는 차량을 선택합니다.

		저는 "차 3"을 선택했습니다.

3. 플레이 테스트

		플레이 버튼을 누르면 새로운 차량이 움직이는 것을 확인할 수 있습니다.
Unity 게임 스크린샷

#2. 충돌 감지 (Collider) 설정

#(1) 문제점: 차량이 오브젝트와 자연스럽게 충돌하지 않음

차량이 벽에 부딪힐 때, 일부가 겹쳐지는 문제가 발생합니다.

#(2) 콜라이더 수정

1. 기존 캡슐 콜라이더 삭제

		**"Capsule Collider"**를 찾아 우클릭 후 삭제합니다.

2. 박스 콜라이더 추가 및 조정

		Box Collider를 찾아 선택합니다.

		"Edit Collider" 버튼을 눌러 초록색 조절점을 조정합니다.

		차량 모양에 맞게 콜라이더 크기를 조정합니다.

3. 테스트

		플레이 버튼을 눌러 다시 확인하면, 차량이 자연스럽게 오브젝트와 충돌합니다.
Unity 게임 스크린샷 Unity 게임 스크린샷

#3. 게임 오브젝트 정리 (Hierarchy 구조화)

Unity 게임 스크린샷

#(1) 문제점: 오브젝트가 정리되지 않음

Hierarchy 창에서 오브젝트들이 무질서하게 나열되어 있습니다.

#(2) 그룹화 및 정리

1. 빈 게임 오브젝트 생성

		Hierarchy 창에서 우클릭 → Create Empty 선택

		새 오브젝트의 이름을 "World Objects" 로 변경

2. 모든 오브젝트를 하위 오브젝트로 이동

		Shift 키를 눌러 집, 바위, 나무 등 여러 오브젝트를 선택

		"World Objects"로 드래그하여 그룹화

3. Transform 값 초기화

		"World Objects"의 Transform을 0,0,0으로 리셋합니다.

		이제 World Objects를 한꺼번에 이동할 수 있습니다.
Unity 게임 스크린샷

#5. 오브젝트별 충돌 설정

(1) 집에 콜라이더 추가

		집 오브젝트 선택 → Box Collider 2D 추가

		이제 차량이 집과 충돌하면 멈춥니다.

(2) 나무에 원형 콜라이더 적용

		Circle Collider 2D를 추가하면 자연스러운 충돌 효과를 얻을 수 있습니다.

정확한 배치를 위해 Snapping 활용

		Global → Snapping Mechanism을 활성화하면 유니티 단위에 맞춰 정렬할 수 있습니다.
Unity 게임 스크린샷

#배경 색상 변경

(1) 현재 문제: 기본 배경색(파란색)이 어색함

		현재 배경이 하늘색으로 되어 있어 도로와 맞지 않음.

(2) 배경색 변경 방법

		메인 카메라 선택

		"Background" 색상 변경

		풀밭 색상으로 변경하여 자연스럽게 만듭니다.
Unity 게임 스크린샷

#{ Unity에서 팔로우 카메라 만들기 }

우리는 주행하는 자동차를 따라가는 팔로우 카메라를 만들 것입니다.

즉, 자동차가 어디로 가든지 카메라는 자동차를 중심으로 화면에 표시해야 합니다.

이 기능을 코드를 이용해서 구현해보겠습니다.

#유니티에서 "레퍼런스(Reference)"란?

**레퍼런스(Reference)**는 **어떤 오브젝트나 변수의 "주소"**를 가리키는 개념이야.

쉽게 말해서, 어떤 걸 직접 들고 있는 게 아니라 "그게 어디 있는지" 가리키는 것이야!

#쉽게 이해하는 레퍼런스 개념

📌 비유 1: 집 주소와 실제 집

집 주소 = 레퍼런스 (Reference)

실제 집 = 오브젝트 (Object)

🔸 친구 집을 방문하려면, 친구의 **집 주소(Reference)**를 알아야 해.
🔸 하지만 집 주소만 있다고 실제 집이 생기는 건 아니지?
🔸 마찬가지로, 유니티에서 레퍼런스를 가졌다고 해서 실제 오브젝트가 생기는 건 아님!

#유니티에서 레퍼런스를 쓰는 이유

1️⃣ 오브젝트를 직접 복사하지 않고 효율적으로 관리하기 위해!
2️⃣ 하나의 오브젝트를 여러 군데에서 사용할 수 있도록!

#❌ 잘못된 코드 (레퍼런스 없이 새로 만들기)

GameObject player = new GameObject(); // 새로운 오브젝트 생성 (잘못된 방법!)
🔺 이렇게 하면 매번 새로운 오브젝트가 생성됨!
🔺 기존 오브젝트를 가리키는 게 아니라, 새로운 오브젝트를 만들어버림.

#올바른 코드 (레퍼런스 사용)

public GameObject player; // 인스펙터에서 직접 연결 가능

void Start()
{
    player.transform.position = new Vector3(0, 0, 0); // 기존 오브젝트 이동
}
🔹 player 변수는 새로운 오브젝트를 만들지 않고, 기존 오브젝트를 가리킴(참조함)!
🔹 메모리를 아낄 수 있고, 오브젝트를 중복 생성하는 실수를 방지함.

유니티에서는 public 변수로 선언된 오브젝트는 인스펙터 창에서 드래그 앤 드롭으로 연결할 수 있어요.

그러니까 player에 어떤 실제 오브젝트를 연결해야 오류가 발생하지 않아요.

#public 이 있는데 왜 `[SerializeField]`를 사용하는가?

캡슐화:

		변수에 대한 외부 접근을 제한하고 싶을 때 사용합니다.

		예를 들어, 변수는 외부에서 수정하지 못하게 하고, 유니티 에디터에서는만 수정할 수 있게 하죠.

코드의 안전성:

		public으로 선언하면 외부에서 값을 변경할 수 있기 때문에

		예기치 않은 오류가 발생할 수 있습니다. private으로 선언하고 [SerializeField]로 인스펙터에서만 수정하게 하면,

		코드에서 직접적으로 변경되는 일이 없으므로 코드가 더 안전해집니다.

#1단계: 카메라 위치 이해하기

Unity에서 카메라는 GameObject입니다.

카메라의 위치를 바꾸면 보이는 화면이 달라집니다.

1. Scene 뷰에서 카메라를 이동해 보면, 카메라가 보는 화면이 변하는 것을 알 수 있습니다.

2. 자동차가 (13,5) 위치에 있으면, 카메라도 같은 (13,5) 위치로 이동해야 합니다.

3. 단, 카메라가 자동차와 너무 가까우면 안 되므로

	 Z축 방향으로 약간 뒤로 이동해야 합니다. ( 2D여서 서로 완전 같은 0 이면 겹쳐져서 아무것도 보이지 않는다 )

#2단계: 스크립트 생성하기

이제 카메라가 자동차를 따라다니도록 FollowCamera 스크립트를 만들어 봅시다.

#스크립트 생성 방법

Unity에서 Project 창 → 우클릭 → Create → C# Script 선택

파일 이름을 FollowCamera라고 설정 (대문자 F, C 사용)

FollowCamera.cs 파일을 열어 코드를 작성

#3단계: 기본 코드 작성

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FollowCamera : MonoBehaviour
{
    [SerializeField] GameObject thingToFollow; // 따라갈 대상 (자동차)

    void LateUpdate()
    {
        transform.position = thingToFollow.transform.position + new Vector3(0, 0, -10);
    }
}
1. [SerializeField] GameObject thingToFollow;

		자동차를 따라가야 하므로, 따라갈 대상을 변수로 저장

		SerializeField를 사용하면 Unity Inspector 창에서 직접 설정 가능

2. LateUpdate() 메서드 사용

		Update()가 아니라 LateUpdate()를 사용

		이유: 자동차의 움직임이 끝난 후, 카메라가 마지막에 따라가도록 하기 위함

		카메라가 자동차보다 먼저 움직이면 화면이 흔들릴 수 있기 때문

3. 카메라 위치 조정 (+ new Vector3(0, 0, -10))

		자동차 위치를 따라가되, Z축 방향으로 -10만큼 뒤로 이동

		Z축은 화면의 앞뒤 방향 → 카메라를 적절히 뒤로 배치해야 자동차가 잘 보임

#4단계: Unity에서 스크립트 적용하기

#스크립트 연결 방법

1. Main Camera 선택

2. Inspector 창에서 "Add Component" 클릭 → FollowCamera 스크립트 추가

3. Thing To Follow (자동차) 연결

		Thing To Follow 옆의 동그라미 버튼 클릭 → 자동차 선택

		또는 자동차를 직접 드래그하여 넣기
Unity 게임 스크린샷

#Unity 실행 순서 이해하기

주요 실행 순서

1. Awake() → 게임이 시작될 때 실행 (거의 사용 X)

2. Start() → 게임이 시작된 직후 실행

3. Update() → 매 프레임마다 실행 (일반적인 업데이트)

4. FixedUpdate() → 물리 엔진 관련 계산 시 사용

5. LateUpdate() → 모든 Update 실행 후 마지막에 실행

#왜 LateUpdate를 사용할까?

카메라가 자동차를 따라가려면 자동차가 먼저 움직이고, 카메라가 나중에 움직여야 함

Update()를 사용하면? → 자동차보다 먼저 카메라가 움직일 수도 있음 → 흔들림 발생 가능

LateUpdate()를 사용하면? → 자동차의 모든 이동이 끝난 후 카메라가 따라감 → 부드러운 동작

#{ 태그 활용하기 }

#1. **게임의 목표**

자동차가 Package(물품)를 픽업하고 Customer(고객)에게 배달하는 게임을 만든다.

#2. **충돌 감지와 트리거**

Unity에서 오브젝트끼리 충돌을 감지하려면 두 가지 방법이 있다.

1. OnCollisionEnter2D (물리적 충돌 감지)

		콜라이더(Collider)와 Rigidbody 2D가 있어야 작동한다.

		오브젝트가 다른 오브젝트와 실제로 부딪혔을 때 실행된다.

		isTrigger가 체크되지 않은 상태여야 한다.

		예: 자동차가 벽과 부딪힐 때 사용.

2. OnTriggerEnter2D (트리거 감지)

		isTrigger를 체크한 상태에서 사용한다.

		오브젝트가 실제로 부딪히지 않아도 통과할 때 이벤트가 발생한다.

		예: 자동차가 Package 위를 지나갈 때 사용.

#3. **태그(Tag)란?**

태그는 게임 오브젝트를 특정 그룹으로 분류하는 데 사용된다.

오브젝트를 구분하는 라벨 같은 역할.

collision.CompareTag("태그이름")을 사용해 특정 태그가 있는 오브젝트와 충돌했는지 확인 가능.

#4. **게임 오브젝트 설정하기 ( 태그 추가하기 )**

Unity 게임 스크린샷 Unity 게임 스크린샷
1. 물품(Package) 만들기

		사각형(Square) 오브젝트를 추가하고 이름을 Package로 변경.

		Inspector 창에서 태그(Tag) → "Add Tag..." → "Package" 추가.

		다시 Package 오브젝트를 클릭해 태그를 **"Package"**로 설정.

		Box Collider 2D 추가 → Is Trigger 체크.


2. 고객(Customer) 만들기

		새로운 사각형 오브젝트를 추가하고 이름을 Customer로 변경.

		태그 "Customer" 추가 후 적용.

		Box Collider 2D 추가 → Is Trigger 체크.

#5. **C# 코드 작성하기**

다음과 같이 Delivery 스크립트를 만들어 적용한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Delivery : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D collision)
    {
        // Package 태그를 가진 오브젝트와 접촉하면
        if(collision.CompareTag("Package"))
        {
            Debug.Log("물품 픽업 됨");
        }

        // Customer 태그를 가진 오브젝트와 접촉하면
        if(collision.CompareTag("Customer"))
        {
            Debug.Log("물품 배달 됨");
        }
    }
}

#Customer , Package 에 Delivery 스크립트 적용

Unity 게임 스크린샷

#{ Unity 2D에서 배달 시스템 구현하기 }

이번 강의에서는 플레이어가 물품을 배달하는 시스템을 구현하고,

여러 번 배달하는 문제를 해결하는 방법을 배웁니다.

bool 변수를 이용하여 물품을 가지고 있는지 여부를 확인하는 방식으로 구현합니다.

#1. bool 변수란?

bool(불리언) 변수는 참(true) 또는 거짓(false) 두 가지 값만 가질 수 있는 변수입니다.

주로 if문과 함께 사용하여 특정 조건이 참인지 거짓인지 확인하는 데 활용됩니다.

#구현 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Delivery : MonoBehaviour
{
    // 플레이어가 물품을 가지고 있는지를 저장하는 변수 (기본값: false)
    bool hasPackage;

    // 플레이어가 다른 객체와 충돌했을 때 호출되는 함수
    void OnCollisionEnter2D(Collision2D collision)
    {
        // 충돌이 발생하면 콘솔에 메시지를 출력
        Debug.Log("충돌 발생");
    }

    // 플레이어가 트리거(Trigger) 객체와 충돌했을 때 호출되는 함수
    void OnTriggerEnter2D(Collider2D collision)
    {
        // 충돌한 객체가 'Package' 태그를 가지고 있다면
        if (collision.CompareTag("Package"))
        {
            Debug.Log("Package 트리거 발생"); // 콘솔에 메시지 출력
            hasPackage = true; // 물품을 주웠다고 표시
        }

        // 충돌한 객체가 'Customer' 태그를 가지고 있고, 물품을 가지고 있을 때
        if (collision.CompareTag("Customer") && hasPackage)
        {
            Debug.Log("Customer 배달 성공"); // 배달 완료 메시지 출력
            hasPackage = false; // 물품을 배달했으므로 다시 물품이 없는 상태로 변경
        }
    }
}

#{ 배달 시스템 구현 – 물품 픽업과 삭제 }

이번 강의에서는 배달 게임에서 물품을 픽업하고 사라지게 만드는 방법을 배웁니다.

핵심 개념은 다음과 같습니다.

플레이어가 물품을 한 번에 하나씩만 픽업할 수 있도록 제한

픽업한 물품은 일정 시간 후 사라지게 만들기

배달 후 새로운 물품을 다시 픽업할 수 있도록 로직 구현
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Delivery : MonoBehaviour
{
    bool hasPackage;
    [SerializeField] float destroyDelay = 0.5f; // 삭제 지연 시간 (인스펙터에서 조정 가능)

    void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.CompareTag("Package") && !hasPackage)
        {
            Debug.Log("Package 트리거 발생");
            hasPackage = true;
            Destroy(collision.gameObject, destroyDelay); // 일정 시간 후 물품 삭제
        }

        if(collision.CompareTag("Customer") && hasPackage)
        {
            Debug.Log("Customer 배달 성공");
            hasPackage = false; // 배달 후 새로운 물품 픽업 가능
        }
    }
}
Destroy() 함수를 사용하여 물품이 사라지게 만듦

SerializedField를 활용해 삭제 시간을 인스펙터에서 조정 가능하도록 설정

한 번에 하나의 물품만 픽업할 수 있도록 제한 (hasPackage 변수 활용)

고객에게 배달 후 새로운 물품을 다시 픽업 가능하도록 설정

#Destroy() 함수 이해하기

Destroy() 함수는 게임 오브젝트를 씬에서 삭제하는 기능을 합니다.

이 함수는 두 가지 인자를 가질 수 있습니다.

첫 번째 인자: 제거할 게임 오브젝트

두 번째 인자(선택 사항): 제거되기까지의 딜레이(초 단위)
Destroy(오브젝트, 딜레이);

#{ 유니티에서 자동차 색상 변경 }

플레이어(자동차)가 물품을 픽업하면 초록색으로 변하고

물품을 배달하면 원래 색깔로 돌아오게 만들기

즉, 자동차 색을 바꿔서 플레이어가 현재 어떤 상태인지 쉽게 알 수 있도록 만들기!

#1. 자동차 색을 바꾸는 방법

자동차의 색상을 바꾸는 방법은 여러 가지가 있지만, 이번에는 "색조(Tint)" 를 사용해 변경합니다.

❌ 자동차 스프라이트(이미지)를 직접 변경하는 방법은?

같은 디자인의 다른 색 자동차 이미지가 없다면 어렵습니다.

갑자기 차가 노란 컨버터블로 변하면 이상하겠죠?

대신 "Tint(색조)" 기능을 사용하면 같은 이미지 위에 색을 입힐 수 있습니다!

유니티의 Sprite Renderer(스프라이트 렌더러) 를 이용하면 이미지의 색상을 변경할 수 있습니다.

#2. Sprite Renderer(스프라이트 렌더러)란?

Unity 게임 스크린샷
Sprite Renderer = 게임 오브젝트의 이미지를 표시하는 컴포넌트(부품)

이 안에는 여러 속성이 있는데, 우리는 color(색상) 속성을 바꿔줄 겁니다!

색을 변경하면 마치 투명한 색 필터를 씌우는 것처럼 자동차 색이 변합니다.
Unity 게임 스크린샷 Unity 게임 스크린샷
using System.Collections;
using System.Collections.Generic;
using UnityEngine; // Unity 관련 기능을 사용하기 위해 필요한 네임스페이스

// Delivery 클래스는 차량이 패키지를 픽업하고 배달하는 기능을 담당합니다.
public class Delivery : MonoBehaviour
{
    // [SerializeField]는 Unity Inspector에서 값을 수정할 수 있도록 합니다.
    // 패키지를 가지고 있을 때의 색상을 설정합니다.
    [SerializeField] Color32 hasPackageColor = new(255, 255, 255, 255); // 기본적으로 흰색

    // 패키지가 없을 때의 색상을 설정합니다.
    [SerializeField] Color32 noPackageColor = new(255, 255, 255, 255); // 기본적으로 흰색

    // 패키지를 파괴하기까지 걸리는 지연 시간 (0.5초 후 삭제)
    [SerializeField] float destroyDelay = 0.5f;

    // 현재 패키지를 가지고 있는지 여부를 저장하는 변수
    bool hasPackage;

    // SpriteRenderer를 저장하는 변수 (차량의 색상을 변경하는 데 사용)
    SpriteRenderer spriteRenderer;

    // Start() 메서드는 게임 시작 시 한 번 실행됩니다.
    void Start()
    {
        // GetComponent<SpriteRenderer>()를 통해 이 오브젝트의 SpriteRenderer 컴포넌트를 가져옵니다.
        // SpriteRenderer는 게임 오브젝트의 스프라이트(이미지)를 표시하고 색상을 변경할 수 있습니다.
        spriteRenderer = GetComponent<SpriteRenderer>();

        /*
         * GetComponent<T>()에서 제네릭 <T>가 사용된 이유:
         * - Unity에서 특정한 타입의 컴포넌트를 가져올 때 GetComponent<T>()를 사용합니다.
         * - T에는 가져오고자 하는 컴포넌트의 타입을 넣으면 됩니다.
         * - 예를 들어, SpriteRenderer를 가져오려면 GetComponent<SpriteRenderer>()를 사용합니다.
         * - 제네릭을 사용하면 컴파일 시점에 타입이 결정되므로 타입 안정성이 높아집니다.
         */
    }

    // 2D 물리 충돌이 발생했을 때 실행되는 메서드
    void OnCollisionEnter2D(Collision2D collision)
    {
        // 충돌이 발생했음을 디버그 메시지로 출력합니다.
        Debug.Log("충돌 발생");
    }

    // 2D 트리거(Trigger) 충돌이 발생했을 때 실행되는 메서드
    void OnTriggerEnter2D(Collider2D collision)
    {
        // 충돌한 오브젝트가 "Package" 태그를 가지고 있고, 아직 패키지를 가지고 있지 않을 경우
        if (collision.CompareTag("Package") && !hasPackage)
        {
            Debug.Log("Package 픽업"); // 패키지를 주웠음을 알리는 디버그 메시지 출력
            hasPackage = true; // 패키지를 보유 상태로 변경
            spriteRenderer.color = hasPackageColor; // 차량 색상을 패키지를 보유한 색상으로 변경
            Destroy(collision.gameObject, destroyDelay); // 패키지를 지정된 시간 후에 삭제
        }

        // 충돌한 오브젝트가 "Customer" 태그를 가지고 있고, 패키지를 가지고 있는 경우
        if (collision.CompareTag("Customer") && hasPackage)
        {
            Debug.Log("Customer 배달 성공"); // 배달 완료 메시지 출력
            hasPackage = false; // 패키지를 보유하지 않은 상태로 변경
            spriteRenderer.color = noPackageColor; // 차량 색상을 원래 색상으로 변경
        }
    }
}

#발생할 수 있는 문제와 해결 방법

❌ 차가 갑자기 사라지는 경우?

✔️ Color32(255, 255, 255, 0); → 알파 값(투명도)이 0이면 차가 보이지 않음!

✔️ 알파 값을 255로 설정해서 자동차가 투명해지지 않도록 해야 함

#{ 유니티에서 자동차 속도 조절 기능 구현 }

#1. **부스트(Boost) 기능**

개념: 자동차가 특정 지점(예: 노란색 원)을 지나가면 속도가 빨라지는 기능

어떻게 구현할까?

		씬(Scene)에 부스트 오브젝트 추가

		2D Object -> Sprite를 추가

		모양을 원(circle)으로 설정

		색상을 노란색으로 변경

		Circle Collider 2D 추가 & Trigger 체크

		새로운 태그 "Boost"를 생성하고 이 오브젝트에 태그 적용

코드에서 부스트 기능 적용

		OnTriggerEnter2D() 함수를 사용

		자동차가 "Boost" 태그가 있는 오브젝트를 지나갈 때 속도를 증가

#2. **충돌 시 속도 감소(Bump) 기능**

개념: 자동차가 벽, 나무 같은 장애물에 부딪히면 속도가 줄어드는 기능

어떻게 구현할까?

		충돌 감지 (OnCollisionEnter2D 사용)

		자동차가 어떤 오브젝트와 충돌하면 속도를 줄이기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Driver : MonoBehaviour
{
    // 🚗 차량 회전 속도 (좌우 조작)
    [SerializeField] float steerSpeed = 1f;

    // 🚗 기본 이동 속도
    [SerializeField] float moveSpeed = 20f;

    // 🚗 충돌 시 줄어드는 속도
    [SerializeField] float slowSpeed = 15f;

    // 🚗 부스트 아이템 획득 시 증가하는 속도
    [SerializeField] float boostSpeed = 30f;

    void Start()
    {
        // Start()는 게임이 시작될 때 한 번만 실행됩니다.
        // 현재는 사용하지 않아서 주석 처리됨.
        // transform.Rotate(0, 0, 45);
    }

    // 🎮 Update() - 매 프레임마다 실행되는 함수
    void Update()
    {
        // ⬅➡ 좌우 이동 입력을 받아 steerAmount 계산
        float steerAmount = Input.GetAxis("Horizontal") * steerSpeed * Time.deltaTime;

        // ⬆⬇ 앞뒤 이동 입력을 받아 moveAmount 계산
        float moveAmount = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;

        // 차량을 좌우로 회전 (-steerAmount는 반대 방향 회전)
        transform.Rotate(0, 0, -steerAmount);

        // 차량을 앞뒤로 이동
        transform.Translate(0, moveAmount, 0);
    }

    // 🚧 충돌 감지 - 자동차가 벽이나 장애물과 부딪힐 때 호출
    void OnCollisionEnter2D(Collision2D collision)
    {
        // 🚗 충돌하면 속도를 줄이기
        moveSpeed = slowSpeed;
    }

    // 🚀 트리거 감지 - 자동차가 특정 영역(부스트 아이템 등)에 들어가면 호출
    void OnTriggerEnter2D(Collider2D collision)
    {
        // 만약 충돌한 오브젝트의 태그가 "Boost"라면
        if (collision.CompareTag("Boost"))
        {
            Debug.Log("Boost!!"); // 콘솔에 "Boost!!" 메시지 출력

            moveSpeed = boostSpeed; // 🚀 부스트 아이템 획득 시 속도를 빠르게 변경
        }
    }
}