[발제]유니티 학습 주간
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 오브젝트처럼 월드 안에 배치된다.
- Screen Space - Overlay:
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 요소'라는 기본 구조를 유지하는 것이 바람직하다.
'팀스파르타 내일배움캠프' 카테고리의 다른 글
| 📚 TIL - 2025년 5월 1일 (목) / 본격 구현 단계 진입 (2) | 2025.05.01 |
|---|---|
| 📚 TIL - 2025년 4월 30일 (수) / 유니티 주간 두번째 과제!! (1) | 2025.04.30 |
| 📚 오류 수정록 - 2025년 4월 28일 (월) / Unity Collaborate 패키지 오류 해결 기록 (0) | 2025.04.28 |
| 📚 TIL - 2025년 4월 25일 (금) / 와이어프레임과 구조설계, 조별과제 완료 (0) | 2025.04.25 |
| [텍스트 RPG프로젝트] 계획 편성해보기 (0) | 2025.04.15 |