본문 바로가기
유니티5 독학 & 게임 제작

유니티5 독학하기 그 57번째 걸음-드디어 본격적인 게임 만들기 실습

by 인터넷떠돌이 2018. 7. 19.
반응형

안녕하세요?


유니티 NGUI 게임 프로젝트라는 책을 보고서 어느정도 2D 유저 인터페이스를 만들 기초를 다진 것 같아서, 이번에는 예전부터 보았던 책인 유니티 5.X,와 함께하는 C# 첫걸음 이라는 책에 있는 내용을 바탕으로 일단 에셋이랑 이런 것을 처음부터 만들 단계는 아니기 때문에, 하는 수 없이 책에서 제공해 주는 프리펩 등을 이용해서 간단한 런 게임을 만드는 실습을 시작하고자 합니다.


원래는 챕터9의 내용을 한개의 포스팅안에 끝내려고 했는데, 분량이 너무 길어져서 하는 수 없이 중간에 짤라야 했습니다. 그래서 이번 포스팅에서는 런게임에서 어떻게 해서 플레이어 캐릭터와 바닥을 설치하며, 어떻게 해서 점프하는 기능을 만들 수 있는지를 실습해 보았고, 그 내용을 포스팅 하고자 합니다.



먼저 위 스크린샷과 같이 새로운 프로젝트를 시작해야 하는데, 일단 Testgameproject라고 이름을 지었고, 2D에 체크표시를 한 다음에 NGUI가 필요할까 싶어서 일단 안에다가 심어 놓기로 했습니다.



그리고 이번에는 실습을 위해서 이미 만들어져 있는 유니티projectfile을 출판사의 홈페이지에서 다운로드 받아서, Player라는 것을 더블클릭합니다.



그러면 자동으로 이 Player라는 프로젝트 안에 있는 내용물들이 모두 받아들이기가 가능해 집니다.



일단 Assets라는 폴더에 Player프리펩이 있는 것을 볼 수 있는데, 이런 상태로 두면 안됩니다.



Prefabs라는 폴더를 만든 다음에 모든 프리펩을 여기로 옮기도록 합니다. 이렇게 하는 이유는 너무 Assets폴더에 파일을 놔두면 나중에 복잡하게 되어서, 프로젝트를 진행하기에 힘들어 질 수 있기 때문입니다.



이제 플레이어 캐릭터를 게임뷰에 추가하기 위해서 우선 드레그 앤 드롭으로 Player프리펩을 계층뷰로 끌어다 놓으면 됩니다. 그러면 위 스크린샷에서 볼 수 있듯이 게임 오브젝트가 만들어 지는 것을 볼 수 있습니다.



이제 인스펙터뷰를 보면, RigidBody2D와 Circle Collider 2D가 있는지를 확인해 보도록 합니다. 일단 물리법칙이라고 해야 할까요? 이런 법칙이 적용되게 하려면 RigidBody2D가 필요합니다. 그리고 어딘가 충돌이 일어나려면 Collider가 필요한데, 여기서는 Circle Collider 2D가 적용이 된 것입니다.




이제 플레이어 캐릭터가 추가되었으니, 이번에는 FloorShort 프로젝트 파일을 유니티5에 추가하도록 합니다. 역시나 더블클릭해서 누르기만 하면


이렇게 이번에도 자동으로 모든 요소를 다 가지고 오도록 합니다.



자동으로 이번에는 Prefabs라는 폴더에 들어가 있는 것을 볼 수 있습니다.



여기서도 역시 드래그 앤 드롭으로 계층뷰에 끌어다 놓아서 게임 오브젝트를 하나 만들어 주도록 합니다.



이제 씬을 보면, 주인공의 플레이어 캐릭터(제이크)와 바닥이 추가된 것을 볼 수 있습니다.



그 다음으로는 Scripts라는 폴더를 만들어서 앞으로 작성되는 모든 스크립트는 여기다가 집어 넣도록 합니다.



그리고 Player게임 오브젝트에 Add Component를 써서 위 스크린샷처럼 C#언어로 PlayerController.cs를 추가하도록 합니다.




이제 새로 생성된 스크립트를 Scripts라는 폴더 안으로 집어 넣도록 합니다.



이제 위 스크린샷처럼 코딩을 하도록 합니다. 우선 public float jumpforce=6f;라는 변수선언이 있는데 6뒤에 붙은 f는 float이라는 타입의 실수형 변수를 선언할 때는 이렇게 뒤에 실수라는 의미로 F를 붙입니다. 그리고 private RigidBody2D vb;라는 변수 선언은 바로 Rigidbody2D라는 컴포넌트를 가지고 오는 변수 선언입니다.



그리고 여기서 나오는 Input.GetMouseButtonDown(0)이라는 것은 바로 마우스 버튼을 누를 때 true라는 값을 주는데, 여기서는 0=왼쪽 마우스 클릭, 1=오른쪽 마우스 클릭, 2=가운데 마우스 버튼 클릭이라는 의미가 있습니다. 



다음으로는 RigidBody2D.AddForce라는 함수가 있는데, 이 함수는 유니티5의 레퍼런스를 보면 나와 있듯이 특정한 조건에서 어느 방향으로 힘을 줄 것이냐를 지정할 수 있습니다.


