
Crosshair In Air Factor공중에 있을 때 확산도를 변하도록 해보자.기본적으로 기존 확산도 계산 함수에서 CrosshairInAirFactor 변수를 더해주면 된다. 그리고 이를 GetCharacterMovement()에 속한 IsFalling() 함수를 통하여 공중 여부를 판별 후, CrosshairInAirFactor의 값을 설정해주면 된다.여기서는 저번에 사용했던 보간 함수를 사용하여 점진적으로 확산이 이루어지도록 하였다. 공중에서는 천천히 넓게 퍼지도록, 지상에서는 빠르게 원상복구 되도록 하였다.

Spreading the Crosshairs이제 크로스헤어의 확산을 적용해보자.크로스헤어는 언리얼에서 HUD 블루프린트 클래스를 통해 적용했었다.따라서 C++에서 선언한 크로스헤어 확산 변수에 접근하기 위해 Getter 함수를 만들어주자. 추가적으로 저번에 Tick 내에 함수를 호출해주는 것을 잊어서 이번에 작성해주었다. 먼저 HUD 블루프린트 클래스에서 Shooter Character에 대해 유효한지 체크를 해주자.우리는 Shooter Character에 있는 getter 함수를 필요로 하므로, 유효여부 체크를 해주는 것이 좋다.이러한 작업은 C++ 내에서 각 포인터 유효여부 체크 작업을 해줬던 것과 동일하다.관련 변수를 먼저 만들어주고 이를 이용해 체크해주자. 이제 HUD 클래스내에서도 확산에 대한 ..

Crosshair Spread Velocity지금은 어떤 움직임에도 크로스헤어가 고정된 상태지만,캐릭터가 움직이거나, 줌 했을 때 등 움직임이 생겼을 때 크로스헤어도 마찬가지로 움직이는 것이 바람직하다.이번엔 이런 크로스헤어의 확산도에 대해 조정해보자. 먼저 관련된 변수들을 선언해주자.기본 확산 배율, 속도에 따른 확산, 공중에 따른 확산, 조준할 때의 확산, 사격 시의 확산 나타낸다. 이후 확산을 계산하는 함수를 작성해주자. 여기서 캐릭터의 걷는 속도에 따른 확산 배율을 계산해보자.걷는 속도는 0~600 사이인데, 이를 배율에 맞게 0~1로 매핑을 해주어야 한다.예를 들어 걷는 속도가 300이면 해당 배율은 0.5가 될 것이다. 여기서 사용하는 함수가 GetMappedRangeValueClamped 이..

Aim Look Sensitivity이번엔 FPS 게임의 필수 항목이라고도 볼 수 있는 감도에 대해서 조절해보자.가까우면 보통 감도가 느려야 맞추기가 수월하니 이를 목표로 조정할 것이다. 처음에 우리는 좌우 화살표를 통해 캐릭터가 회전할 수 있도록 하였다.우선 이와 관련된 변수들을 우선 선언해주자.평상시와 조준시에 대한 TurnRate와 LookUprate 값들 이다. 마찬가지로 생성자에서 초기화 해주자. 조준 시와 비조준 시에 대해 값을 설정해주는 함수를 만들어 주자.매 순간 체크를 해야하므로 이를 Tick 함수 내에 위치시켜주면 된다. 다음으로 핵심이라고 할 수 있는 마우스에 대한 감도도 조절해주자.기존에 AddControllerPitchInput와 같은 함수로 간단하게 했던 것을 직접 함수를 생성하..

Aiming State Machine현재는 항상 조준하는 상태이므로, 이를 스테이트 머신을 통해 자세 전환을 하도록 만들어주자.이를 위해 ShooterAnimInstance 클래스에 Aiming 여부에 대한 변수가 필요하다. 이는 기존의 ShooterCharacter 클래스에서도 선언했었다.따라서 해당 클래스에서 getter 함수를 만들어주자. 이제 이를 이용하여 ShooterAnimInstance 클래스에서 Aiming 여부를 얻어주자. 다음으로 새롭게 스테이트 머신을 생성해주자. 마찬가지로 state에 애니메이션도 할당해주자.기존에 Cached한 내용을 사용한다. Aiming의 경우 기존 내용을 또 Cached로 저장하고, 이를 사용해주자. 변환 조건은 Aiming의 상태에 따라 변화한다. 변환 시간..

