오늘부터 골드메탈님의 '유니티 뱀서라이크' 강의를 참고하여 게임을 만들어보려고 한다.
Vampire Survivors라는 게임과 비슷한 류의 게임을 만들어보는 강의이다.
이전에 Vampire Survivors와 비슷한 게임을 만들기 위해 Slime Survivor라는 게임 프로젝트를 진행했었는데, 실력이 부족한 상태에서 만든 게임인지라 퀄리티가 낮고 게임의 완성도가 조금 떨어지는 부분이 있었다.
그래서 이번에는 골드메탈님의 강의를 통해 완성도가 높은 게임을 만들어보고자 한다.
일단 오늘은 1일차라 기본적인 부분을 작업했다.
이렇게 총 4가지를 진행했다.
프로젝트에 사용할 Asset은 골드메탈님이 Asset Store에서 배포해주셔서 이를 다운받아서 사용했다.
https://assetstore.unity.com/packages/2d/undead-survivor-assets-pack-238068

이 Asset은 Sound, Sprite, Font 등 게임 제작에 필요한 다양한 File을 제공해주고 있다.
일단 먼저 Player Sprite를 사용하여 Player Object를 만들었다.

위 사진을 보면 Dead, Run, Stand 총 3가지 상태에 대한 Sprite가 있다.
각 상태에 따른 Sprite를 하나의 Animation으로 생성했고, Animator를 통해 상태 변화에 따라 Animation이 재생될 수 있도록 했다.

이제 Player가 움직일 수 있도록 Input 관련하여 코드를 작성해야했는데, 기존에는 Input.GetAxisRaw로 Horizontal, Vertical 값을 읽어와서 직접 Player의 움직임을 제어했었다.
하지만 이번 강의에서 새로운 Input System을 배웠는데, 바로 Player Input이다.
Package Manager에 가서 Input System이라는 Package를 다운받으면 새로운 Input System을 사용할 수 있다.

다운받고나면 Component 추가에 Player Input이라는 Componenet가 생긴 것을 볼 수 있다.
이 Component를 Player에 추가하고 새로운 Action을 만들어주면 된다.
Action을 생성 후 열어보면 다양한 값들이 있는데, 이 중에 Player - Move의 값을 설정해주었다.
나는 Player의 상, 하, 좌, 우 4가지 방향 값이 필요하기 때문에 Action Type은 Value로, Control Type은 Vector2로 설정했다.
그리고 맨 아래에 Processors라는 Field에서 Normalize된 Vector2 값을 받아올 수 있도록 값을 추가했다.
이렇게 설정하고나면 OnMove라는 함수로 입력 값을 받아올 수 있다.

파라미터로 InputValue 타입의 값을 받아와서 내가 설정한 대로 Vector2 값을 Get해주면 내가 입력한 방향 Vector2 값이 return 된다.
이렇게 받아온 Vector2 값을 사용하여 Player의 이동 및 위에서 설정한 Animator를 조절해주면 된다.



Player가 움직이면 Player를 따라 Main Camera도 움직여야할 필요가 있다.
Main Camear가 Player를 따라가게하는 기능을 추가하기 위해 기존에 사용했던 방법인 Main Camera의 Position을 Player의 Position으로 Update 시키는 코드를 추가하려고 했다.
하지만 강의 영상에서 새로운 방법인 Cinemachine이라는 것을 배워서 이를 사용해보았다.
Package Manager에서 Chinemachine을 다운받으면 Cinemachine이라는 Object를 만들 수 있는데, 그 중 Virtual Camera를 만들면 기존에 있는 Main Camera에 자동으로 CinemachineBrain이라는 Component가 추가된다.


이 때, Virtual Camera의 Inspector에 있는 Follow 속성에 Player를 추가하게되면 Main Camera가 Player가 움직이는 방향으로 따라오게 된다.

카메라가 움직일 때 Player의 Object가 부들부들거리는 현상은 현재 Player의 이동이 Fixed Update에서 구현이 되었기에, Main Camera의 Chinemachine Component에서 Update Method를 Fixed Update로 바꿔주면 된다.
TileMap을 사용하여 게임의 배경이 될 맵을 만들었다.
이전에 TopDown RPG에서 사용했었던 Rule Tile을 사용하여 지정한 Sprite가 Random하게 배치되는 Rule Tile을 만들었다.


이 Rule Tile을 사용하여 Rule Tile에 등록되어있는 Sprite 중 하나가 선택되어 Tile이 만들어지도록 했다.

이 게음은 Player가 한정된 장소에서 움직이는게 아니라 무한히 넓은 Field를 돌아다니면서 따라오는 적을 잡는 게임이다.
따라서 배경이 되는 맵도 Player를 따라 무한하게 배치가 되어있어야 한다.
하지만 이는 물리적으로 불가능하기 때문에 기존에 만들어져 있던 Tile Map을 재배치하는 방식으로 무한 맵을 구현했다.
일단 Rule Tile을 사용하여 30 x 30의 Tile Map 4개를 만들어서 Player를 중앙으로 두고 각 Tile Map을 배치했다.


각 Tile Map은 Composite Collider를 통해 하나의 Colldier로 지정했고, Player 또한 30 x 30의 Box Collider를 갖고 있으면서 이 Collider가 특정 TileMap의 Collider와 벗어나는 경우 TileMap의 Position을 변경시켜주었다.
예를 들어, Tile Map의 좌표가 (0, 0)이고 Player의 좌표가 (30, 0)일 때 두 Object의 Collider가 떨어지게 되므로 이 순간을 확인하여 Tile Map의 좌표를 (60, 0)으로 바꿔주는 것이다.

OnTriggerExit2D 함수에서 X축이나 Y축으로 groundLen(30)만큼 떨어져있다면 Player의 이동방향 앞에 다시 재배치되는 식으로 코드를 작성했다.

Player가 움직이는 방향 반대쪽의 Tile Map이 Player의 앞으로 이동하면서 Tile Map의 바깥 부분이 보이는데, Tile Map이 이동하는 것을 보이기 위해 Player의 속도를 빠르게 설정했기 때문에 위와 같은 현상이 발생한 것이다.
실제 게임 플레이에선 Player의 속도가 저 정도로 빠르기 않기에 Tile Map 바깥 부분이 보이는 현상은 발생하지 않는다.

Camera를 땡겨서 확인한 결과 Player가 이동함에 따라 해당 방향으로 Tile Map이 재배치되는 것을 볼 수 있다.

Tile Map은 4개밖에 없지만 특정 방향으로 계속 움직여도 맵이 끝기지 않는 것을 볼 수 있다.