팀스파르타 내일배움캠프

📚 TIL - 2025년 4월 29일 (화) / 발제 및 유니티 주간의 시작

creator2041 2025. 4. 29. 21:09

[발제]유니티 학습 주간

1. 게임 개발 프로세스

  • 콘텐츠화:
    • 게임 개발 및 연습 과정에서 가장 기본적인 목표는 경험을 콘텐츠화하는 것이다.
  • 개발 과정:
    • 가이드 코드 분석
    • 스켈레톤 코드 작성
    • 필수 기능 구현 및 테스트
    • 확장 기능 구상

2. 유니티 게임 구조의 기본 개발 기술 (필수 기능)

  • 캐릭터 이동 및 맵 탐색
  • 맵 설계 및 상호작용 영역 구현
  • 미니게임 실행
  • 점수 시스템 구축
  • 게임 종료 및 복귀 기능
  • 카메라 추적 기능

3. 난이도를 높여 도전할 수 있는 확장 기능 (도전 기능)

  • 추가 미니게임 제작
  • 커스텀 캐릭터 제작
  • 리더보드 시스템 구축
  • 탑승물 제작
  • NPC와 대화 시스템 구현

4. 개인과제 제출 안내

  • 제출일자: --
  • 필수 제출 내용:
    • 과제 결과물: 최종 게임 프로젝트를 업로드한 Git 리포지터리 URL 제출
    • 트러블슈팅을 포함한 TIL 작성 (개발 중 KPT 형식 회고를 병행하면 더 좋음)

[유니티 강좌 1. 유니티 설치와 기본환경]


유니티란 무엇인가

Unity는 2D 및 3D 게임을 비롯해 애니메이션, 시뮬레이션, AR/VR 콘텐츠 제작을 지원하는 멀티플랫폼 게임 엔진이다. 초보자부터 전문가까지 폭넓게 사용할 수 있도록 다양한 기능과 친숙한 개발 환경을 제공한다.

주요 특징

  • 멀티플랫폼 지원: 하나의 프로젝트로 다양한 플랫폼(모바일, PC, 콘솔 등) 배포 가능.
  • 강력한 물리 엔진: 충돌, 중력, 질량 등을 쉽게 처리할 수 있다.
  • 에셋 스토어: 다양한 리소스와 툴을 손쉽게 구할 수 있어 개발 속도를 높여준다.
  • C# 기반 프로그래밍: 비교적 배우기 쉬운 문법과 방대한 자료 지원.
  • 무료 및 유료 모델: 수익이 일정 기준을 넘지 않으면 무료로 사용 가능하다.

개발 환경 세팅

유니티 허브 설치

  • Unity Hub는 여러 버전의 Unity 엔진과 프로젝트를 통합 관리할 수 있는 필수 프로그램이다.
  • 프로젝트 생성, 버전 관리, 모듈 추가 등을 여기서 진행한다.

통합 개발 환경(IDE) 설치

  • Windows: Visual Studio Community 2022 권장.
  • Mac: JetBrains Rider 또는 Visual Studio Code 사용 가능.
  • IDE는 코드 작성, 디버깅, 유닛테스트 등을 보다 편리하게 만들어준다.

유니티 주요 인터페이스

  • 씬(Scene) 뷰: 게임 오브젝트 배치 및 편집을 위한 공간.
  • 게임(Game) 뷰: 실제 플레이되는 화면을 시뮬레이션.
  • 하이어라키(Hierarchy) 창: 현재 씬에 존재하는 모든 오브젝트 목록.
  • 인스펙터(Inspector) 창: 선택한 오브젝트의 세부 속성을 조정.
  • 프로젝트(Project) 창: 에셋과 리소스 파일들을 관리.
  • 콘솔(Console) 창: 에러, 경고, 디버그 메시지 확인.

학습 중 느낀 점 및 보완할 점

  • Unity는 초보자에게도 문턱이 낮은 편이나, 인터페이스 구성과 용어에 익숙해지는 데 시간이 소요된다.
  • 특히, "씬"과 "게임 뷰"를 구분하고 활용하는 법을 초반에 명확히 이해하는 것이 중요하다.
  • IDE 설치 시 부가 기능(플러그인) 설치 여부에 따라 프로젝트 설정이 달라질 수 있으므로, 가급적 튜터나 공식 가이드라인을 따르는 것이 안정적이다.
  • 앞으로 프로젝트를 진행하면서 씬 구성 → 하이어라키 정리 → 인스펙터 조정의 흐름을 자연스럽게 체득할 필요가 있다.

