Unity 스터디 2회차 - 2D 게임 입문과 충돌 처리, 애니메이션

Lee Joon Woo·2020년 12월 30일
0

이번 회차에서는 2D의 기본적인 연습들을 대부분 해보았다. 간단한 2D 오브젝트 생성부터 그것들을 이용한 다양한 학습들을 진행하였는데, 아무래도 코딩은 많이 해보아서 그런지 대충 로직들은 머리에 들어오는 것 같다.

움직임 처리

처음에 한 것은 간단한 스프라이트에 스크립트를 달아서 거기서 내부적으로 Input값들을 확인하여 캐릭터를 이동해주는 것이였다. GetAxisRaw를 이용하면 좌우 상하를 각각 1과 -1값들로 받을 수 있게 되었다. GetAxis를 사용하면 같은 효과를 받을 수 있지만 대신에 서서히 1이나 -1쪽으로 가기때문에 이동이 점점 빨라지는 효과가 있다.


다만 이렇게 사용하게 되면 문제점이 한개 발생하는데 물리법칙을 적용하기 위해 RigidBody2D를 적용시켜 주게되면, 충돌처리가 일어나면서 다른 물체에서 밀려나기는 하는데, 강제적으로 transform값을 바꾸기 때문에 일단 이동이 일어난 후에 밀려나서 아래와 같이 상당히 이쁘지 않게 보이게 된다.

이를 해결하기 위해서는, transform값을 바꿔서 이동을 주는 것이 아니라 rigidBody의 velocity값 자체를 바꿈으로써 물리적인 계산을 안에서 할 수 있게 하면 해결되었다.

Prefab, Instantiate 그리고 Destroy

이후는 GameObject의 틀이라고 할 수 있는 Prefab을 만들어서 이를 이용해 스페이스바를 누르면 총알을 발사 할 수 있게 만들어주었다.

총알 Prefab에 넣은 스크립트에는 방향에 맞추어 이동해주는 스크립트, 그리고 Player스크립트에서 방향을 조절할 수 있도록, public으로 만들어준 setDirection 메소드가 있다.
Player단에서는 bullet 프리팹을 이용하여 스페이스가 눌릴때 instantiate를 해주고, 플레이어의 이동방향을 총알방향으로 설정해주었다. 가만히 있을때 총알도 쏠 수 있기에, 마지막으로 바라보고 있던 방향을 저장해두는것도 포함해두었다.

사진에는 보이지 않지만, 이 시점에서 문제는 총알이 화면 밖을 나가도, 없어지지않고 계속 게임오브젝트로써 메모리를 차지하고 있는 문제가 있었다. 이를 해결하기 위해 한가지는 이동거리에 따라 삭제해줄수도있고, 아니면 화면밖으로 나가는 오브젝트들에 대해서 삭제를 시켜줄 수 있었다. 본인은 후자쪽방식인, 총알이 특정 좌표를 넘어가면 삭제되도록 만들어주었다. Destroy의 인자로 나를 가리키는 변수인 gameObject를 전달해주어서 총알 본인을 삭제시키게 만들었다.

충돌처리 1

이 프로젝트에서 마지막으로 한 것은, 총알이 벽에 도달할때 총알이 없어지게 한 것이다.
이는 Collider를 이용해서 OnTriggerEnter함수를 이용하여 Destory를 대상 오브젝트로 해주었다.
이때 주의해야할 것은, Player는 단순히 부딪히고 끝나야하고, Bullet만 없어져야한다는 것이다. 이때 활용한것이 Tag라는 기능이다.
또한 OnCollisionEnter가 아닌 Trigger를 사용한 이유는, Collision으로 처리하면 Bullet과 Player모두 Collider를 가지고 있어서, 발사할때마다 Player가 밀려나는 효과가 생겨나서, 어쩔수 없이 현재는 이렇게 구현하였다.

2D 애니메이션

2D 애니메이션을 학습하기 위해서는 아무래도 이쁜 스프라이트를 사용하고 싶었고, 그렇기 때문에 Asset Store를 돌아다녀보면서 사용할만한 소스를 찾아서 새로운 프로젝트를 만들어주었다.
'Knight Sprite Sheet'라는 무료 에셋을 다운받아서 이를 이용하여 진행하였다.

처음에 구상한 것은, 총 4개의 애니메이션이었다. Idle, Walk, Attack, Push로 마지막은 앞 회차에서 말한 박스 밀기를 보여주고 싶어서 하려고 했었다. 하지만 현재로써는 나에게 만들어져있는 스프라이트는 Push가 없어서 일단 이건 빼고 3개를 제작하였다.