Aiming PoseAiming 시에 포즈가 다소 이상하기에 이번엔 이를 위한 Aiming Pose를 만들어주자.기존 포즈와 blend를 통한 작업을 해주어야 하므로, 기존 애니메이션을 Cached로 저장해주자. 그리고 에셋 브라우저에서 RMB_AO_CC 를 검색해보면 Aiming 포즈를 취하는 애니메이션을 볼 수 있다.해당 애니메이션을 사용하기 위해 복사본으로 따로 저장하고, blend를 통해 사용할 것이므로 애디티브 기능을 꺼주자.한쪽은 기본이고 한쪽은 애디티브 애니메이션일 때 blend 결과가 비정상적일 수 있다. 이제 스테이트 머신을 만들어서 Aiming에 대한 애니메이션을 설정해주자. 이를 기존 애니메이션과 blend 작업을 해주자. 이 상태로 플레이를 해보면 기존의 사격시 반동 애니메이션이 사..

Aiming Zoom Interpolation현재 줌으로 화면을 전환할 때 화면이 부드럽게 움직이지는 않는다.이번엔 이를 더 부드럽게 줌인아웃이 되도록 수정해보자. 먼저 줌인 했을 때 더 가깝게 보이고 조준점 위치를 줌인 상태에 맞게 위치하도록 관련된 값들을 다소 조정해주었다. 이제 줌인아웃시 부드럽게 전환되기 위한 보간 속도를 선언해주자.그리고 매번 시야값을 얻기 위한 변수도 선언해주었다. 마찬가지로 생성자에서 초기화 해주자. CamerCurrentFOV 값은 마찬가지로 BeginPlay() 함수에서 기존에 설정했던 디폴트 값으로 설정해주자. 이제 Tick 함수에서 매번 현재 카메라의 FOV 값을 얻으며, 이를 목표 FOV 값에 맞게 보간해주자.기본적으로 현재 카메라 FOV 값으로 카메라를 세팅하며, ..

Zooming Field of View 줌 여부에 따라 다른 View를 갖도록 설정해보자.우선 줌 여부 체크를 위한 bool 변수가 필요하다. 이후 해당 값을 생성자에서 초기화해주자.기본적으로 줌을 하지 않은 상태이므로 false가 기본값이 된다. 이제 줌 했을 때와 안 했을 때에 대한 함수가 필요하다. 해당 함수를 액션 매핑으로 바인딩 해주자.이를 위해 우선 매핑부터 만들어주자. 이제 기본 시야와 줌 했을 때 시야를 위한 변수도 선언해주자. 해당 값을 마찬가지로 생성자에서 초기화해주자.줌 했을 때의 시야는 우선 60으로 잡았다. BeginPlay() 함수에서 기본 시야에 대한 값을 FollowCamera 의 시야로 할당해주자. 이후 줌 여부에 따라 바인딩된 함수를 작동시키고, FollowCamer의 ..

Smoothing Character Movement움직임을 더 자연스럽게 만들어보자.지금은 멈출 때 갑작스럽게 멈추는 현상이 존재한다. 또한 좌우로 빠르게 움직이는 경우와 같이 특정 상황에서 캐릭터가 덜렁거리는 듯한 모습이 발생한다.이를 위해 먼저 Smooth Time을 설정해주자.그리고 Type은 Averaged로 변경해주었다.(언리얼 4의 경우 smooth Time -> interpolation / Type 기본 Averaged) Jog_start와 Jog_stop 2가지 블렌드 스페이스에 대해 같은 작업을 해주자. 이제 캐릭터가 크게 덜렁거리지 않고 훨씬 부드럽게 움직이는 모습을 볼 수 있다. 그리고 BP ShooterCharater 클래스의 CharacterMovement 디테일 패널을 보면 무브..

Jog Stop Blendspace이어서 Jog Stop에 대한 블렌드 스페이스이다.해당 애니메이션도 마찬가지로 left, right, bwd에 대해 stop 애니메이션이 따로 존재한다.똑같이 작업해주자. 컴파일 해보면 이번엔 제대로 적용되지 않고 여전히 jog_fwd_stop 동작이 재생되는 것을 볼 수 있다.이는 멈추는 순간이 더 이상 해당 방향의 속도를 가진 것이 아니라 0의 속도를 가지기 때문이다.따라서 0일 때의 애니메이션이 jog_fwd_stop 애니메이션이 재생되는 것이다. 이를 해결하기 위해서는 0이 아닐 때 직전 Offset 값을 얻어줄 필요가 있다.속도가 0보다 클 때만 따로 값을 저장해주도록 하자. 그리고 Offset 값을 해당 값으로 교체해주자. 이제 애니메이션을 다듬을 차례다. 우..

