Sputnik(2) - 구르기

JUSTICE_DER·2023년 8월 30일
0

🛰Sputnik (Satellite)

목록 보기
5/9

1. Roll

이전 Satellite 프로젝트에선 점프를 넣었었는데,
Jump 대신 다른 것을 넣는다.
https://velog.io/@sputnikel0221/Satelite-1

램넌트2처럼 점프 대신에 구르기를 넣어보려고 한다.

1-1. Asset

https://www.youtube.com/watch?v=j6NfpUzYLmM
위의 사이트에서 구르기 애니메이션을 받았는데,
정상적으로 import 되지 않는다.

구르기 모션이 잘린다

따라서 아래 영상을 보고 해결하려고 한다.
https://www.youtube.com/watch?v=n1CgViSTIBQ
하지만 되지 않았다.

그냥 Import시, SetRange로 직접 프레임을 입력하였다.
해당 Asset에 최대로 입력할 수 있는 프레임이 38이었다.
(초과하면 아예 만들어지지조차 않는다)

1-2. Roll 방향

구르기를 하긴 하는데, 구르기 자체가 방향성이 없는
단일 Animation이라서
원하는 방향으로 구르게 하려는 계획은 차질이 있어 보인다.

하지만 하나의 Animation을 여러 방향으로 동작하게 할 수는 없을까?

A. RelativeRotation 설정

흠.. 일단 생각한 방식은
스페이스 바를 눌러서 구를 때에만
캐릭터의 방향을 입력의 direction을 보도록 회전하고,
구르고 나서는 원래의 direction을 보도록 하려고 한다.

회전하고 - 회전한 채로 앞으로 구르고 - 원래대로 돌아온다.
그러면 해당 방향으로 구르는 형식이 된다.

bUseControllerRotationYaw를 잠시 false로 설정하여 동작시킨다

우선 그렇게 구현하기 위해
AnimInstance에서 변수값들을 설정하고, CPP에서 가져와 사용한다.

AnimInstance에 몽타주 Ref를 직접 받고 그대로 실행하는 함수를 제작했고,
PlayerCharacter에서는 입력에 따라 Roll함수를 실행하는데
AnimInstance의 몽타주실행함수를 실행하도록 시켰다.

흠.. 그렇다면 이제 캐릭터의 방향을 돌리는 작업을 해야할 것이다.

AnimGraph에서 설정되는
Movement Angle값을 가져와서 구르는 방향으로 보게 하고 싶다.

이렇게 설정해봤다. 안된다.
마지막 0이 아닌 입력의 방향으로 플레이어가 보게 하고,
해당 방향으로 몽타주를 수행하도록 하고 싶은데..

불편한 점은 해당 값을 print하는데 0도 출력한다는 것이다.
Direction이나 float변수 둘 다 0이 출력된다.

앞으로도 구르게 하고 싶은데,
이게 앞 구르기의 0인지, 옆으로 이동 사이에 나타나는 0인지 어떻게 구별시킬 수 있을까.
해당 값의 Length인 Speed로는 구별하지 못한다.

AnimInstance에 PlayerDirection변수를 추가하고,
해당 변수를 반환하는 함수를 만들었다.

그리고 해당 변수값을 Yaw에 더하면서,
relative rotator로 수정하여 입력의 Direction만큼 회전하여 동작한다.

이 때, bUseControllerRotationYaw를 false로 해야만한다.
그래야 잠시 PlayerController와 Anim의 방향을 다르게 설정할 수 있기 때문이다.

B. bUseControllerRotationYaw

이제 구르고 나면, bUseControllerRotationYaw를 true로 해야했는데,
맨 마지막에 주석의 위치에 작성하면,
아예 bUseControllerRotationYaw를 false하지 않은 상태가 되어버린다.

왜지?

일단 해결할 수 있는 방법은 true false 설정을 같은 공간에 하지 않고,
MontageEnd delegate나, Timer를 사용하는 방법이 있을 것 같다.

다만, 정면을 보고 우측으로 굴러도,
해당 설정에 의해 다시 정면을 본다.
나는 우측으로 구르면 그대로 우측을 보게 하고 싶었다.

MontageEnd Delegate를 사용하였더니 정상적으로
원래의 상태로 돌아오게 된다.

C. Camera Lerp