[유니티 강좌 2.  유니티 스프라이트 추가와 애니메이션 설정]


스프라이트란 무엇인가

Unity에서 스프라이트(Sprite)란 2D 그래픽 이미지를 의미한다. 일반적으로 게임 내의 캐릭터, 배경, 아이템 등을 표현할 때 사용된다.

스프라이트 시트(Spritesheet)

  • 여러 개의 작은 이미지를 하나의 큰 이미지 파일로 합친 것을 말한다.
  • 스프라이트 시트를 불러올 때 "Sprite Mode"를 "Multiple"로 설정한 뒤, Sprite Editor를 통해 각각 잘라내야 한다.
  • 이 과정을 통해 여러 개의 독립된 스프라이트 오브젝트를 생성할 수 있다.

PPU(Pixels Per Unit) 설정

  • PPU란: 1 유니티 유닛 안에 몇 개의 픽셀이 들어가는지를 정하는 값.
  • 기본적으로 100픽셀이 1유닛에 매핑된다.
  • 예시: 비행기 이미지 가로 길이가 100픽셀이라면, PPU가 100일 때 1유닛 크기가 된다.
  • 만약 PPU를 200으로 설정하면, 같은 비행기 이미지는 절반 크기로 보인다.

스프라이트를 활용한 애니메이션 제작

  • 하이어라키 창에서 새 오브젝트를 만들고, 스프라이트들을 드래그하여 자동으로 **애니메이션 클립(Animation Clip)**을 생성할 수 있다.
  • 트랜스폼(Transform)은 항상 리셋하는 습관을 들이는 것이 좋다. (오브젝트 위치 초기화)
  • 애니메이션 전이(Transition)는 Animator에서 설정할 수 있으며, 조건부 이동(Condition)을 걸어줄 수 있다.
  • 예를 들어, int형 파라미터 isdie가 1일 때 죽는 애니메이션으로 전이하도록 설정할 수 있다.

배경과 소팅 오더 설정

  • 배경 오브젝트 연결:
    • Ctrl + D로 복제 후, V키를 눌러 스냅 포인트를 잡아 옆에 정렬하는 방식으로 이어붙일 수 있다.
  • Sorting Layer와 Order in Layer:
    • 스프라이트 렌더러(Sprite Renderer) 컴포넌트에서 설정 가능.
    • "Sorting Layer"를 통해 레이어 그룹을 설정하고, "Order in Layer"를 통해 렌더링 순서를 결정.
    • 값이 높을수록 화면 위에 표시된다.

학습 중 느낀 점 및 보완할 점

  • 스프라이트를 자르는 작업은 반복적으로 숙달할 필요가 있다.
  • Sprite Editor를 처음 사용할 때 헷갈릴 수 있으므로, 자주 직접 손으로 잘라보고 적용해보는 것이 빠른 숙련에 도움이 된다.
  • 애니메이션 전이 시 불필요한 디폴트 전이(Default Transition)를 삭제하고 필요한 경우만 조건부 전이를 설정하는 습관이 중요하다.
  • 오브젝트 복제 시 항상 위치를 초기화(Reset Transform)하고, 붙여넣기(Snap) 기능을 적극 활용하면 배경 작업 속도가 비약적으로 올라간다.

[유니티 강좌 3.  캐릭터 움직임과 점프 로직 구현]


Rigidbody2D와 Collider 설정

Unity에서 캐릭터의 움직임과 충돌 처리는 Rigidbody2D(물리 연산)와 Collider2D(충돌 영역)로 관리된다.

  • Rigidbody2D
    • 물리 엔진과 연동되어 중력, 힘, 속도 등을 계산해준다.
    • Dynamic 설정 시 외부 힘에 의해 반응하고, Kinematic 설정 시 직접 움직임을 제어할 수 있다.
  • Collider2D
    • 충돌 판정만 수행하며, 물리 반응은 Rigidbody가 담당한다.
    • Circle Collider, Box Collider, Polygon Collider 등 다양한 형태를 지원한다.

