ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CCI - 05 - 펫!!
    팀업 프로젝트/C.C.I

    안녕하세요.

     

    이번엔 플레이어를 따라다니는 펫을 알아보겠습니다.

     

    나름 예쁘게 찍어주고 싶어서 여러 장 찍어 봤는데

     

    음.. 뭔가 어색함이 연출되는 느낌을 지울 수가 없었습니다..

     

    유니티 에셋 스토어에서 무료로 받아온 Toon Fox입니다.

     

    원래는 날아다니는 펫을 데리고 다니면서 

     

    적들을 공격하거나 플레이어를 도와주는 역할군으로 나누려고 했었는데,

     

     

    첫 번째로, 저희가 회의를 거치면서 전투 씬이 없는 것이 좋을 것 같다는 의견이 나왔었습니다.

     

    두 번째로, 도난당한 고양이를 구하는 Run 게임으로 그에 맞는 이미지를 구하고자

    유니티 에셋 스토어를 찾던 중 괜찮은 에셋이 있어서 가져오게 되었습니다!

     

    세 번째로, 귀엽습니다.

     

    네 우선 바로 코드로 가겠습니다.

     

    FoxFSM이라는 스크립트를 생성해 주었습니다.

     

    유한 상태 머신 Finite State Machine

     

    을 따와 이름을 지었습니다 ㅎㅎ

     


    enum FoxState (열거형)으로 선언해 주어

    관리를 쉽게 해 주었으며

     

    FoxState를 제어하기 위해 foxState라는 변수를 선언해 주었습니다.

     

    foxSpeed : 펫의 스피드입니다.

     

    idelDis : idle로 상태가 전환될 거리입니다.

     

    moveDis : Move로 상태가 전환될 거리입니다.

     

    notFindDis : 플레이어를 못 찾았을 때

    플레이어 위치로 이동시키기 위한 변수입니다.

     

    foxNav : 펫에 입혀줄 NavMeshAgent를 담아줄 변수입니다.

    foxAni : 펫이 실행할 애니메이션이 담긴 Animastor입니다.

    playter : 플레이어입니다.

    (플레이어의 위치로부터 펫의 위치를 측정하기 위해 플레이어를 받아올 변수입니다.)

     

    먼저 Start함수입니다.

     

    각 변수에 필요한 컴포넌트 (NavMeshAgent / Animator)를 받아와 주었으며

     

    player변수에게 GameObject 중 "Player"를 Find로 찾아 transform(위치)를 받아와 주었습니다.

     

    또한 인스펙터 창에서 지정한 foxSpeed의 값을 펫이 가지고 있는 네비의 스피드에 대입시켜 주었으며,

     

    초기 상태 foxState는 FoxState.Idle의 상태로 Idle 상태를 갖고 시작하게 됩니다.

     

    이 상태 값들은 Update함수에서 switch로 foxState의 값에 따라 간단히 실행이 될 수 있게 하였으며

     

    각 상태시 실행될 코드부터 살펴보겠습니다.

     

    가장 먼저 Idle 상태입니다.

     

    각 거리를 재기 위해 Distance의 함수를 사용했으며

     

    transform(펫)의 위치와 플레이어의 거리를 계산해 moveDis 범위 안에 있다면

     

    Idle을 true로 바꿔주어 Idle애니메이션의 향하는 트랜지션의 조건들을 맞춰 주었으며

     

    만일 그 거리가 moveDis의 범위보다 크다면

     

    foxState의 상태는 FoxState.Move로 전환되게 해 주었습니다.

    펫의 상태가 Move일 시 실행될 코드입니다.

     

    우선 몇 가지 문제가 있지만,,

     

    초기에 작성한 코드를 먼저 보시겠습니다.

     


    우선 첫 번째로 이번에도 거리를 구하는 데에 Distance를 썼습니다.

    (magnitude도 써보고 sqrMagnitude도 다 써봤는데, 전 왜인지 Distance가 더 변한 것 같습니다....)

     

    transform(펫)과 플레이어의 위치를 계산해서 moveDis의 범위 밖이라면

     

    펫은 플레이어를 따라가게 해 두었습니다.

     

    먼저 LooAt으로 펫의 회전을 player를 보게 해 두었으며

     

    각 각 트랜지션의 조건에 맞는 파라미터 값 불 변수를 변경해 주었습니다.

     

    이후 미끄러지는 현상과 다른 애니메이션 진행 중 움직이게 되어

     

    미끄러 지는 현상을 방지하고자

     

    isStopped = true / 이동을 멈출 거냐? = 네

     

    ResetPath(목적지 초기화)

     

    를 해 준 뒤 SetDestination으로 목적지를 player로 지정해 주었습니다.

     

     

    두 번째 조건문인 if문에서는

     

    펫이 플레이어를 향해 이동을 하다가 moveDis안에 들어왔을 시

     

    "Move"를 false로 해서 애니메이션을 멈춰 주고

     

    "Idle"을 true로 변경하여 대기 애니메이션을 실행하게 해 줬습니다.

     

     

    파란색 WireSphere가 moveDis이며

     

    씬 상에서 직접 확인하며 체크하기 위해

     

    OnDrawGizmos를 사용하였습니다.

     

    인자는 중점(펫) , 범위입니다.

     


    동작은 잘 되었지만, 

     

    계속 테스트를 해보던 중 문제가 생겼습니다.

     

    우선 두 가지 문제가 생겼었는데

     

    (1)

    플레이어가 낙하 시 펫의 내비게이션이 디딜 곳을 인지하지 못해 오류가 발생하였습니다.

     

    (2)

    설명드리기가 애매해서 그림으로 표시를 해 보았습니다.

     

    내비게이션의 Bake가 된 곳을 제외하고 경로가 없는 곳을 플레이어가 점프를 해서

     

    지나가게 되면 펫이 완전히 넘어오지 못하고

     

    왼쪽 맵 끝의 경로와 오른쪽 플레이어의 위치로 번갈아 가며 위치하는 문제가 있었습니다.

    (오류로 판별되진 않았지만, 원하던 그림은 아니었고 더군다나 시각적으로 보이기에 큰 문제였습니다.)

     

    우선 (2) 번을 해결하기 위해.. 베이크를 일반 도형을 생성해 놔 구워 놓고 비활성화해놓을까..?

     

    를 생각해 봤었는데

     

    나중에 문제가 생길 수도 있는 부분이었고, 더군다나 이런 눈 가리고 아웅 의 프로그래밍 방식은

     

    제가 원하는 부분이 아니였습니다.

     

    생각보다 많은 시도들이 있었는데,, 일단 보다 간결하게 하고자 한 게

     

    펫의 NavMeshAgent를 껐다 켜주는 코드였습니다.

     

    그리 하여 펫의 상태가 Move 일 시에 실행되는 코드에 if문을 추가시켜

     

    펫이 플레이어로부터의 위치가 notFindDis 보다 클 경우엔

     

    enabled를 false로 꺼준 상태에서 펫의 위치를 플레이어의 위치를 옮겨 주며

    다시 enable를 이용해 NavMeshAgent를 true로 활성화시켜 주었습니다.

     

    이후 플레이어의 위치에 있는 펫은 Idle 상태로 돌아가게 해 주었습니다.

     


    근데 (1) 번 같은 문제는 해결이 상당히 어려웠습니다.

    (어려웠다기보다 방법을 못 찾았다..? 가 맞는 것 같습니다.)

     

    1번 문제가 플레이어가 높은 곳에서 낙하 시 혹은

     

    장애물에서 떨어질 시 펫이 player의 위치로 와서 NavMeshAgent가 활성화되면 

     

    나는 오류였는데, 이 펫의 NavMeshAgent을 원하는 시점에 껐다 켰다 하는 게 불가능하였기에 발생한 문제였습니다.

     

     

    플레이어를 점프 중 이거나 그라운드가 아닐 시는 실행 안 되는 코드를 구현했지만, 

     

    플레이어가 점프를 계속하면서 가거나 한다면 펫이 자연스럽게 따라오지 못하는 어색합이 연출되었습니다.

     

     

    흠.. 아쉽지만 아직 NavMeshAgent를 갖고 있으며 문제를 해결한 방법은 찾지 못했습니다.

    (하지만 포기는 하지 않았습니다.)

     

    결국 아쉽지만 네비의 항목은 지우고 움직임을 TransLate로 움직이게 해 두었으며

     

    방향 * 펫 스피드 * Time.deltaTime을 곱해 주어 프레임간의 격차를 없애주는 코드가 완성되었습니다.

     

     

    00 : 25초

    이것으로 플레이어를 따라다니는 펫을 살펴보았습니다.

     

    감사합니다.

     

    '팀업 프로젝트 > C.C.I' 카테고리의 다른 글

    CCI - 07 - 적 & 펫 스킬 적용  (0) 2022.05.13
    CCI - 06 - 펫 스킬 (쿨타임)  (0) 2022.05.13
    CCI - 04 - Hp  (0) 2022.05.13
    CCI - 03 - 버튼 & Mini Map (UI)  (0) 2022.05.12
    CCI - 02 - 플레이어 이동 구현  (0) 2022.05.12

    댓글

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