본문 바로가기

프로그래밍/Unity

2D 게임을 위한 몇가지

unity3d 홈에서는 여러 튜토리얼을 제공하는데, 2D Platformer 튜토리얼도 제공한다.

2D 형태의 플랫포머 장르를 위한 기본적인 내용을 다루고 있다.

물론, 실제로 동작은 3D 이지만 내부적인 제한을 두어 2D처럼 보이도록 하고 있다.

카메라 프로젝션을 Orthographic으로 설정하면, 더욱 2D 느낌이 나타난다.

   

해당 튜토리얼 내용 중 알아두어야 할 몇 가지에 대해서만 기술한다.

   

1. 바닥 설치

바닥은 여러 가지 타일로 각각 collider를 포함하고 있다.

별도의 강체 적용이 되어 있지 않으므로, 특별한 설정이 필요치 않다.

   

2. 움직임

튜토리얼에는 두가지 형태의 캐릭터 컨트롤을 보여준다.

CharacterController 를 사용하는 캐릭터와 Rigidbody+Collider 를 사용하는 우주선.

   

3. 회전의 고정

2D라곤 하지만 실제론 3D 세계이므로, 각종 회전, 물리적용 등에 의해 화면 앞,뒤로 오브젝트가 움직여 버리는 일이 생긴다. 즉, Z축이 개입하게 되어 캐릭터 충돌이나 인식이 불가능해져 버리는 상황이 나타난다.

매 업데이트( void FixedUpdate() ) 에서 z축을 고정해버려도 되나 튜토리얼은 Component를 사용하고 있다.

   

일단 Rigidbody가 포함된 객체는 아래와 같이 rigidbody의 Constraints 값을 조절하면 된다.

   

   

   

튜토리얼의 캐릭터 같이 rigidbody가 포함되지 않은 객체는 별도의 component를 사용한다.

Component - Physics - Configurable Joint

   

아래처럼 설정하면, Z축으로 이동과 X,Y축 회전은 처리되지 않는다.

   

   

   

4. 캐릭터

CharacterController 는 내부적으로 Collider와 기본적인 충돌 루틴이 포함되어 있다.

하지만, 물리적인 요소가 없으므로 직접 이동과 중력 등을 적용해주어야 한다.

   

이동은 Move 메쏘드를 사용하며, 리턴값으로 CollisionFlags 가 전달된다.

function Move( motion:Vector3):CollisionFlags

   

다른 오브젝트의 Collider와 충돌 시 OnControllerColliderHit 메쏘드가 호출된다.

(Move로 이동하는 경우에만 호출되며, 다른 오브젝트는 Rigidbody를 포함해야 한다. rigidbody가 없으면 그냥 벽 or 바닥 처럼 인식되어 별도의 충돌 루틴은 호출되지 않음)

   

function OnControllerColliderHit(hit:ControllerColliderHit):void

   

레퍼런스에는 아래와 같이 상대방 오브젝트의 rigidbody를 가져와 필요한 처리를 한다.

var body:Rigidbody = hit.collider.attachedRigidbody;

   

튜토리얼에서는 캐릭터가 해당 물체를 밀어 이동이 가능하도록 설정하고 있다.

PlatformerPushBodies 라는 스크립트로 구성되어 있는데, 세부 내용은 아래와 같다.

 

> 충돌검사

void OnControllerColliderHit( ControllerColliderHit hit )

> 충돌한 오브젝트의 rigidbod 얻기

Rigidbody body = hit.collider.attachedRigidbody;

   

> 속도를 추가시키기 위한 방향 설정

Vector3 pushDir = new Vector3( hit.moveDirection.x, 0, hit.moveDirection.z);

   

body .velocity = pushDir * pushPower * Math.Min( controller.GetSpeed(), controller.movement.walkSpeed);

   

   

   

바닥이나 벽은 별도의 충돌 루틴이 없으니 캐릭터 상태에 따른 처리를 해야한다.

일단 isGrounded 로 현재 캐릭터에 바닥에 닿아있는지를 알수 있다.

   

바닥에 닿아 있을때만 점프가 동작하도록 하거나, 바닥에 닿아 있는데, 이전 상태가 점프 였으면 "착지" 메시지를 전송해 에니메이션 처리 스크립트에서 착지에니메이션을 처리 할 수 있도록 한다.

   

   

   

   

5. 우주선

우주선은 CharacterController가 아닌 Rigidbody, collider 조합으로 움직임을 구현한다.

물리처리를 위하여 FixedUpdate에서 계산이 이루어지게 되며, 충돌의 경우 OnCollisionEnter를 사용한다.

   

FixedUpdate에서는 속도의 최대값, 최소값을 지정하고, 주어진 속도를 감소시키기 위한 Drag 계산이 포함되어 있다. 물체의 종류 혹은 움직임에 맞게 속도가 저항값을 조절해 주어야 한다.

   

6. 에니메이션

캐릭터 에니메이션은 점프,낙하,착지,걷기,뛰기로 이루어져 있는데, 걷기, 뛰기는 이동 시 에니메이션이고, 나머지 세개는 점프와 관련이 있다.

   

점프의 경우 점프 메쏘드를 호출하는 메시지가 전달되면,

점프 - Play

낙하 - PlayQueued

   

착지 시

낙하 - Stop

착지 - Play , Blend

   

형태로 실행된다.

   

7. 기즈모

게임화면이 아닌 unity3d의 편집화면에서만 보일 요소를 추가 할 수 있다.

스폰 포인트나 데드존 등 편집의 편리를 위해 자신만의 아이콘을 추가해 표시되도록 하는 기능인데..

   

빈 게임오브젝트를 하나 추가한다.

아이콘으로 사용할 이미지를 프로젝트에 추가.

스크립트 작성.

void OnDrawGizmos() {

Gizmos.DrawIcon( transform.position, "Test.tiff" );

}

   

이러면 빈 오브젝트에 원하는 아이콘이 등록되게 된다.

뭐 혼자 작업할땐 쓸일이 없을 수도.... -_-;;

   

화면영역 - 전체 레벨에서 캐릭터가 움직일 수 있는 영역을 지정하고 있다. 2D이므로 큰 사각박스로 이루어져 있고, 각각 영역은 박스 collider를 동적 생성해 구성한다.