logo
Published on

Unity 기본 구조 정리

Authors
  • avatar
    Name
    valery
    Twitter

Unity 기본 구조 정리

Unity는 코드만으로 게임을 만드는 방식이 아니라, Scene 안에 GameObject를 배치하고, GameObject에 Component를 붙여 기능을 만드는 방식으로 동작한다.

1. 프로젝트 기본 폴더 구조

Unity 프로젝트에서 주로 사용하는 폴더는 Assets 안에 있다.

Assets/
├─ Scenes/
├─ Scripts/
├─ Sprites/
└─ Prefabs/

Scenes

Scene은 게임 전체가 아니라, 게임 안에서 한 번에 불러오는 오브젝트 묶음이다.

예를 들어 게임이 커지면 다음처럼 씬을 나눌 수 있다.

Assets/Scenes/
├─ MainMenu.unity
├─ GameScene.unity
└─ GameOver.unity

각 씬은 자기 안에 필요한 GameObject들을 따로 가진다.

GameScene
├─ Main Camera
├─ Player
├─ Enemy
└─ UI

즉, Player 같은 오브젝트는 독립된 파일로 따로 저장되는 것이 아니라, 현재 씬 파일 안에 저장된다.

Assets/Scenes/SampleScene.unity
└─ 이 안에 Player 오브젝트 정보가 저장됨

Scripts

Scripts 폴더에는 C# 코드 파일을 저장한다.

Assets/Scripts/
└─ PlayerMove.cs

스크립트는 GameObject에 붙여서 동작을 만들 때 사용한다.

예를 들어 PlayerMove.csPlayer 오브젝트에 붙이면, 그 오브젝트가 코드에 따라 움직인다.

여기서 중요한 점은 스크립트 파일이 혼자 실행되는 것이 아니라, Unity Editor에서 GameObject에 Component로 붙어야 실행된다는 것이다.

Sprites

Sprite는 2D 오브젝트에 붙이는 이미지 리소스다.

예를 들어 플레이어 이미지가 있다면 다음처럼 저장할 수 있다.

Assets/Sprites/
└─ player.png

Sprite 자체는 단순한 이미지일 뿐이다. 움직임, 충돌, 체력 같은 기능은 없다.

Sprite를 화면에 보이게 하려면 GameObject에 SpriteRenderer 컴포넌트가 필요하다.

Player
├─ Transform
└─ SpriteRenderer
   └─ player.png를 화면에 표시

Prefabs

Prefab은 GameObject의 구성을 재사용 가능한 원본 파일로 저장한 것이다.

예를 들어 Player 오브젝트가 다음과 같이 구성되어 있다고 하자.

Player
├─ Transform
├─ SpriteRenderer
│  └─ player.png
├─ Rigidbody2D
├─ BoxCollider2D
└─ PlayerMove.cs

이 오브젝트를 Prefabs 폴더로 드래그하면 Player.prefab 파일이 만들어진다.

Assets/Prefabs/
└─ Player.prefab

Prefab은 스크립트나 이미지를 실제로 하나로 합치는 것이 아니다. 정확히는 어떤 컴포넌트가 붙어 있는지, 어떤 Sprite와 Script를 참조하는지, 각 값이 무엇인지를 저장한다.

Player.prefab
├─ GameObject 이름
├─ 붙어 있는 Component 목록
├─ Component의 설정값
└─ 참조하는 에셋
   ├─ player.png
   └─ PlayerMove.cs

즉, Prefab은 "완성된 오브젝트 구성 정보"를 저장한 재사용 원본이다.

2. Project - Scene - GameObject 구조

Unity 구조는 다음처럼 이해할 수 있다.

Project
└─ Scene
   └─ GameObject
      └─ Component

Project

Project는 게임 전체를 의미한다.

First2DGame/
├─ Assets/
├─ Packages/
└─ ProjectSettings/

프로젝트 안에는 씬, 스크립트, 이미지, 사운드, 설정 파일 등이 들어간다.

Scene

Scene은 게임 안에서 한 번에 불러오는 오브젝트 묶음이다.

예를 들어 메뉴 화면, 실제 게임 화면, 게임오버 화면을 각각 다른 씬으로 나눌 수 있다.

Project
├─ MainMenu Scene
├─ Game Scene
└─ GameOver Scene

단, 작은 게임은 씬 하나만으로도 만들 수 있다.

처음에는 SampleScene 하나 안에 Player, Enemy, UI 등을 모두 넣고 시작해도 된다.

SampleScene
├─ Main Camera
├─ Player
├─ Enemy
├─ Wall
└─ UI

씬은 화면 이미지 자체가 아니다. 씬은 "어떤 오브젝트들이 존재하고, 어디에 있고, 어떤 컴포넌트를 갖는지"를 저장하는 파일이다.

화면에 실제로 보이는 결과는 Scene 안의 Camera가 찍어서 보여준다.

Scene
├─ Player
├─ Enemy
└─ Camera
   └─ Game View에 화면을 보여줌

GameObject

GameObject는 씬 안에 존재하는 객체다.

예를 들면 다음과 같다.

Player
Enemy
Bullet
Wall
Camera
UI

GameObject는 빈 껍데기에 가깝고, 실제 기능은 Component를 붙여서 만든다.

예를 들어 Player는 단순히 이름만 있는 객체가 아니라, 여러 Component가 붙은 객체다.

Player
├─ Transform
├─ SpriteRenderer
└─ PlayerMove.cs