코드 실행 순서 정리

  • Awake():
    • 스크립트 인스턴스가 로드될 때 호출. 오브젝트 활성화와 무관하게 먼저 실행.
    • 컴포넌트 초기화 등 필수 세팅은 여기서.
  • Start():
    • 오브젝트가 활성화된 직후 한 번 호출. 일반적인 초기화는 여기서 진행.
  • Update():
    • 매 프레임 호출. 주로 입력 처리게임 로직 담당.
  • FixedUpdate():
    • 고정된 시간 간격으로 호출. 주로 물리 연산 관련 코드를 여기에 작성.
  • LateUpdate():
    • Update 이후 호출. 주로 카메라 추적 등 최종 연산용으로 사용.

캐릭터 점프 및 이동 처리

  • 입력 처리:
    • Input.GetKeyDown(KeyCode.Space)로 스페이스바 입력 감지.
    • Input.GetMouseButtonDown(0)으로 마우스 왼쪽 클릭 감지.
  • Flap 처리:
    • 점프를 할 때 isFlap 플래그를 true로 변경.
    • FixedUpdate에서 flapForce를 Y축 속도에 적용하고, 이후 isFlap을 false로 리셋.
  • 캐릭터 회전:
    • 수직 속도(velocity.y)에 따라 캐릭터의 각도를 변경.
    • Mathf.Clamp()를 이용해 회전 각도를 -90도 ~ +90도 사이로 제한.
    • Quaternion.Euler(0, 0, angle)을 통해 부드럽게 회전시킨다.

추가 개념 정리

  • deltaTime이란?
    • 프레임 간 시간 차를 의미한다.
    • 프레임 속도가 다르더라도 일관된 움직임을 구현할 때 사용.
  • Collider 충돌 유형 차이:
    • Collision: 실제 물리 충돌 및 반응 발생.
    • Trigger: 충돌 이벤트는 발생하지만 실제 물리 반응은 없음. (ex: 체크포인트 통과)

학습 중 느낀 점 및 보완할 점

  • Rigidbody2D와 Collider2D 설정을 꼼꼼히 체크하지 않으면, 물리 연산이 비정상적으로 동작할 수 있다.
  • Update와 FixedUpdate의 역할을 엄격히 구분하는 습관이 필요하다.
  • deltaTime 개념을 초반에 명확히 이해해두어야, 앞으로 애니메이션이나 이동 로직을 짤 때 오류를 줄일 수 있다.
  • 코드 작성 시 입력, 물리, 연산 순서를 명확히 구분하면 디버깅이 쉬워진다.

[유니티 강좌 4.   장애물 생성과 반복생성 로직]


포지션과 로컬포지션의 차이

  • Position
    • 오브젝트의 "월드 좌표"를 의미한다.
    • 씬 전체를 기준으로 (0,0,0) 중심에서의 절대적 위치를 나타낸다.
  • LocalPosition
    • 오브젝트의 "부모 오브젝트"를 기준으로 한 상대적 위치다.
    • 자식 오브젝트를 다룰 때는 LocalPosition을 사용해야 예상한 움직임이 나온다.

프리팹(Prefab) 개념 정리

  • Prefab이란?
    • 프로젝트 에셋 폴더에 저장된 오브젝트의 '원본 템플릿'이다.
    • 하이어라키에 인스턴스(복제본)를 만들어서 사용하고, 원본을 수정하면 모든 인스턴스에 반영된다.

장애물(Obstacle) 생성 로직

  • SetRandomPlace() 메서드
    • 장애물 간 가로 간격을 일정하게 유지하면서 생성된다.
    • 구멍(hole)의 크기는 랜덤으로 설정되어 플레이마다 다른 구성을 만든다.
    • highPosY와 lowPosY 범위 안에서 Y축 위치도 랜덤하게 조정된다.

Rigidbody2D 사용시 주의사항

  • Dynamic:
    • 외부 힘(중력, 충돌 등)에 자연스럽게 반응하는 설정. 일반적인 장애물은 Dynamic이 기본이다.
  • Kinematic:
    • 직접 위치를 조작하거나, 물리력을 적용하지 않고 움직이는 경우 사용한다.
    • 장애물이 고정되거나 직접 위치를 갱신할 때는 Kinematic 설정을 활용할 수 있다.

