예지의 테크 로그포스 (Yeji's Tech Log Force)
Unity로 게임 개발하기 #2 본문
기존Prefab으로 new Prefab만들기
바닥(ground)prefab을 활용해 벽(wall)prefab을 만든다고 해보자.
1. 바닥 prefab을 hierachy에 올리기
2. Hierachy에 올린 prefab을 우클릭->Prefab->Unpack completely(연결을 끊어준다.)
그럼 기존 바닥prefab과는 구분된 Object가 된다.
3. 이 Object의 이름을 벽(wall)으로 바꿔주고,
Project부분에 새로이 만든 Wall폴더에 넣으면 새로운 Prefab이 완성된다.
태그(Tag) 사용하기
Inspector에서 Tag라는 기능을 확인해볼 수 있다. Tag란 말 그대로 이름표를 의미한다.
이를 통해서 개별적인 Prefab/Object들을 구분 지을 수 있다.
(가령, 벽과 바닥을 각각 wall, ground로 tag하여 구분가능)
태그를 만들어보자.
1. AddTag를 클릭
2. + 를 눌러 Tag를 Add, Save’
3. 다시 돌아와보면 ground, wall 등 추가한 Tag가 보일 것이다. 클릭하여 원하는 Tag로 달아주자.
Jump 하기
슈퍼마리오, 메이플스토리와 같은 플랫포머게임(platform game)에서 '점프'는 매우 중요한 요소이다.
점프 입력을 ‘위쪽 방향키’로 받는다고 하면 아래와 같이 Jump에 대한Script를 작성할 수 있다.
한편, GetKey와 GetKeyDown의 차이는 뭘까?
- GetKey: key입력 시 꾹~ 누르면 계속해서 true를 반환한다
- GetKeyDown: 꾹~ 누르고 있어도 한번만 true를 반한한다.
즉, 키보드 입력을 계속해서 반영하고자 할 때는 GetKey,
꾹 눌러도 한 번만 체킹하고 싶다면 GetKeyDown을 사용하면 된다.
아래와 같이 위쪽 방향키를 눌렀을 때 위쪽으로 힘을 주는 코드를 작성해보자.
자! 이제 저장해서 play시키면 놀랍게도 캐릭터가 점프를 하지 않는다.
Jump Debuging
왜 점프를 하도록 코드를 짰는데 점프를 못할까??????
차근차근 분석을 해보자.
1. 점프 방향키 입력을 못받는 것은 아닐까? → 로그를 찍어 확인해보자.
방향키에 관한 코드 내부에 Debug.log(“Enter”)를 추가해준다. 이후 Play!
방향키를 눌렀을 때 Enter로그가 잘 출력되는 것으로 보아, 방향이 입력까지는 인식을 한다는 점을 알아냈다.
2. 그렇다면 제대로 작동하지 못하고 있는 부분은 Debug.log(“Enter”)의 아랫줄,
이 부분이라는 것을 알 수 있다.
이 코드에서는 plyer프리팹의 Rigidbody를 스크립트상에서rigid로 사용하고 있다.
사실 필자는 player가 좌우로 움직이는 때에도 해당프리팹의 Rigidbody를 아래와 같이 사용한 적이 있다.
한 prefab의 Rigidbody를 rigid란 변수를 통해 공유하며 조절해주고 있다.
그런데 위의 코드를 자세히 보면, 처음 direction은 (x,y)가 (0,0)이다.
이후 방향키 입력에 따라 Vector.left에 moveSpeed를 곱해주느냐, right에 곱해주느냐로 나뉘어 rigid의 속도를 조절한다.
그런데 Vector2.left는 (-1,0)이다.
그러므로 어떤 moveSpeed를 곱해도 y값은 0일 것이다.
Jump부분에서 아무리 rigid에 위쪽(y축 양수방향)으로 힘을 주어도 Update()부분에서 y축은 0으로 고정시킨다.
따라서 player가 점프할 수 없는 것이다.
3. 그렇다면 이 문제를 어떻게 해결할까?
Update부분에서 y를 계속해서 0으로 고정시키고 있다.
따라서 0으로 고정시키지 않고, Rigidbody의 velocity의 y값으로 설정하도록 하면
y값이 0이 아닌 값으로 변화할 수 있을 것이다.
그래서 좌우 움직임을 담당하는 스크립트에 아래와 같이 코드를 추가해주었다.
점프를 자연스럽게
위와 같은 방식으로 점프 구현에 성공은 했다만..
공중에서 점프를 계~~속 할 수 있다. 날아갈 수도 있다.
이건 일반적이지 좀 않으니까~~~! 공중에 떠있으면 점프X, 바닥에 있으면 점프O 되게 해볼 것이다.
1. 발바닥쪽에 Collider를 하나 더 만들어서 바닥과 충돌여부 감지
Box Collider를 발 밑쪽에 작게 하나 더 만들어 주었다.
또, 이 Collider를 Trigger로 설정하여 ‘오브젝트를 뚫고 지나갈 수 있지만 충돌은 감지하는 상태’로 만들어주었다.
이제 스크립트에서는 OnTriggerEnter2D를 사용하여 충돌을 감지할 수 있다.
2. 바닥과의 충돌만 감지하기
이제 충돌을 감지할 수 있게 되었는데, 어떻게 ‘바닥’과의 충돌만을 감지할까?
게임을 하다보면 적과 충돌할수도, 벽과 충돌할수도 있다.
이를 구분하는 방법은 글 앞쪽에서 언급한 ‘Tag’의 사용이다.
충돌이 발생하면 매개변수로 collision이 들어온다. 이 때 collision의 tag가 ground(바닥의 tag)라면 표시를 해주면 된다. 표시는 bool타입의 isGrounded 변수를 만들어서 체크해주었다.
3. isGrounded==true일때만 jump
isGrounded가 true라면 바닥과 충돌이 일어난 것이라고 표시했다.
(player가 바닥에 있다는 의미)
따라서 점프부분의 Update에 아래와 같은 코드를 추가해주었다.
또, 위의 코드를 처리하면 점프를 한 셈이 되므로 isGrounded를 false로 바꿔주어야 한다.
이 과정을 마치면 player가 바닥에 있을 때, 1회만 점프 가능하도록 할 수 있다.
적 만들기
우선 적의 역할을 하는 prefab을 Scene에 하나 던져주자.
무서운 괴물이 만들어졌다!!! 그런데 사실 얘는 지금은 아무런 공격도 움직임도 없다.
AI를 추가하여 진짜 무섭게 움직이는 적으로 만들어보겠다. → 적이 벽에 부딪히면 반대로 움직이도록.
1. 적이 부딪힐 벽 생성
2. 적 Prefab에 AI역할을 할 Scripts생성
- 벽과의 충돌은 OnCollisionEnter2D를 이용하여 감지.
- isLeft라는 bool타입 변수를 통해 적이 벽에 부딪히면 반대로 가도록 설정.
- 적이 벽에 부딪혔을 때 반대편으로 이동하는데,
몸통도 반대로 돌려주도록 SpriteRenderer(이미지를 보여주는 컴포넌트)사용.
flipX를 true/false로 설정하여 X방향 좌우 반전이 가능하다.
enemy와 player의 충돌
마리오 게임을 보면 player와 enemy가 부딪혔을 때 일어나는 효과들이 있다.
땅 아래로 떨어진다거나, 이동이 불가해지는 등 이다.
이 효과를 player Prefab에 스크립트를 달아서 추가해보겠다.
- 데미지를 입었을 때(적과의 충돌)의 효과
적과 충돌이 일어나면 위의 함수를 호출한다.
이 함수에서는 collider들의 inspector체크가 풀리도록 하였다. 이는 충돌감지를 더 이상 받지 않겠다는 것을 의미한다. 그럼 player는 땅 아래로 떨어지게 될 것이다.
또, render설정을 통해 기존 색깔은(1,1,1)로 동일하게 유지하되, 투명도만 0.5f로 바꿔주었다.
- 충돌감지
적에게 enemy라는 tag를 달아, 충돌 시 OnDamage()를 호출해주도록 하였다.
'[Unity] Projects & Study > Simple Platformer Game' 카테고리의 다른 글
Unity로 게임 개발하기 #4 (0) | 2021.08.21 |
---|---|
Unity로 게임 개발하기 #3 (0) | 2021.08.20 |
Unity로 게임 개발하기 #1 (0) | 2021.08.12 |