TPS 캐릭터 만들기 - 제자리 회전 분석
*언리얼엔진5를 배우는 과정을 기록하는 포스팅입니다.
아직 미숙하고 처음 글을 작성하는 만큼 미흡한 부분이 많은데 댓글로 피드백 부탁드립니다! 감사합니다.
.
*현재 강의자료를 토대로 생성하는 캐릭터는 이후 TPS 슈팅 게임에 적용할 캐릭터의 프로토 타입으로 만들고있습니다.
강의를 기반으로 약간의 수치 및 로직 수정이 있을 수 있습니다.
강의자료:
https://www.youtube.com/watch?v=-yKtw-zKOU8
메모)
먼저 변경점을 살펴보자면,
AnimGraph의 Idle 상태에서 바로 출력하는 것이 아닌
Idle & TurnInPlace SM 에서 Rotate Root Bone 을 거쳐 출력한다.
먼저, Rotate Root Bone을 살펴보기 위해 해당 노드를 제외하고 바로 Idle And TurnInPlace를 출력하면,
다음과 같이 캐릭터의 회전도 같이 들어가는 모습을 보이는데,
https://www.youtube.com/watch?v=Kappe0LXZok (Rotate Root Bone 설명 및 Turn In Place C++버전)
를 통해서
Turn 애니메이션이 실행되면 (이 때, Turn 애니메이션은
다음과 같이 RootMotion에 대한 설정이 되어있는데,
이 때 설정된 Curve값에 맞게 스켈레톤 자체를 회전시켜 주는 기능을 하는 것 같다.
그로인해 거치지 않았을 때에는 그저 이동되는대로 똑같이 회전이 적용되는데,
Rotation Root Bone 을 거쳤을 때에는 해당 방향에 맞추어 본 자체를 회전해주는 것 같다.
Yaw 옵션 외에도 Picth의 옵션도 핀으로 가능하기에, 원하는대로 조절하면 좋을 것 같다.
(활 조종할때 등..에 사용될 수 있을 것 같다. , 하지만 이는 다른 기능이 있으므로 후에 살펴볼 예정이다.)
다음으로 Idle And TurnInPlace를 살펴보면
다음과 같이 YawOffset 값의 절댓값이 45보다 커지면 TurnInPlace로 넘어가도록 하였고,
Turn In Place 를 보면 Yaw Offset 의 부호에 따라 회전을 다르게 하는데,
이제 Yaw Offset의 값을 구하는 곳을 살펴보자면,
(한 화면으로 볼 수 있도록 위치를 조절한 상태이다.)
먼저 빨간 줄 윗쪽을 보자면,
매 프레임마다, 내 플레이어의 Z축 회전값(Yaw) 과 이전 Yaw값(Yaw Last Tick) 값을 받고,
그 차이를 빼서 Yaw Change Over 값을 갱신한다.
매 Tick Event 마다 Z축을 기준으로 얼마나 회전했는지 계산한 뒤에,
만약 플레이어가 움직임이 있다면 값을 초기화 해주고,
움직임이 없다면 프레임마다 변화된 Yaw값을 관리하는 Yaw change Over과 현재의 Yaw Offset을 더하여 [-180, 180] 내부의 값이 되도록 조정 한 뒤 Yaw Offset에 갱신해준다.
이렇게 한 뒤 Yaw Offset의 값을 로그에 출력해보면 마우스 회전에 따라 값이 조정되는 것을 확인 할 수 있다.
다음으로 빨간색 선 아래쪽을 살펴보기 전,
Get Curve Value 라는 속성이 있을텐데,
먼저 MM_Rifle_TurnLeft_90 애니메이션을 살펴보면,
DistanceCurve 와 IsTurn 을 추가한 걸 볼 수 있는데,
여기서 "IsTurn은 Metadata 이고, DistanceCurve는 Curve이다.
(처음엔 IsTurn이 Curve인줄알고 그냥 진행했는데, 이러면 후에 회전을 하지 않는 현상이 발생한다. 이는 뒤에 설명)
DistanceCurve를 보면, (0.0, -45.0) , (0.5, 0.0) 의 커브값을 가지는데,
이는 0.0초에 -45의 값, 0.5초에 0.0의 값을 의미하는데
이때 -45는 캐릭터가 회전하길 원하는 각도이다. (Yaw Offset의 값)
75도에 회전하길 원하면 -75를, 90도마다 회전하길 바라면 -90.0을 넣어주면 된다.
다시 살펴보자면,
먼저 Get Curve Value를 통해 IsTurn을 받아오면,
해당 애니메이션이 재생중(돌고 있다면)이면 1을, 아니면 0을 반환한다.
만약 플레이어가 돌기 시작한다면,
처음 한번으로 Curve Value의 값을 "DistanceCurve" Curve 값으로 바꾸는데,
애니메이션이 시작한 0.0s 당시엔 설정한 -45.0의 값으로 초기화될 것이다. (업데이트 당시에 따라 다르지만 유사한 수치)
이 때, 회전하는 애니메이션이 재생되면서 DistanceCurve의 데이터 값의 차이를 매 프레임마다 YawOffset에 수치를 가하면서, Yaw Offset의 값이 점점 0에 가까워질 것이다.
만약 플레이어가 회전을 70도를 했을 때라면, 45도만큼 회전이 들어가며 IsTurn? 과정의 노드를 통해서 YawOffset값이 -45가 된 35라는 값이 될거고 여기서 10도를 추가로 회전해 45도가 되면 다시 회전이 들어가는 방식으로 진행될 것이다.
실행 이미지)
이 결과 최종적으로 45도마다 회전이 들어가는 모습을 볼 수 있으며,
각도에 대한 조정이라던가 좀 더 유기적이게 각도를 여러개를 설정하던 남은 각도에 대한 처리를 하던 진행을 하면 조금 더 깔끔한 애니메이션을 만들 수 있을 것 같다.