Rigidbody2D.AddForce(force,mode);


여기서 force라는 것은 주로 방향을 이야기 하는데, 2D이기 때문에 당연하다면 당연하게도 Z축은 없고, X축이나 Y축만이 있습니다. 그래서 Vector2.up이라는 내용은 바로 위로 향하라는 것이고, *jumpforce는 얼마만큼 올라가게 할 것이냐 하는 것입니다. 


mode에 대해서는 좀 상당히 설명할 것이 일단 많습니다.



유니티5의 래퍼런스를 읽어 보고나서, ForceMode2D.Impulse라는 의미는 2D에서 힘을 가하게 하는데, 여기서는 주로 force와 impulse 두 종류가 있는데 force는 계속해서 힘을 가하는 것으로 보이고, impulse에서는 그냥 한번만 일시적으로 가하는 것입니다.



왜인지 계속해서 에러가 떴는데, 알고보니 Awake에서 e한자를 빼먹는 오타로 인해서 생긴 것이였습니다. 일단 이 Awake()는 Start()보다도 먼저 호출이 되어서 실행이 되는데, 이 함수는 주로 Start()를 들어가기 전에 한번만 선언해야 하는 내용들을 설정하는데 정말 유용합니다.



그 다음에는 그냥 실행을 시켜서 점프를 시켜보니, 너무 낮게 뛰어서 한번 25정도로 인스펙터 뷰에서 수정을 했습니다. 여기서 또 주의해야 할 것이 있는데, 스크립트상에서 한번 선언을 하면, 다음에 아무리 바꾸기를 해도 적용이 안되고, 유니티5의 인스펙터 뷰에서 수정을 해야만 합니다.




한번 실행을 시켜 보니까, 무슨 허공답보라고 해야 할까요? 계속해서 공중으로 뜰 수 있는 오류가 발생하였습니다. 이건 이 게임에서 원하는 동작이 안되기 때문에, 작업에 들어가야 합니다.



그래서 위에 있는 Jump()라는 사용자 정의 함수에 IsGrounded()라는 리턴(return)값의 상태에 따라서 연속적인 클릭이 불가능하게 만들었습니다.

그리고 먼저 레이어를 선언하는 public LayerMask groundLayer;를 선언하도록 하고, 변수가 상황에 따라 달라지는 함수가 bool IsGrounded()가 있습니다.



일단 여기서 먼저 등장하는 것이 Physics2D.Raycast라는 것인데 간단하게 말하자면, 특정한 지점에서 레이저를 쏘아서 거리를 측정하는 기능이라고 볼 수 있습니다. 이 함수는 우선 아래와 같이 사용을 합니다.


Physics2D.Raycast(origin, direction,distance,layerMask);


우선 origin은 다른것 없고, 어디에서 부터 이 레이저를 쏠 것이냐 하는 것입니다. this.transform.position이라는 것은 바로 이 스크립트가 붙어 있는 게임 오브젝트의 현재 transform에 속에 있는 것중에 하나인 position에서 부터, 즉 이 게임 오브젝트의 현재 위치에서 부터 레이저를 쏘라는 의미가 됩니다.


direction은 이제 레이저를 어느 방향으로 쏠 것이냐 하는 것인데, 여기서는 Vector2.down이라고 해서 아랬쪽으로 발사를 하라는 것이고, 이어서 distance는 당연 실수로 선언된 거리이며, 다음에 나오는 layerMask는 어떤 레이어에서 작동하느냐, 즉 아무 오브젝트에서 작동하면 곤란한 일이 일어나니 바닥하고만 반응하도록 이런 것을 사용하는 것 입니다.



이제 Edit>Project Settings>Tags & layers를 열어서 위 화면과 같은 인스펙터 뷰를 불러 오도록 합니다.



다음으로는 UserLayer8에 Ground라고 지정을 하도록 합니다.



이제 바닥의 레이어를 따로 설정할 차례가 되었습니다. 계층뷰에서 FloorShort를 선택하도록 합니다.



인스펙터 뷰에서 Layer를 Ground로 바꾸도록 합니다.



다음으로 Player게임 오브젝트를 계층뷰에서 선택하도록 합니다.



계층뷰에 있는 PlayerController스크립트 컴포넌트 항목으로 가면, 앞서 선언을 해둔 public LayerMask GroundLayer;라는 변수를 지정해야 하는 항목이 있는 것을 볼 수 있습니다. 여기서 당연 Ground를 선택하도록 합니다.



이제 최종적으로 완성이 된 결과물 입니다. 이번에는 바닥에서 얼마 이하 거리가 되지 않으면, IsGrounded가 false값이 되기 때문에, 연속해서 점프가 클릭되지 않아서 허공답포가 되지 않습니다. 이것으로 이번 포스팅까지 완성된 작품을 보여드렸으며, 비로 예제가 완성되어 있는 키트를 조립하는 것이기는 하지만, 그래도 완성품을 만든다는 느낌을 만들 수 있도록 한번 제작을 하도록 해 보겠습니다.

반응형