레이어를 통한 충돌 제어

  • 특정 콜라이더끼리만 충돌하거나 무시하도록 제어할 수 있다.
  • 예시: Player는 Ground와만 충돌하고, 다른 장애물과는 트리거 이벤트만 발생시킨다.

학습 중 느낀 점 및 보완할 점

  •  장애물 생성 로직은 초기화와 반복을 잘 분리해서 관리해야 유지보수가 쉽다.
  • Position과 LocalPosition의 개념을 헷갈리지 말자. 특히 부모-자식 관계가 얽힌 경우 주의해야 한다.
  • 프리팹으로 저장할 때, 불필요한 컴포넌트나 설정이 남아있지 않은지 반드시 확인하는 습관을 들이자.
  • 콜라이더와 Rigidbody2D 설정이 맞지 않으면 트리거 충돌 또는 물리 충돌이 예상과 다르게 발생할 수 있다.
  • 폴리곤 콜라이더와 박스 콜라이더를 동시에 사용할 때, 콜라이더 간 충돌 판정이 중복되어 의도치 않은 물리 문제가 발생할 수 있다. 이 경우 레이어 설정이나 콜라이더 분리 관리로 해결해야 한다.

[유니티 강좌 5.   재시작과 점수 구현]


싱글턴(Singleton) 패턴의 이해

Unity에서는 게임의 주요 관리 객체를 싱글턴 패턴으로 구성하는 경우가 많다.

  • Singleton 패턴이란?
    • 클래스 인스턴스를 하나만 생성하고 전역에서 접근할 수 있도록 보장하는 디자인 패턴.
  • Unity에서의 구현 방식:
    • static 키워드로 Instance 프로퍼티를 만들고, Awake() 메서드에서 자기 자신을 초기화한다.
    • 예시:
    • static GameManager gameManager; public static GameManager Instance { get { return gameManager; } } private void Awake() { gameManager = this; }
  • 주의사항:
    • Awake는 여러 객체가 동시에 실행될 수 있으므로, 싱글턴 초기화 순서에 주의해야 한다.
    • 복수 인스턴스가 생성되지 않도록 방어 코드 추가를 고려할 수도 있다.

점수 시스템 구현

  • AddScore() 메서드:
    • 점수 추가 후, UIManager를 통해 현재 점수를 화면에 갱신한다.
    • 디버깅을 위해 Debug.Log로 점수 변화를 기록하는 것도 좋은 습관이다.
  • UIManager 연결:
    • FindObjectOfType<UIManager>()로 UIManager를 찾아서 연결.
    • 별도로 null 체크를 통해 UIManager가 존재하는지 확인하는 것도 안전하다.

게임 재시작 로직

  • GameOver() 메서드:
    • 게임이 끝났을 때 호출되며, Restart 버튼이나 텍스트를 활성화시킨다.
  • RestartGame() 메서드:
    • 현재 활성화된 씬을 새로 로드하여 게임을 재시작한다.
    • SceneManager.LoadScene(SceneManager.GetActiveScene().name); 코드를 사용한다.

학습 중 느낀 점 및 보완할 점

  • 싱글턴을 남발하면 코드 유지보수가 어려워질 수 있으니, 정말 필요한 매니저 클래스에만 적용해야 한다.
  • 점수 UI 갱신 로직은 별도의 UI 매니저로 분리해서 관리하는 것이 깔끔하고 유지보수에 유리하다.
  • 재시작 로직을 구현할 때, 씬 전체를 초기화하는 방법 외에 필요한 리소스만 리셋하는 방법도 고려해볼 수 있다.
  • 게임 종료 후 입력(버튼 클릭, 키 입력 등)을 막는 안전장치도 향후 추가할 필요가 있다.

[유니티 강좌 6.  캔버스(Canvas)와 UI 기초]


캔버스(Canvas)란 무엇인가