카메라를 해당 방향으로 회전하게 하고 싶다. Lerp하게.

Roll 내부에 위처럼 작성했다.
PlayerController를 많이 사용할 것 같아서, 변수로 만들어두고 사용했는데,
분명 Controller가 몸에 Possess되어서 이동을 하는데,
구르기만 하면 위의 PlayerController가 없는 상태가 된다.

다른 Shoot 등의 함수는 잘 동작하는데 일단 왜인지 모르겠다.
PlayerController는 그냥 그때그때 Cast해야하는 존재인가..?

저 주석을 풀면, 원하는 대로 바뀐다.

이제 원래 방향으로 Lerp하게 카메라를 바뀌게 하고 싶다..

이 방법을 사용해본다.
https://www.youtube.com/watch?app=desktop&v=y9dZv1KBoaQ

위처럼 그래프를 작성했는데, 동작하지 않는다.

Space를 누르면 Roll을 하고,
Camera는 Lerp하게 움직여야하는데 동작하지 않았다.

아마 CPP에서 몽타주가 끝나고 bUse~ 설정을 true로 한 부분이 문제로 보여서
해당 부분을 해제했는데도 되지 않는다.
Relative나 World나 모두 동작하지 않았다.

CPP로 왔다.

Lerp를 사용하는데, 역시 Lerp는 왜 쓰는건지 이해가 안될 정도로
부자연스럽다.

하지만 어짜피 bUseControllerRotationYaw=true가 되며,
Controller가 보는 방향을 보게 된다.

CPP에서 TimeLine을 사용하기 굉장히 까다롭고,
추가로 BP에서는 MontageEnd에 맞게 작업하기가 까다로워서..
일단 스킵한다.

정 못하겠으면 정면을 보고 이동방향으로 피하는 애니메이션
구해서 방향에 따라 적용하는 방법이 있을 것이다 ..
https://ellder4mk.tistory.com/645

2. Roll 추가기능

  • 공격 안되게
  • 이동 안되게
  • 구르는 중에 구르기 안되게

위의 3개를 구현하기 위해서
단순히 bool을 생성하는게 가장 효율적일 것으로 보인다.

구현해본다.

구르기 시에 바로 true설정을 하고,
구르기 Montage가 끝나면 false 선언한다.

조준도 안되게 바꾼다.

A. 오류

그런데 구르면서 Aiming 키를 꾹 누르고 있으니까
구르고 나서 Aiming키를 누르지 않아도 Aiming이 된다.

왜????
아마 Montage가 끝나는 타이밍 때문으로 보이는데,,
Timer를 넣어야하나?

안된다. 카메라도 계속 줌이 된다.
어떻게 return을 뚫고 들어가는거지??

Aiming의 기능을 시작하는 부분에 Warning로그를 두었다.
그리고 Aiming이 Block되는 부분에 Error로그를 두었다.

오류가 발생한 시점을 찍었고,
분명 Aiming의 기능이 실행되지 않았음에도, 공격이 되는 모습이다.

Shoot에 위의 로그를 두었다.

오류가 발생한 시점이고,
어떤 연유로 bIsAiming이 true가 되었을까 모르겠는데,
true가 되었다.

여기가 문제로 보인다.
Roll중에는 마우스를 꾹 누르고 있다가, Roll 이후에 마우스를 떼고,
그렇다면 마우스를 떼는 시점에 rolling중이 아니고 정상적으로 동작하고,
ChangeAiming을 통해 그냥 bool값이 참이면 거짓, 거짓이면 참으로 바뀐다.

if 조건문을 추가함으로써 해결되었다.

B. Roll시에 이동 막기

이제 남은건 이동하는 것을 막아야하는데,,,
Timer를 활용해본다.

BlockRolling이라는 bool 변수를 하나 더 만들고,
0.2초 뒤에 실행되는 함수에 의해 해당 값이 false가 되어야지만
Rolling을 할 수 있게 하였다.

bIsRolling과 bBlockRolling 2개로 나눈 이유는,
구르고 난 다음에 바로 공격은 해야하고, 구르기는 막아야하는
타이밍의 차이 때문이다. 그 차이가 0.2초로 둔 것이다.
업로드중..

일단 검색해봤다.

profile
Time Waits for No One

0개의 댓글