
존 레몬의 공포 체험 시작하기
Tutorial
Beginner
+10XP
30 mins
(388)
Unity Technologies

존 레몬의 공포 체험: 3D 초급자용 프로젝트에 오신 것을 환영합니다. 이 학습 프로젝트의 튜토리얼을 진행하면서 자신만의 3D 스텔스 게임을 제작하고, 그 과정에서 각 단계의 바탕이 되는 원칙에 대한 이해도를 높이게 됩니다. 이 프로젝트에서는 Unity를 처음 접하는 사용자를 위한 단계별 가이드를 통해 스텔스 게임을 제작하는 방법을 알아보겠습니다.
첫 번째 튜토리얼에서 배울 내용은 다음과 같습니다.
- 게임 개발을 위해 Unity 프로젝트를 설정합니다.
- 플레이어 캐릭터용 프리팹을 만듭니다.
- 캐릭터 애니메이션화를 시작합니다.
- 캐릭터가 물리에 반응하도록 설정합니다.
Unity를 이용한 2D 게임 개발에 대해 자세히 알고 싶으신가요? 온라인 일대일 수업에서 Unity 개발 전문가와 이야기해 보세요.
Languages available:
1. 개요
존 레몬의 공포 체험: 3D 초급자용 프로젝트에 오신 것을 환영합니다. 여러분은 이 학습 프로젝트의 튜토리얼을 진행하면서 자신만의 3D 스텔스 게임을 제작하고, 그 과정에서 각 단계의 바탕이 되는 원칙에 대한 이해도를 높이게 됩니다. 이 프로젝트에서는 Unity를 처음 접하는 사용자를 위한 단계별 가이드를 통해 스텔스 게임을 제작하는 방법을 알아보겠습니다.
첫 번째 튜토리얼에서 배울 내용은 다음과 같습니다.
- 게임 개발을 위해 Unity 프로젝트를 설정합니다.
- 플레이어 캐릭터용 프리팹을 만듭니다.
- 캐릭터 애니메이션화를 시작합니다.
- 캐릭터가 물리에 반응하도록 설정합니다.
이 튜토리얼을 완료하면 존 레몬의 움직임을 제어하는 첫 스크립트를 작성할 수 있습니다.
2. 시작하기 전에
Unity를 처음 사용하시나요?
Unity를 처음 사용하는 경우, Unity 필수 과정 학습 길잡이를 통해 기초를 다지고 Unity 에디터에서 제작을 시작할 수 있습니다. 존 레몬의 공포 체험: 3D 초급자용 프로젝트를 진행하기 전에 이 학습 길잡이를 완료하는 것이 좋습니다.
Unity Hub 업데이트
Unity 프로젝트 설정을 시작하기 전에 Unity Hub를 최신 릴리스로 업데이트하는 것이 좋습니다. 이전 버전의 Hub를 사용할 경우 제공된 지침과 실제 경험하는 내용에 차이가 있을 수 있습니다.
Unity 에디터 기초 확인
Unity 에디터의 기초를 다시 확인하고 싶을 때는 언제든지 Unity 에디터 둘러보기를 살펴보세요.
Unity 프로젝트 설정
Unity 프로젝트를 설정하는 방법은 다음과 같습니다.
1. 아직 설치하지 않은 경우 Unity 2020.3을 설치합니다.
2. Unity 에셋 스토어에서 3D Beginner: Tutorial Resources로 이동합니다.
3. 씬 저장
이전 튜토리얼에서는 Unity 에디터의 레이아웃을 살펴보았습니다. 또한 씬은 여러 게임 오브젝트로 구성되며, 각 오브젝트에는 기능과 동작이 담긴 컴포넌트가 포함된다는 것도 배웠습니다.
이제 게임 오브젝트를 씬에 추가해 보겠습니다.
새 프로젝트가 생성되면 Unity는 "Untitled"라는 비어 있는 씬을 자동으로 생성합니다.
File > Save로 이동하거나 Ctrl/Cmd+S를 눌러서 파일을 저장할 곳을 선택합니다. Scenes라는 기존 폴더에 이 씬을 "MainScene"으로 저장합니다.
그러면 프로젝트(Project) 창에 MainScene이라는 씬 에셋이 생성됩니다.
이제 씬에서 작업을 수행할 수 있습니다. 이 씬은 튜토리얼을 진행하는 내내 사용될 예정입니다. 변경 사항을 저장하려면 Ctrl/Cmd+S를 수시로 눌러 주세요.
4. 캐릭터 모델 추가
이전 튜토리얼에서 이 게임을 만드는 데 필요한 모든 에셋을 임포트했습니다. 처음으로 사용할 에셋은 3D 모델입니다.
3D 게임에서는 대부분이 모델로 구성되어 있으며 캐릭터, 환경, 프랍 역시 모델입니다. 모델은 주로 Unity 외부에서 제작한 후 임포트하여 기능을 추가합니다. 이러한 모델을 사용하려면 모델을 게임 오브젝트로 추가해야 합니다. 이를 가리켜 모델의 인스턴스를 생성한다고 합니다.
플레이어 캐릭터인 존 레몬을 추가해 보겠습니다.
1. 프로젝트 창에서 Assets > Models > Characters 폴더로 이동하여 JohnLemon 모델을 찾습니다.
2. 프로젝트 창에서 씬(Scene) 뷰로 모델을 드래그하여 모델을 배치할 곳을 정확히 선택할 수 있습니다. 또한 모델을 계층 구조(Hierarchy)로 드래그하여 기본 위치에서 게임 오브젝트를 생성할 수도 있습니다.
3. 씬 뷰 위에 커서를 두고 F 키를 눌러 초점을 맞춥니다.
이제 씬에서 플레이어의 캐릭터를 확인할 수 있습니다. 또한 인스펙터(Inspector)에서 방금 인스턴스화한 게임 오브젝트에 대한 정보도 찾을 수 있습니다. 현재 다음과 같은 두 개의 컴포넌트가 있습니다.
- 씬에서 위치와 크기 정보를 갖고 있는 Transform 컴포넌트
오브젝트를 애니메이션화해 주는 Animator 컴포넌트
이 캐릭터에 이렇게 두 가지 기능만 있는 건 아닙니다. 예를 들어 씬 뷰에서 플레이어 캐릭터를 볼 수 있지만 두 컴포넌트는 이에 대한 정보를 담고 있지 않습니다.
4. 계층 창에서 JohnLemon 게임 오브젝트를 찾습니다.
게임 오브젝트 이름 옆에 있는 화살표는 게임 오브젝트에 자식 오브젝트가 있음을 의미합니다.
5. 화살표를 클릭하여 JohnLemon을 펼치고 자식 오브젝트를 확인합니다.
이 게임 오브젝트에는 JohnLemon과 Root라는 두 개의 자식 오브젝트가 있습니다. 자식 게임 오브젝트 JohnLemon을 선택합니다.
이 게임 오브젝트에는 Skinned Mesh Renderer라는 컴포넌트가 있습니다. 캐릭터를 나타나게 하는 컴포넌트입니다.
모델은 삼각형의 메시로 구성되어 있으며 Mesh Renderer는 이 메시를 "렌더링"하여 볼 수 있도록 합니다. Skinned Mesh Renderer는 Mesh Renderer의 특별한 유형으로 모델의 뼈대 전체의 위치와 회전을 기반으로 메시 모양을 변경할 수 있게 해 줍니다. 이러한 뼈대는 모델의 자식 게임 오브젝트입니다. JohnLemon의 뼈대는 모두 Root 게임 오브젝트의 자식입니다.
6. 계층 구조에서 Root 게임 오브젝트를 선택합니다. ALT 키(Windows) 또는 Option 키(macOS)를 누른 상태로 이름 왼쪽에 있는 화살표를 클릭하여 모든 자식 게임 오브젝트를 펼칩니다.
각각의 게임 오브젝트는 JohnLemon 바디의 일부를 구성합니다.
7. 툴바의 플레이 버튼을 클릭하여 플레이 모드를 시작합니다.
8. 계층 구조에서 LeftForeArm이라는 게임 오브젝트를 선택합니다. Transform 컴포넌트에서 Rotation 필드를 찾고 Y 값을 90으로 설정합니다.
씬 뷰에서 JohnLemon의 왼쪽 팔이 90도로 꺾인 것을 볼 수 있습니다. 기본적으로 이렇게 JohnLemon 캐릭터를 애니메이션화하게 됩니다. 부모 게임 오브젝트에 있는 Animator 컴포넌트가 모든 뼈대 오브젝트의 Transform 컴포넌트 회전값을 변경하며, 여러 부분의 변경이 동시에 이뤄지며 캐릭터를 애니메이션화합니다.
9. 플레이 버튼을 다시 눌러 플레이 모드에서 나갑니다. 플레이 모드 중에 변경한 사항은 종료 시 저장되지 않는다는 점에 유의하세요.
10. Alt 키(Windows) 또는 Option 키(macOS)를 누른 상태에서 JohnLemon 부모 게임 오브젝트 옆에 있는 화살표를 클릭하여 모든 게임 오브젝트를 다시 접습니다.
캐릭터 생성 과정을 더 배우기 전에 프리팹에 대해 알아보고, 프리팹이 게임 개발에 어떤 도움을 주는지 살펴보겠습니다.
5. 프리팹이란?
프리팹은 이미 설정된 컴포넌트가 포함된 단일 게임 오브젝트나 하나로 묶인 여러 게임 오브젝트를 나타내는 특수한 형태의 에셋입니다. 프리팹은 동일한 사물의 인스턴스를 만드는 데 사용되는 청사진과 같습니다. 프리팹의 인스턴스는 각각 프리팹 에셋에 연결되어 있기 때문에 에셋을 변경하면 모든 씬에서 프리팹의 모든 버전이 변경됩니다.
이 프로젝트에서는 캐릭터를 프리팹으로 만드는 것을 시작으로 이 시스템을 사용하게 됩니다. 따라서 게임에서 여러 레벨을 만들게 되는 경우, 레벨마다 JohnLemon을 다시 제작할 필요 없이 새 프리팹만 인스턴스화하면 됩니다.
프리팹의 이름과 아이콘은 계층 창에서 파란색으로 구분됩니다.
여기서 주의해야 할 점이 있습니다. JohnLemon 게임 오브젝트의 이름과 큐브 아이콘이 파란색으로 표시되어 있지만 큐브 위에 작은 흰색 종이가 있습니다. JohnLemon 게임 오브젝트는 이미 프리팹인 것일까요?
그렇다고 할 수 있습니다. Unity에서 모델은 읽기 전용 프리팹처럼 작동합니다. 읽기 전용 프리팹은 모델의 인스턴스를 생성하기 위한 청사진이지만, 청사진 자체는 변경할 수 없습니다.
6. 캐릭터를 프리팹으로 변환
이 프리팹을 변경할 수 있어야 하므로, 조정할 수 있는 새로운 프리팹을 만들어 보겠습니다.
1. 계층 구조에서 게임 오브젝트를 드래그하여 프로젝트 창의 Assets > Prefabs 폴더로 가져옵니다. Original Prefab 또는 Prefab Variant 생성을 원하는지 묻는 대화 상자가 나타나면 Original Prefab을 선택합니다.
이러한 방식으로 게임 오브젝트를 드래그하면 어떤 폴더에 드래그하더라도 게임 오브젝트가 프리팹으로 변환됩니다. 프로젝트를 간결하게 유지하려면 모든 프리팹을 프리팹 폴더에 저장하는 것이 좋습니다.
2. 이제 JohnLemon 프리팹이 생성되었으며, 이 프리팹을 변경하면 씬에 있는 JohnLemon 프리팹의 인스턴스에 반영됩니다. 프리팹을 수정하려면 프리팹 모드에서 열어야 합니다. 그 전에 먼저 Ctrl+S(Windows) 또는 Cmd+S(macOS)를 눌러 씬을 저장합니다.
이제 JohnLemon 프리팹을 열 수 있습니다.
3. 인스펙터 창에서 Open Prefab 버튼을 클릭합니다.
Unity 에디터가 이제 프리팹 모드로 전환됩니다. 이 모드에서는 수정 중인 씬의 밖으로 이동하여 프리팹만 있는 임시 씬으로 전환됩니다. 씬 뷰가 약간 변경된 것을 확인할 수 있습니다. 왼쪽 상단에 Scenes | JohnLemon이라고 적힌 바가 새로 만들어졌으며 오른쪽에는 Auto Save라고 적힌 체크박스가 있습니다.
Scenes | JohnLemon은 현재 프리팹 모드에서 수정되고 있는 프리팹의 정보를 나타냅니다. 이 경우 JohnLemon 프리팹만 수정하고 있기 때문에 뒤로 가면 수정 중이던 씬으로 돌아가게 됩니다.
4. Auto Save 체크박스를 비활성화합니다. 활성화할 경우 속도가 느려집니다. 프리팹을 변경한 내용을 직접 저장할 수 있도록 Save 버튼이 표시됩니다.
5. 계층 창에도 상단에 새로운 바가 생성되었습니다.
왼쪽에는 경로를 따라 돌아갈 수 있는 화살표가 있습니다. 화살표를 클릭하면 MainScene으로 돌아갑니다.
이 3D 초급자용 프로젝트 과정 전반에서 프리팹을 수정하게 되며, 수정은 대부분 프리팹 모드에서 진행됩니다. 따라서 씬 내 게임 오브젝트 수정과 프리팹 수정 간의 전환에 익숙해져야 합니다.
이제 JohnLemon 프리팹을 변경하며 애니메이션을 적용해 보겠습니다.
7. 캐릭터 애니메이션화
이 게임에서 플레이어 캐릭터에 적용될 애니메이션은 두 가지로, 플레이어가 움직일 때의 걷기 애니메이션과 움직이지 않을 때의 대기 상태 애니메이션입니다.
JohnLemon 게임 오브젝트를 선택하고 인스펙터에서 Animator 컴포넌트를 확인합니다. 첫 번째 프로퍼티는 Controller입니다. 이 컨트롤러는 JohnLemon을 움직이는 데 사용할 Animator 컨트롤러라는 에셋 유형을 참조합니다.
Animator 컨트롤러에는 상태 머신이 포함되어 있습니다. 상태 머신은 Animator 컴포넌트가 특정 시간에 해당 계층 구조에서 어떤 애니메이션을 설정해야 하는지 결정합니다. 이 애니메이션은 Animator 컨트롤러에서 설정된 애니메이션 클립을 기반으로 합니다.
8. Animator 컨트롤러 만들기
Animator 컨트롤러를 만드는 방법은 다음과 같습니다.
1. 프로젝트 창에서 Assets > Animation > Animators 폴더를 찾습니다. 폴더를 오른쪽 클릭한 다음 Create > Animator Controller를 선택합니다.
2. Animator 컨트롤러 이름을 "JohnLemon"으로 설정하고 더블 클릭해 Animator 창에서 편집을 시작합니다.
Animator 창의 2가지 주요 섹션은 다음과 같습니다.
- 애니메이터 레이어 및 애니메이터 파라미터 수정을 위한 왼쪽 패널
- 상태 머신을 표시하는 오른쪽 공간
3. Animator 창 왼쪽 상단에 있는 Parameters 탭을 클릭합니다.
Animator 컨트롤러의 상태 머신은 애니메이터 파라미터의 현재 값에 따라 결정을 내립니다. 이러한 애니메이터 파라미터의 값은 스크립트로 설정되어 있습니다. 캐릭터가 플레이 중인 애니메이션에 영향을 줄 수 있는 독립 변수마다 하나의 파라미터가 필요합니다.
JohnLemon에 적용될 애니메이션은 두 가지로, 움직이지 않을 때의 대기 상태 애니메이션과 움직일 때의 걷기 애니메이션입니다. 따라서 JohnLemon은 걷는 상태 또는 걷지 않는 상태에 있게 됩니다.
파라미터에는 다음 네 가지 유형이 있습니다.
- float 파라미터는 부동 소수점 변수로 소수점을 포함합니다.
- int 파라미터는 소수점이 없는 정수 값을 갖습니다.
- bool 파라미터는 참 또는 거짓으로 표현되는 부울 방식의 값을 갖습니다.
- trigger 파라미터는 값을 갖지 않는 특별한 형태의 파라미터이며, 한 애니메이션에서 다른 애니메이션으로의 변환을 유발합니다.
이 경우에는 캐릭터가 걷고 있거나 정지해 있기 때문에 bool 파라미터가 가장 적절합니다.
4. 드롭다운 메뉴에서 + 버튼을 클릭하고 Bool을 선택하여 새로운 부울 애니메이터 파라미터를 생성합니다.
5. 새 애니메이터 파라미터의 이름을 "IsWalking"으로 지정합니다. 철자와 대문자에 주의하여 정확하게 입력해야 합니다. 그 이유는 다음 튜토리얼에서 첫 스크립트를 작성하면서 확인할 수 있습니다.
IsWalking 파라미터의 이름 오른쪽에 비활성화된 체크박스가 있습니다.
이는 파라미터의 기본값입니다. 플레이어 입력이 없으면 캐릭터는 정지 상태가 되므로 IsWalking은 false가 되어야 합니다. 따라서 지금은 값을 변경할 필요가 없습니다.
9. 애니메이션 설정
지금까지 플레이할 애니메이션을 결정하는 방법을 배웠습니다. 아직 준비된 애니메이션이 없으므로 한번 설정해 보겠습니다.
1. 프로젝트 창에서 Assets > Animation > Animation 창으로 이동합니다.
현재 애니메이션 파일은 미리보기가 가능한 아이콘으로 보입니다. 하지만 이 프로젝트에서는 목록 보기로 에셋을 확인하는 게 더 편리합니다. 프로젝트 창의 오른쪽 하단에 있는 슬라이더를 찾아 왼쪽으로 끝까지 드래그합니다.
2. 모델 다섯 개 중에 두 개의 이름이 John@으로 시작하는 것을 볼 수 있습니다. 이 명명 규칙을 통해 두 모델이 JohnLemon에 대한 애니메이션임을 알 수 있습니다.
John@Idle과 John@Walk를 모두 펼쳐서 서브 에셋을 확인합니다.
서브 에셋은 부모 게임 오브젝트의 직계 자식(모델은 게임 오브젝트로 인스턴스화됨), 메시, 애니메이션을 보여 줍니다. 이 두 모델의 경우 애니메이션은 각각 Idle과 Walk입니다.
3. Animator 컨트롤러에서 이러한 애니메이션을 사용하려면 프로젝트 창에서 애니메이션을 Animator 창으로 드래그합니다. Idle을 먼저 드래그합니다.
4. 애니메이션은 애니메이터 상태의 Animator 컨트롤러에 있습니다. Idle 및 Walk 애니메이션을 드래그하면 Animator 컨트롤러는 이 둘을 포함하는 상태를 각각 생성하여 애니메이션의 이름을 따서 명명합니다.
애니메이터 상태는 Animator 컨트롤러에 포함된 상태 머신의 일부입니다. 상태 머신은 어떤 상태를 현재 상태로 할지 결정하는 로직을 포함합니다. 그런 다음 현재 상태에 따라 플레이되는 애니메이션이 결정됩니다.
기본 상태는 주황색으로 표시됩니다. 이 경우 Idle을 먼저 드래그했기 때문에 기본 상태는 Idle입니다. 기본 상태를 변경하려면 상태를 오른쪽 클릭하고 Set As Layer Default State를 선택합니다.
이제 상태 머신에 두 가지 상태가 있습니다. 하지만 어떤 상태가 플레이되어야 하는지 결정할 로직은 없습니다. 상태 머신은 현재 기본 상태로 시작하여 절대 변경되지 않기 때문에 JohnLemon은 항상 대기 상태가 됩니다. 로직을 추가하려면 애니메이터 전환을 만들어야 합니다.
10. 애니메이터 전환 만들기
애니메이션 전환을 만드는 방법은 다음과 같습니다.
1. Idle 상태를 오른쪽 클릭한 다음 Make Transition을 선택합니다. 그러면 마우스 커서를 따라 전환이 시작됩니다.
전환 생성을 마치려면 Walk 상태를 클릭합니다.
2. 캐릭터는 걷기에서 대기 상태로 전환할 수 있어야 하므로, 위 과정을 반복하여 Walk에서 Idle로의 전환을 생성합니다.
상태 머신의 모습은 다음과 같습니다.
3. 이제 상태 머신은 두 애니메이션 간 전환이 가능해졌지만, 언제 전환해야 하는지에 대한 정보는 아직 없습니다. IsWalking 파라미터를 생성했던 것을 기억하시나요? 이 파라미터는 상태 머신이 애니메이션을 변경할지 또는 그대로 유지할지를 결정하는 데 사용됩니다.
연결선을 클릭하여 Idle에서 Walk로의 전환을 선택합니다.
4. 인스펙터에서 이 전환의 설정을 확인합니다. 가장 먼저 변경할 것은 Has Exit Time 체크박스입니다.
Has Exit Time이 참인 경우(체크박스가 활성화됨), 일정 시간이 지나면 전환이 자동으로 수행되고 상태 머신은 다음 상태를 플레이합니다. 이 게임에서는 전환이 발생하는 시점을 적절히 제어해야 하므로 Has Exit Time 체크박스를 비활성화합니다.
이제 인스펙터 창 아래쪽에 "Transition needs at least one condition or an Exit Time to be valid, otherwise it will be ignored."라는 경고가 표시됩니다. Has Exit Time 체크박스를 비활성화했기 때문에 현재는 이 전환을 수행할 필요가 없습니다. 조건을 추가하여 전환 하나를 생성해야 합니다.
11. 전환에 조건 추가
조건을 전환에 추가하는 방법은 다음과 같습니다.
1. 현재는 비어 있는 Conditions 목록 아래의 + 버튼을 클릭합니다.
2. 캐릭터가 걷기 중일 때 Idle에서 Walk로의 전환이 필요합니다. 즉 IsWalking이 true일 때입니다.
여기에서 바로 이전에 생성된 기본 조건이 사용됩니다. IsWalking이 true인 경우 JohnLemon은 Idle에서 Walk로 전환해야 합니다. 따라서 설정을 변경할 필요가 없습니다.
다음으로 Walk에서 Idle로의 전환을 설정해야 합니다. 이 전환에도 비슷한 요구 사항이 있습니다.
3. Animator 창에서 Walk에서 Idle로의 전환을 선택합니다. Has Exit Time 체크박스를 비활성화합니다. 이전과 마찬가지로 일정 시간이 지나 상태가 변하도록 하는 것이 아니라 원하는 때에 변하도록 합니다.
4. Has Exit Time 체크박스가 비활성화되었으므로 또 다른 조건을 하나 생성해야 합니다.
이 조건 역시 IsWalking을 확인해야 하는데, 이번에는 값을 false로 설정해야 합니다. 캐릭터가 걷기 중이 아니라면 Walk에서 Idle로 전환해야 합니다.
이제 Animator 컨트롤러 설정이 완료되었습니다.
12. Animator 컨트롤러를 JohnLemon 프리팹에 할당
JohnLemon 프리팹에 Animator 컨트롤러를 할당하는 단계가 남아 있습니다.
1. 프로젝트 창에서 Assets > Animation > Animators로 이동하여 JohnLemon Animator 컨트롤러를 찾습니다.
2. 계층 구조에서 JohnLemon 게임 오브젝트를 선택한 다음 Animator 컨트롤러를 인스펙터에서 Animator 컴포넌트의 Controller 프로퍼티로 드래그합니다. 이 과정을 거쳐야만 JohnLemon이 움직일 수 있게 됩니다.
3. 씬 창 오른쪽 상단에 있는 Save 버튼을 클릭합니다. 경우에 따라 Scene 탭을 선택해야 할 수도 있습니다.
이제 JohnLemon 프리팹의 모든 인스턴스가 업데이트되어 변경 사항이 적용됩니다.
13. 캐릭터가 물리에 반응하도록 설정
이제 캐릭터는 방과 복도가 여러 개 있는 유령의 집을 돌아다니며 탐색합니다. 하지만 캐릭터는 유령이 아니기 때문에 벽을 통과하게 해서는 안 됩니다.
이를 구현하려면 다음 단계에 따라 JohnLemon 프리팹이 물리에 반응하도록 해야 합니다.
1. 프리팹 모드에서 수정하기 위해 JohnLemon 프리팹을 엽니다. 인스펙터를 보면 Transform과 Animator라는 두 가지 컴포넌트가 있습니다. 물리에 반응하려면 캐릭터에 Rigidbody와 Collider라는 두 가지 컴포넌트가 추가로 필요합니다.
Rigidbody 컴포넌트는 게임 오브젝트를 이동 가능한 물리 시스템의 한 부분으로 표시합니다. 캐릭터가 움직이고 벽을 통과하지 못하도록 하여 물리 시스템의 일부로 만드는 것이 목표이기 때문에 JohnLemon 게임 오브젝트에 Rigidbody 컴포넌트가 필요합니다.
2. Add Component 버튼을 클릭합니다.
3. 검색창이 표시되면 'Rigidbody'를 입력하고 표시되는 옵션에서 Rigidbody를 선택합니다.
이 프로젝트는 3D 프로젝트이므로 Rigidbody 2D가 아닌 Rigidbody를 클릭합니다. 실수로 컴포넌트를 추가했다면 컴포넌트 컨텍스트 메뉴(컴포넌트 오른쪽 상단의 톱니바퀴)를 사용하여 제거할 수 있습니다.
4. 지금까지의 작업 내용이 없어지지 않도록 JohnLemon 프리팹에 저장합니다.
5. 이제 JohnLemon 프리팹에 Rigidbody 컴포넌트가 추가되어 중력 등의 물리 효과에 반응하게 됩니다. 플레이 모드를 시작하여 작동하는 모습을 확인해 보겠습니다. 씬 뷰의 상단에 있는 Scenes를 클릭하여 MainScene으로 돌아간 뒤 툴바에 있는 플레이 버튼을 누릅니다.
캐릭터가 조금 아래로 내려가고 멈추는 걸 보니 무언가 잘못된 것 같습니다. 플레이 버튼을 눌러 플레이 모드에서 나갑니다.
이 부분은 애니메이터에서 다룹니다. Animator 컴포넌트의 세 번째 프로퍼티는 Apply Root Motion이며 현재 활성화되어 있습니다.
14. 루트 모션이란?
애니메이션은 특정 계층 구조 내에서 모든 게임 오브젝트를 이동하고 회전하는 데 사용됩니다. 이러한 이동과 회전의 대부분은 부모 오브젝트에 연관되어 발생합니다. 하지만 계층 구조의 부모 게임 오브젝트에는 부모가 없기 때문에 움직임에 영향을 받지 않습니다. 이 부모 게임 오브젝트는 루트라고도 불리며, 이 오브젝트의 움직임을 루트 모션이라고 부릅니다.
주의: JohnLemon 프리팹의 계층 구조에서 루트라고 불리는 게임 오브젝트는 골격의 루트를 가리키는 것이며, 실제 루트 게임 오브젝트를 가리키는 것이 아닙니다. 루트 게임 오브젝트는 Animator 컴포넌트가 위치한 게임 오브젝트를 가리키며 이 경우에는 JohnLemon이라는 게임 오브젝트가 이에 해당합니다.
Animator 컴포넌트에서 Apply Root Motion이 활성화되어 있으므로, 애니메이션에 있는 루트의 모든 움직임이 프레임마다 적용됩니다. 애니메이터가 Idle 상태로 플레이 중이기 때문에 움직임이 없으므로 애니메이터가 움직임을 적용하지 않습니다. 그렇다면 JohnLemon 게임 오브젝트는 왜 움직이는 걸까요? 바로 애니메이터의 업데이트 모드 때문입니다.
15. 업데이트 루프란?
영화와 TV의 원리와 마찬가지로, 게임에서도 화면에 이미지가 표시되고 이 이미지가 초 단위로 여러 번 바뀌면서 마치 움직이는 것처럼 보입니다. 이러한 이미지들을 프레임이라고 하며 프레임이 화면에서 표현되도록 하는 과정을 렌더링이라고 합니다. 영화와 TV의 경우 대개 다음에 표시될 이미지가 미리 정해져 있습니다. 하지만 게임에서는 사용자가 다음 상황에 영향을 미치기 때문에 다음 이미지에 대한 경우의 수가 굉장히 많습니다. 각각의 이미지는 사용자 입력에 따라 산출되어야 하고 사용자의 선택은 매우 짧은 순간마다 발생하기 때문에, 다음에 무엇을 표시할지 결정하는 프로그래밍도 이와 동일한 속도로 작동합니다. 이것을 업데이트 루프라고 합니다.
프레임이 표시될 때마다 많은 일들이 차례로 발생합니다. 현재로서는 커스텀 컴포넌트가 업데이트 메서드를 호출하며 화면에 새로운 이미지가 렌더링된다는 것만 알면 됩니다. 이러한 업데이트의 길이는 계산 및 렌더링의 복잡도에 따라 다양합니다. 하지만 모든 물리 작업을 실행하는 또 다른 루프가 있습니다. 이 루프는 업데이트 빈도에 변화가 없다는 것이 특징이며 이 때문에 FixedUpdate라고 부릅니다.
Animator 컴포넌트는 업데이트 수행 시점을 변경할 수 있습니다. 기본적으로 Animator 컴포넌트는 렌더링에 따라 업데이트를 수행합니다. 이는 애니메이터가 Update에서 캐릭터를 이동하고 동시에 리지드바디가 Fixed Update에서 캐릭터를 이동함을 의미합니다. 이 때문에 위와 같은 문제가 발생했지만 간단히 해결할 수 있습니다.
16. JohnLemon의 이동 문제 해결
먼저 프리팹 수정으로 돌아갑니다.
1. 인스펙터 창에서 Prefab 옆에 있는 Open 버튼을 클릭합니다.
2. Animator 컴포넌트로 이동합니다. Update Mode 프로퍼티 드롭다운에서 Animate Physics를 선택합니다.
이렇게 하면 애니메이터가 물리에 맞게 캐릭터를 이동하게 됩니다. 이제 캐릭터를 이동하는 업데이트 루프 간 경합이 없기 때문에 캐릭터가 물리에 제대로 반응하게 됩니다.
3. 현재 캐릭터의 애니메이션에는 수직 루트 모션이 없습니다. 하지만 JohnLemon이 무언가와 충돌한 후 수직으로 이동하게 될 수도 있습니다. 수직 이동을 중단하는 방법이 몇 가지 있습니다.
가장 확실한 옵션은 Rigidbody 컴포넌트에서 Use Gravity를 비활성화하는 것입니다.
이 방법을 사용하면 캐릭터가 아래로 떨어지는 것을 막을 수는 있지만 확실한 방법은 아닙니다. Use Gravity를 비활성화하더라도 캐릭터는 충돌로 인해 아래로 떨어지거나 위로 올라갈 수 있습니다. 따라서 이러한 상황을 막으려면 물리를 통해 캐릭터의 이동을 제한해야 합니다.
4. RigidBody 컴포넌트를 찾고 화살표를 클릭하여 Constraints 프로퍼티를 펼칩니다.
이러한 Constraint 프로퍼티는 리지드바디가 이동할 수 있는 방향을 제한합니다.
Unity의 좌표 시스템을 탐색하여 어떻게 작동하는지 알아보겠습니다.
17. Unity의 좌표 살펴보기
Unity 내 위치 및 방향은 x, y, z로 표시되는 3D 좌표를 통해 작동하며 좌표는 벡터를 형성합니다. 벡터에 대한 자세한 정보는 다음 튜토리얼에서 확인할 수 있습니다. 씬에는 씬 창의 우측 상단에 방향을 표시하는 씬 기즈모가 있습니다.
색깔이 있는 화살표는 각각의 축에 대한 양의 방향을 나타내며 반대쪽의 회색 화살표는 음의 방향을 나타냅니다.
- x축: 빨간색
- y축: 초록색
- z축: 파란색
18. 위치 및 회전
씬에서 부모가 없는 게임 오브젝트는 모두 씬의 원점(0, 0, 0)을 기준으로 배치됩니다. 부모가 있는 게임 오브젝트는 모두 부모를 기준으로 위치가 정해집니다. 하지만 게임 오브젝트는 회전 가능하기 때문에 자식의 상대 또는 로컬 위치는 부모의 회전된 좌표를 따릅니다. Rigidbody Constraints가 나타내는 것이 바로 이 로컬 좌표(또는 축)입니다.
이제 JohnLemon 게임 오브젝트의 로컬 축을 살펴보겠습니다.
1. JohnLemon 게임 오브젝트를 선택하고 씬 뷰를 확인합니다.
확인할 수 있는 내용은 다음과 같습니다.
- x축(빨간색): 캐릭터의 오른쪽
- y축(초록색): 캐릭터의 위쪽
- z축(파란색): 캐릭터의 앞쪽
2. 그러면 캐릭터에 어떤 제약을 적용해야 할까요?
캐릭터는 앞과 좌우로 움직여야 하기 때문에 x 또는 z 위치를 제한할 필요는 없습니다. 하지만 위아래로 움직이지는 않아야 하기 때문에 이 움직임을 중단하려면 Freeze Position Y 체크박스를 활성화합니다.
3. 회전은 특정 축을 중심으로 한 회전을 가리킵니다. 예를 들어 캐릭터가 x축을 중심으로 회전한다면 위나 아래를 향한 채로 누워 있는 것처럼 보일 것입니다.
z축을 중심으로 회전한다면 옆쪽으로 누워 있는 것처럼 보일 것입니다.
JohnLemon이 위와 같은 방식으로 이동해서는 안 되므로 Freeze Rotation X 및 Z 체크박스를 활성화합니다. 또한 JohnLemon이 몸을 돌릴 수 있도록 해야 하므로 Freeze Position Y 체크박스를 활성화 상태로 유지합니다.
이제 Rigidbody 컴포넌트가 설정되어 캐릭터가 물리 시스템에 반응하게 됩니다. 하지만 씬에서 물리적인 존재감을 갖는 것은 아니기 때문에 무언가가 캐릭터에 부딪히거나 캐릭터가 무언가에 부딪칠 수는 없습니다. 씬에서 캐릭터가 물리적 존재감을 갖게 하려면 콜라이더가 필요합니다.
19. JohnLemon에 콜라이더 추가
콜라이더는 여러 컴포넌트를 총칭하는 용어입니다. 콜라이더는 물리적 충돌을 목적으로 오브젝트의 형태를 정의하여 캐릭터가 충돌하거나 충돌을 받도록 만들 수 있습니다. 다양한 형태의 Collider 컴포넌트가 있는데 JohnLemon에게 가장 적합하며 단순한 것은 Capsule Collider입니다.
1. 인스펙터 창에서 Add Component 버튼을 클릭하고 Capsule Collider를 찾습니다. Capsule Collider 옵션을 선택하되 Capsule Collider 2D를 클릭하지 않도록 주의합니다.
2. 현재 Capsule Collider가 모델에 제대로 적용되지 않았기 때문에 게임에서 충돌이 올바르게 작동하지 않습니다. 따라서 Capsule Collider의 크기를 조절하고 위치를 변경하여 JohnLemon의 형태에 근접하게 만듭니다.
Capsule Collider의 Height 프로퍼티를 1.4로 변경하고 Center 프로퍼티를 0, 0.7, 0으로 변경합니다.
이렇게 하면 콜라이더의 중간 지점이 지면을 기준으로 한 높이의 절반이 되는데, JohnLemon의 키가 약 1.4m이기 때문에 지금 형태가 JohnLemon에 잘 적용되었다고 할 수 있습니다.
3. 하지만 폭은 아직 큰 편이기 때문에 Capsule Collider의 Radius 프로퍼티를 0.4로 변경합니다.
이제 캡슐이 캐릭터의 형태에 근접해졌습니다.
원하던 대로 캐릭터가 물리에 반응하게 됐습니다. 이제 벽에 부딪치더라도 넘어지지 않습니다.
20. 요약
이번 튜토리얼에서는 게임에 사용할 캐릭터에 대한 작업을 시작해 보았습니다. 프리팹의 강력한 기능을 조금이나마 엿보고 JohnLemon의 행동을 제어하는 간단한 규칙을 몇 가지 만들었습니다. 다음 튜토리얼에서는 첫 스크립트를 작성하여 캐릭터의 행동을 설정해 보겠습니다.