Unity에서 Canvas는 UI 요소들을 그리는 "화면상의 도화지" 역할을 한다.

  • Canvas의 역할:
    • UI 요소(버튼, 텍스트, 이미지 등)는 반드시 Canvas 아래에 있어야 화면에 출력된다.
    • 모든 UI 오브젝트는 부모로서 Canvas를 가진다.
  • Canvas의 Render Mode:
    • Screen Space - Overlay:
      • 가장 기본적인 방식. 화면 위에 바로 그린다.
    • Screen Space - Camera:
      • 특정 카메라를 기준으로 UI를 배치할 수 있다.
    • World Space:
      • UI가 3D 오브젝트처럼 월드 안에 배치된다.

UI 텍스트(TextMeshPro) 구성

  • TextMeshPro란?
    • Unity 기본 텍스트보다 훨씬 선명하고 다양한 기능을 제공하는 고급 텍스트 시스템.
  • 설정 방법:
    • TextMeshProUGUI 컴포넌트를 추가해 사용한다.
    • 처음 사용 시 TMP Essentials 패키지를 설치해야 한다.
  • 활용:
    • 점수 출력, 안내 문구 표시 등 게임 내 다양한 텍스트를 깔끔하게 표현할 수 있다.

UIManager를 통한 UI 관리

  • UIManager 스크립트 구성:
    • TextMeshProUGUI 오브젝트를 참조하여 점수 업데이트, 재시작 버튼 표시 등을 제어한다.
  • SetRestart() 메서드:
    • 게임 오버 시 재시작 텍스트를 활성화시킨다.
  • UpdateScore(int score) 메서드:
    • 현재 점수를 텍스트로 변환하여 화면에 표시한다.

학습 중 느낀 점 및 보완할 점

  • Canvas는 UI 오브젝트를 묶어주는 기본 단위이므로, 반드시 계층 구조를 명확히 이해해야 한다.
  • TextMeshPro는 강력하지만 기본 텍스트보다 설정할 항목이 많기 때문에 초기 셋업에 신경써야 한다.
  • UIManager를 통해 모든 UI 변경을 일원화하면 코드의 가독성과 유지보수성이 높아진다.
  • 앞으로 복잡한 UI(메뉴, 인벤토리 등)를 다루게 될 때, Canvas와 UIManager 구조를 체계적으로 잡는 것이 핵심이 될 것이다.

[트러블슈팅]


UIManager 스크립트 구조

UIManager는 UI 요소들의 상태를 통합적으로 관리하는 클래스이다.
게임의 흐름에 따라 점수 표시나 재시작 안내 같은 UI를 제어한다.

  • 필드 구성:
    • TextMeshProUGUI scoreText : 현재 점수를 표시하는 텍스트.
    • TextMeshProUGUI restartText : 게임 종료 후 재시작을 알리는 텍스트.
  • 초기화 작업:
    • Start() 메서드에서 restartText를 비활성화 (SetActive(false))하여 게임 시작 시에는 보이지 않게 설정한다.

UI 업데이트 메서드

  • SetRestart() 메서드:
    • 게임 오버 시 호출되어 restartText를 활성화한다.
  • UpdateScore(int score) 메서드:
    • scoreText에 현재 점수를 문자열로 변환하여 갱신한다.

Null 체크의 중요성

  • UI 오브젝트가 정상적으로 연결되어 있지 않으면 런타임 에러가 발생할 수 있다.
  • if (scoreText == null) 또는 if (restartText == null)처럼 사전에 null 체크하여 문제를 조기에 발견할 수 있다.
  • Debug.Log로 오류를 출력하는 습관도 중요하다.

학습 중 느낀 점 및 보완할 점

  • UI를 담당하는 클래스를 별도로 만드는 것은, 코드의 역할을 명확히 분리하고 유지보수를 편하게 만들어준다.
  • TextMeshProUGUI 같은 외부 패키지 연동 컴포넌트를 사용할 때는 초기 설정과 의존성 확인을 반드시 해야 한다.
  • 게임 오버와 점수 갱신 같은 기본 동작을 UIManager를 통해 일관성 있게 처리하면, 전체 시스템의 안정성이 올라간다.
  • 향후 복잡한 UI를 설계할 때도 'UIManager - Canvas - UI 요소'라는 기본 구조를 유지하는 것이 바람직하다.