간단하게 모든 상태를 서로 왔다갔다 할 수 있게 애니메이터를 구현했다.
Idle과 Walk사이의 Transition은 isWalk이라는 bool변수를 조정하여 Has Exit Time False로 주어서 서로간에 바로바로 애니메이션 전환이 일어나게 하였고,
Idle, Walk 에서 Attack으로 가는 Transition은 isAttack이라는 Trigger를 주어서 전환을 시켰다. 마지막으로 Attack에서 다시 idle이나 Walk으로 가는것은 isWalk변수에 따라서 알아서 바뀌도록 만들어주었다.


추가로 Sprite들에 대해서는, 실험을 해보니 Local Scale의 x값이 음수로 바뀌게 되면 좌우반전효과가 일어나는 것을 발견하였고, 이를 이용해 오른쪽 스프라이트만 있지만 왼쪽도 자연스럽게 구현이 가능하다는 것을 발견하였다.

충돌처리 2

처음에 의도하였던, 박스는 미는것에 관해서는 단순히 두 물체 모두 Rigidbody2D를 가지고 있으면, Velocity와 Mass에 따라서 알아서 밀리게 되어있기에 크게 신경쓰지 않고 쉽게 만들어졌다. 다만 박스가 밀린뒤에 건드리지않았는데 추가로 밀리는 현상이있어서 이는 박스의 Linear Drag값을 최대치로 올려서 얼추 해결했다.
바깥의 벽의 경우에는 밀리지 않게 하려면, 단순히 rigidbody2D를 넣지 않고 Collider만 넣거나, 아니면 rigidbody2D의 body type을 Kinematic으로 설정해두면 아예 움직이지 않는 물체로 설정되어서 벽바깥으로 나가지 못하게 막을 수 있었다.

미는것이 너무 쉽게 끝나버려서 다른 추가할만한 점을 찾던 도중 Attack 모션을 만들었으니, 박스를 없애게 하고 싶었다. 아이디어를 구상하던 도중, 칼의 범위를 미리 만들어두고, 해당 공격범위를 trigger로써 애니메이션 도중에 잠시 생성시켰다가, 사라지게 하면 유사하게 구현할 수 있을것 같았다.

우선은 칼의 히트박스를 눈에 보이게 빨간색으로 생성시켜서 트리거로써 상자에 닿으면 사라지게 만들게 했다. 해당 히트박스는 Player의 자식으로 넣어져서, 위치가 Player의 이동에 따라서 잘 붙어서 이동되었다.

처음에는 이것을 Prefab으로 만들어서 스페이스바를 누를때 Instantiate를 하고 시간을 재서 다시 Destroy를 하는 방식을 썼었는데, 매우 코드가 더러워졌고 결국에 지인찬스를 써서 물어보았더니 애니메이션에서 해당 오브젝트의 자식들 Active여부를 애니메이션내에서 설정이 가능하다고 들어서 바로 적용시켰다.
기본적으로 Hitbox 오브젝트를 Disable시켜놓고, 공격 애니메이션 내부에서 잠시 Active시켰다가 다시 끄는 것을 적용하였다. 정확히 빨간 선이 그어진 부분만 Active시켜주었다. 이를 적용시켜서 적용시킨 결과다.


마지막으로 실제 공격하는것처럼 보이기위해서 색깔을 없애서 적용시킨 프로젝트의 최종모습이다.

다음 회차

유튜브 알고리즘에 의해서 아무생각없이 Unity 강의영상들을 보던 도중 Anima2D라는 에셋에 대해 알게되었고, 이를 이용해서 Inverse Kinematics로 이 캐릭터에 없던 미는 모션을 추가해줄 것 같다. 전부다 갈아없고 하고 싶지만, 워낙 비효율적이라 해당 모션만 그렇게 만들어서 적용시킬듯한 느낌이다. 만약 해당모션만 되지않는다면 다 갈아엎을지도 모른다...
이외에 다음회차에는 3D 입문 조금과 카메라를 이용한 장난, 씬 전환 그리고 사운드들을 조금 넣어보고 싶다. 여러개의 씬들을 넣어서 일단 뭐라도 빌드를 해서 뽑아보는 것이 다음회차까지의 목표이다.

프로젝트 파일

스터디 중에 만들어지는 프로젝트들은 모두 github에 올라올 예정입니다.
https://github.com/Linked-List/UnityStudy

profile
게임개발자가 꿈

0개의 댓글