여기서 Player라는 이름은 필수가 아니다. Hero, Character, MyBox 같은 이름으로 바꿔도 된다.

중요한 것은 이름이 아니라, 어떤 Component가 붙어 있는지다.

3. GameObject와 Component

Unity에서 오브젝트는 Component들의 조합으로 만들어진다.

예를 들어 Player는 다음처럼 구성할 수 있다.

Player
├─ Transform
├─ SpriteRenderer
├─ Rigidbody2D
├─ BoxCollider2D
└─ PlayerMove.cs

각 Component의 역할은 다음과 같다.

Component역할
Transform위치, 회전, 크기 정보. 모든 GameObject에 기본으로 존재
SpriteRenderer2D 이미지를 화면에 표시
Rigidbody2D2D 물리 엔진의 영향을 받게 함
BoxCollider2D충돌 범위 설정
PlayerMove.cs직접 작성한 이동 코드

즉, Unity에서 기능을 만든다는 것은 보통 다음 과정을 반복하는 것이다.

GameObject 만들기
→ 필요한 Component 붙이기
Component 값 설정하기
C# Script 작성하기
Script를 GameObject에 붙이기
→ 실행해서 확인하기

4. C# Script는 어떻게 붙는가

PlayerMove.cs 같은 스크립트는 C# 코드 파일이다.

예를 들어 다음 코드는 플레이어 이동을 담당한다.

using UnityEngine;

public class PlayerMove : MonoBehaviour
{
    public float speed = 5f;

    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float y = Input.GetAxisRaw("Vertical");

        Vector3 direction = new Vector3(x, y, 0).normalized;
        transform.position += direction * speed * Time.deltaTime;
    }
}

이 코드는 파일로만 존재하면 아무 일도 하지 않는다.

Unity Editor에서 Player GameObject에 PlayerMove.cs를 Component로 붙여야 실행된다.

Player
├─ Transform
├─ SpriteRenderer
└─ PlayerMove.cs

PlayerMove.cs가 Player에 붙어 있으면, 코드 안의 transform은 Player의 Transform을 의미한다.

즉, 아래 코드는 "이 스크립트가 붙어 있는 GameObject의 위치를 바꿔라"라는 뜻이다.

transform.position += direction * speed * Time.deltaTime;

그래서 같은 스크립트를 Enemy에 붙이면 Enemy가 움직이고, Player에 붙이면 Player가 움직인다.

코드는 특정 이름의 객체를 자동으로 찾는 것이 아니라, 자기 자신이 붙어 있는 GameObject를 기준으로 동작한다.

5. Unity Editor와 VS Code의 역할

Unity Editor와 VS Code는 역할이 다르다.

Unity EditorVS Code
Scene 편집C# Script 작성
GameObject 생성게임 로직 작성
Component 추가
Sprite, Prefab, Collider, Camera 설정
게임 실행 테스트

예를 들어 Player 오브젝트 자체는 VS Code에서 Player.cs 파일로 보이지 않는다. 왜냐하면 PlayerSampleScene.unity 안에 저장된 GameObject 데이터이기 때문이다.

반면 PlayerMove.cs는 실제 C# 코드 파일이므로 VS Code에서 볼 수 있다.

Assets/
├─ Scenes/
│  └─ SampleScene.unityPlayer 오브젝트 정보 저장
└─ Scripts/
   └─ PlayerMove.csPlayer의 행동 코드

6. 배경과 구조물은 어떻게 만드는가

모든 것을 독립 GameObject로 만들 필요는 없다.

종류방법
움직이고 행동하는 것GameObject + Script
반복 배치되는 바닥, 벽, 배경Tilemap
이미지로만 보이는 큰 배경SpriteRenderer

예를 들어 2D 맵은 보통 Tilemap으로 만든다.

SampleScene
├─ Main Camera
├─ Grid
│  ├─ Ground Tilemap
│  └─ Wall Tilemap
├─ Player
└─ EnemySpawner

바닥 타일 1000개를 각각 GameObject로 만들면 낭비가 심하다. 그래서 Tilemap 하나가 많은 타일 데이터를 관리하게 만든다.

나쁜 방식

Wall_001 GameObject
Wall_002 GameObject
Wall_003 GameObject
...
Wall_500 GameObject

좋은 방식

Wall Tilemap GameObject
└─ wall tile 500개 데이터

7. 전체 정리

Unity의 핵심 구조는 다음과 같다.

개념설명
Project게임 전체
Scene한 번에 불러오는 오브젝트 묶음
GameObject씬 안에 있는 객체
ComponentGameObject에 붙는 기능
Script직접 만든 Component
Sprite2D 이미지 리소스
PrefabGameObject 구성을 저장한 재사용 원본

처음에는 다음 흐름만 이해하면 된다.

  1. Scene 안에 Player GameObject를 만든다.
  2. Player에 SpriteRenderer를 붙여 화면에 보이게 한다.
  3. PlayerMove.cs를 작성한다.
  4. Player에 PlayerMove.cs를 Component로 붙인다.
  5. 실행하면 Unity가 매 프레임 Update()를 호출한다.
  6. 코드가 Player의 transform.position을 바꾼다.
  7. Unity가 바뀐 위치를 화면에 다시 그린다.

결론적으로 Unity 개발은 다음 반복이다.

GameObject 만들기
Component 붙이기
Script 작성하기
GameObject에 Script 붙이기
Prefab으로 재사용하기
Scene 안에서 테스트하기