Jog Start BlendspaceJog Start에 대한 애니메이션도 블렌딩 작업이 필요하다.현재 모습에서 좌우로 뛰기 시작하면 다소 어색한 모습을 볼 수 있다.애니메이션을 보면 left, right, bwd 전부에 대한 start 동작이 따로 존재하는 것을 알 수 있다.이를 이용해서 블렌드 스페이스를 만들어주자. 좌우 애니메이션 할당 때와 동일하게 블렌드 스페이스에 배치해주자. 이번엔 JogStart 스테이트에 해당 블렌드 스페이스를 배치해주자. 필요시 기존 애니메이션 복사본을 조금 다듬어주자.여기서는 좌우 시작 애니메이션에 대해 다듬어주었다.

Strafing Blendspace이제 좌우 애니메이션을 실제로 할당해보자.우리는 블렌드 스페이스를 사용하여 자연스럽게 애니메이션이 블렌딩되도록 할 것이다.따라서 블렌드 스페이스를 먼저 생성해주자. 해당 블렌드 스페이스를 보면 디테일 패널에 Axis에 대한 세팅을 하는 칸이 존재한다.여기서 우리가 필요한 것은 수평 축이다.해당 값을 OffsetYaw로 하여, -180 ~ 180으로 설정해주자. 수직축은 이름만 할당하고 아직 사용하지 않으니 건들지 않는다. 이제 jog_fwd 부터 할당해보자.앞으로 걷는 경우이니 OffsetYaw가 0일 때여야 할 것이다. 뒤로 걷는 경우도 설정해주자.0과 반대로 180인 경우 뒤로 걷을 것이다.-180, 180 두 케이스 모두에 할당해주자. 좌우측도 할당해주자.각각 -9..

Movement Offset Yaw현재 좌우 이동에 대한 애니메이션이 존재하지 않는다.따라서 할당을 해주어야 하는데 이에 앞서서 어떤 상태 일 때 그러한 애니메이션을 할당 또는 블렌딩해야 하는지 알아야 할 필요가 있다.이를 위해 목표 회전 상태와 회전 값, 또 이 둘을 통해 상대적인 회전 차이 값을 얻을 수 있다.이것이 우리의 목표인 Movement OffSet Yaw 값이 된다. 먼저 해당 변수를 선언해주자.해당 작업은 애니메이션을 위한 것이므로 ShooterAinmInstance 클래스에서 하게 된다. 우선 목표 회전 상태를 얻어서 AddOnScreenDebugMessage 함수를 통해 뷰포트에 출력해보자. 이어서 회전 값도 구해서 출력해보자. 해당 값들을 NormalizedDeltaRotator 함..

Refactor Beam End Code현재 FireWeapon 함수가 상당히 길어져서 가독성이 안좋아졌다.해당 함수를 리팩토링하여 가독성을 높여보도록 하자. 빔의 마지막 위치를 얻는 데 필요한 내용을 모두 분리시켜보자.우선 인풋으로 필요한건 라인트레이스에 필요한 소켓 위치와 갱신될 빔위치이다.둘다 참조 변수로 선언해주고, 소켓 위치는 고정이기에 const도 추가로 작성해준다. 이제 필요한 내용을 보면 뷰포트사이즈를 얻어서 정중앙 위치를 얻고 이를 월드 값으로 변환하는 과정과,변환 성공 여부를 토대로 라인 트레이스를 하는 과정이다. 끝점에 대한 값은 인풋 참조 변수는 OutBeamLocation을 사용한다.그리고 총구 기준 시작점인 소켓 위치는 마찬가지로 인풋으로 설정했던 MuzzleSocketLocat..

Trace from Gun Barrel이제 크로스헤어를 통해 사격하므로 아무 문제없는 것 같지만, 오히려 크로스헤어를 기준으로 삼기에 문제가 발생하는 부분도 존재한다.만약 현재 큐브 앞에 또다른 큐브를 위치시키고 크로스헤어를 앞의 큐브 바로 옆에 위치시켜 사격할 경우 실제론 앞의 큐브에 부딪히지만 멈추지 않고 뒷 큐브까지 사격이 도달하는 모습을 볼 수 있다. 이를 수정하기 위해 라인 트레이스를 하나 더 설정해야 한다.새롭게 크로스헤어를 기준으로 설정했었지만, 기존에 했던 대로 총신을 기준으로 하는 라인 트레이스를 추가적으로 생성해주자. 그리고 임팩트 파티클의 위치 또한 수정해주자.2번의 라인 트레이스를 거친 후에 생성되어야 한다. 이제 컴파일 해보면 제대로 앞의 큐브에 먼저 충돌하는 모습을 볼 수 있다.