ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2D 슈팅게임 02. 캐릭터 이동구현
    유니티 프로젝트/2D.SpaceShooter

    타이틀 씬에서 게임 화면 씬으로 넘어가는 것처럼 보이는 효과를

    SetActive를 활용해 UI를 비활성화시켜주며 완성을 시켰습니다.

     

    지난 받아온 Sprite들을 이용하여 Player와 Monster를 만들고 

    Player의 이동구현은 현재 모바일 환경이기에 조이스틱으로 캐릭터를 움직일 예정입니다.

     

    유니티 에셋 스토어에서 받아온 무료 캐릭터의 Idle 이미지를 가져왔습니다.

    이후 중력을 적용시켜줄 수 있는 Rigidbody 2D (3D x)와 Collider 2D (3D x)를 입혀 생명을 불어넣어 주었고

    바닥과 양 벽을 빈 오브젝트에 콜라이더를 추가시켜주어 캐릭터가 떨어지거나,

    필요 이상의 x축으로 나가는 것을 막았습니다.


    Collider에 대해 찾아보던 도 중, 알게 된 사실인데

    Sphere Collider가 연산속도가 가장 빠르다고 합니다.

    Sphere Collider > Capsule Collider > Box Collider 순서라고 합니다.

    따라서 특별한 경우가 아니라면 다음 순서대로 Collider 컴포넌트를 선택하길 권장한다고 합니다.

     

    역시 모든 일에는 그냥이 없는 것 같습니다.

    사소한 부분으로 지나갈 수 있는 점도 다 이유가 있으니, 아는 것이 힘인 것 같습니다.


    단순 이해 돕기용 동영상

    이제 Player가 완성되었으니, 조이스틱으로 Player의 이동을 구현해 보겠습니다.

     

    우선 화면 터치에 반응을 해주기 위해 EventSystems 네임스페이스를 선언해 주었고,

    IPointerDownHandler : 마우스로 터치를 했을 때

    IPointerUpHandler : 마우스의 터치가 떼어졌을 때

    IDragHandler : 마우스로 드래그 중일 때

    로 총 3가지 이벤트 함수를 사용하였습니다.

    ( 이 외에도 많은 이벤트 시스템의 인터페이스 종류가 존재하기에, 공부를 하여 다양한 연출을 연습해 보아야겠습니다. )

     

    transform.position = new Vector2(eventData.position.x, transform.position.y)를 드래그 함수에 작성하여 

    transform (조이스틱)의 포지션을 eventData.position.x, transform.position.y (드래그 중인 마우스)로 

    따라가게 해 주었습니다.

    x축은 eventData의 포지션을 따라지만

    y축은 이동이 필요 없기에, 현재 transform(조이스틱)의 0의 좌표로 고정시켜 주었습니다.

     

    OnPointerUp 함수는 마우스가 떼 진 상황의 이벤트이기에,

    transform (조이스틱)의 위치를 Vector2.zero로 만들어 new vector2(0,0)와도 같이 만들어 주어

    초기화를 시켜줬습니다.

     

    단순히 이렇게만 해 놓으니, x축이 필요 이상으로 벗어나는 게 보기 싫었고, 필요치 않다고 판단했습니다.

     

    조이스틱이 움직이는 OnDrag 이벤트 함수에서

    transform.localPosition.x 축의 최소 거리와 최대 거리를 제한해 두었습니다.

    -180과 180의 값은 조이스틱이 움직일 수 있는 최소거리와 최대 거리를 씬 창에서 계산한 것입니다.

     

    여기선 모두 localPosition로 코드를 작성했는데.

     

     Position과 localPosition의 차이점을 보자면

    position : 오브젝트의 위치를 항상 월드의 원점을 기준으로 월드 공간상에 선언된다.

     

    localPosition : 부모의 위치 기준으로 설정된다.

    (부모가 없을 경우 position == localPosition과 동일.)

     

    현재 조이스틱은 조이스틱 UI항목들은 패드 안에 모두 담겨 있기에

     

    참고

    localPositon을 사용하였습니다. 추 후 차이점이나 문제점이 생긴다면 수정 및 문제점을 업로드하겠습니다.

     

    이후 public GameObject를 사용해 player를 인스펙터 창에서 손쉽게 적용을 할 수 있게 해 주었고

    player를 이동시키기 위해 rigidBody2D와 이동 스피드를 적용하기 위해 moveSpeed를 적용시켜 주었습니다.

     

    //

    - 추가 설명 부분입니다 -

    public으로 받아온 player의 Rigidbody2D를 받아오는 코드입니다.

    Rigidbody2D를 받아오는 부분을 체크를 못해서 추가 작성합니다.

    //

     

    이동 함수 구현은 코 루틴 함수로 사용했습니다.

    제가 듣기론 다른 개발자들이 Update문을 최소화하려고 한다고 들었었고,

    더욱 pc게임보다 모바일 게임은 Update문 보다 코 루틴 함수로 하는 것이 좋다고 들었습니다.

     

    얕게 살펴본 지식으로는.

    매 프레임에서 처리되는 Update 함수.

    함수 처리 중단에 중단(대기)이 가능한 Corutine함수.

     

    매 프레임마다 반드시 발생하는 모든 오브젝트들이 Up date Call 때문에 렉이 발생하는 경우가 많기에, 매 프레임 처리가 꼭 되어야 하는 부분이 아니라면 Corutine을 사용하는 것이 빠르다고 합니다.

     

    그리 하여 Update가 아닌 코 루틴으로 구현을 해 보았습니다.

    (이번 프로젝트에선 Update를 쓰지 않을 생각입니다.)

    player의 움직임을 담당할 Move 코 루틴 함수입니다.

    player의 좌우 이동은 Sprite Renderer의 Flip x의 (체크 / 언체크)를 이용해 변경해 주었고

    if(transform.localPosition.x < 0)의 x가 0보다 작은 범위라면 flip.x = false(언체크)

    if(transform.localPosition.x < 0)의 x가 0보다 큰  범위라면 flip.x = true(체 크)

    로 변경해 주었습니다.

     

     playerRigid.velocity = new Vector2(

    x 축은 moveSpeed

    y 축은 현재 rigidbody의 velocity.y축 그대로

    )

    로 이동 구현을 해 주었습니다.

     

    이후 이 코 루틴 함수를 터치가 될 시 실행 되게 해 주었고

    터치가 해제될 시 (떼어졌을 시 ) 에는 코 루틴 함수 ("Move")를 종료시켰으며

    즉시 멈추게 하기 위해 velocity의 속도는 vector2.zero로 new vector(0,0)과 같은 상태로 만들어 주었습니다.

    Sprite 14 - 23번을 Walk 애니메이션으로 만들어 주었고
    전체 코드 1
    전체 코드 2

    Animator 컴포넌트와 그림자 GameObject를 받아와 실행해 주었습니다.

     

    그림자인 shadow의 포지션은 shadow.transform.position = new Vector2(player.transform.position.x, -2.71f)

    로 player의 x축은 맞추고 y축은 -2.7f 된 위치에 항상 나타내어지게 하였습니다.

     

     

    Unity 너란녀석... 알면 알 수록 재밌구나 후후후

    댓글

김효겸 / Tel. 010-7735-0580 / E-mail. dollzzang2@hanmail.net