[23. Trimming Animations]
![](https://blog.kakaocdn.net/dn/BIZGi/btrPviZlX3G/BiJ6Mg6ITWzlrm0KUW0KyK/img.png)
애니메이션의 길이를 원하는대로 자를 수 있다.
[29. Blending Shooting Animations]
![](https://blog.kakaocdn.net/dn/c0RueR/btrPDHYSb99/0jIFCMsKJf9qA3X9KRKwp1/img.png)
![](https://blog.kakaocdn.net/dn/cvIN4T/btrPIJmS11k/oefO5YZxWWMGYitKrJPgHK/img.webp)
별다른 블렌드 없이 이동과 사격 애니메이션을 연결하면 위와 같이 이동 사격시 매우 어색하다.
이동과 사격 애니메이션의 상하체를 블렌드시키면 자연스러워질 것이다.
그러면 상하체를 구분할 수 있는 기준점이 있어야 하는데, 척추의 시작점을 기준으로 잡으면 적당할 것이다.
![](https://blog.kakaocdn.net/dn/dLBEtC/btrPDl9yJTc/wyd9kkUmpkMGKLVelMUDg0/img.png)
![](https://blog.kakaocdn.net/dn/VsV1z/btrPFzyQz1a/nrpD8fHJKkxyRO3lMfknh0/img.png)
![](https://blog.kakaocdn.net/dn/baVRPv/btrPEoLB3M5/3Bsro2k2NaC0iGnf2IxkE1/img.png)
인덱스를 추가하고 본 이름은 위에서 봤던 척추의 시작점인 spine_01으로 설정한다.
![](https://blog.kakaocdn.net/dn/bv7JaZ/btrPIEMOZ6p/bkf3kb0tNlbO6UzpaM5W7k/img.png)
기본은 이동이 되므로 베이스 포즈로 이동 애니메이션 캐시포즈를 지정하고 블렌드 포즈로 사격 캐시포즈를 지정한다.
![](https://blog.kakaocdn.net/dn/c7uZm2/btrPFdpcqFs/D0vhJMICine0bWAwrjqCfk/img.webp)
[32. Beam Particles]
ParticleSystemComponent로 파티클의 속성을 지정해줄 수 있다.
UParticleSystemComponent* Beam = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), BeamParticles, SocketTransform);
if (Beam)
{
Beam->SetVectorParameter(FName("Target"), BeamEndPoint);
}
[33. Socket Offset]
SpringArm의 SocketOffset값을 설정하면 카메라가 부착되는 소켓의 위치가 해당 로컬 좌표로 설정된다.
[34. HUD Class and Crosshairs]
UI를 그리는 방법은 몇 가지가 있다.
![](https://blog.kakaocdn.net/dn/OuWev/btrPFX8apI9/4EQPGoKeqgww3KoKPDwxM1/img.png)
그중 하나인 HUD 클래스를 만들어서 출력하는 방법을 사용한다.
HUD 블루프린트 클래스를 만들어서 게임모드의 기본 HUD로 설정해주면 된다.
Size X,Y는 해상도를 반환해준다.
[35. Directing Rifle Shots]
![](https://blog.kakaocdn.net/dn/GYfcI/btrPJWGrWfO/IgaMVQeX3hvAgKXVZPiPi1/img.png)
TPS 게임에서는 보통 크로스헤어에 정확하게 발사되길 기대한다. 또한 원활한 시야 확보를 위해서 캐릭터가 화면의 정중앙이 아닌 왼쪽이나 오른쪽으로 치우치게 된다.
이 때문에 레이캐스트를 한 번만 사용한다면 총알의 타격 이펙트가 의도하지 위치에 생성되므로 두 번의 레이캐스트를 통해 값을 보정하여 사용해야 한다.
![](https://blog.kakaocdn.net/dn/bgA9ZQ/btrPJcXrdaK/ZHhQS1ZzBko9KDbJSzOkQk/img.png)
위와 같이 캐릭터가 벽에 근접한 경우 에임은 벽이 아닌 옆을 가리키게 되지만 총구는 벽을 가리키고 있으므로 발사 시 총알이 벽에 가로막혀야 정상일 것이다.
하지만 총구가 아닌 카메라를 기준으로 레이캐스트가 되어있기 때문에 벽을 뚫고 발사가 된다.
![](https://blog.kakaocdn.net/dn/cYVNWa/btrPI8VnUZs/ikKHHNtGUZHRUpm8aeJFpk/img.png)
첫 레이캐스트로 에임과 오브젝트의 충돌 여부를 판단해서 끝점을 조정하고 두번째 레이캐스트로 실제 착탄 위치를 판별한다.
연산이 모두 끝난다면 궤적을 알려주는 트레일이나 착탄 이펙트를 재생시켜주면 된다.
![](https://blog.kakaocdn.net/dn/c4aUg4/btrPIgz08LW/ALGzNlK5sNIk81VXKmHrpK/img.png)
레이캐스트 연산을 두번해야 하는 이유는 위 그림으로 설명이 될 것이다.
[38. Movement Offset Yaw]
블렌드 스페이스를 적용하기에 앞서서 캐릭터가 이동하는 방향에 대한 각도를 구해야 한다.
![](https://blog.kakaocdn.net/dn/bdcAEI/btrPIRGzw3I/drKKKXnKiKPYyM7Px196P1/img.png)
캐릭터는 월드좌표에 상대적이기 때문에 속도나 방향은 캐릭터의 회전에 따라 값이 변하게된다.
그래서 기준점을 항상 0˚로 유지할 수 없다.
하지만 플레이어의 시야와 속도 회전값 두개를 연산하면 두 값의 차이에 의해 원하는 값을 구할 수 있다.
다만 기준점을 0˚로 유지하는것은 아니고 단순히 두 값을 연산한 결과에 의해 나오는 값이다.
FRotator AimRotation = ShooterCharacter->GetBaseAimRotation();
FRotator MovementRotation = UKismetMathLibrary::MakeRotFromX(ShooterCharacter->GetVelocity());
MovementOffsetYaw = UKismetMathLibrary::NormalizedDeltaRotator(MovementRotation, AimRotation).Yaw;
![](https://blog.kakaocdn.net/dn/cFH3xp/btrPJ28aEGv/Y2prisulAfLvqyKRRA6In1/img.png)
AimRotation은 월드 좌표에 상대적이고 MovementRotation은 AimRotation에 상대적이기 때문에 두 값의 차이는 캐릭터의 회전과 관계없이 언제나 일정하게 나온다. 다만 속도가 0이라면 AimRotation을 빼고있기 때문에 마우스의 회전만으로도 각이 변하게 된다.
이때는 캐릭터 트랜스폼의 역행렬로 속도를 변환시켜주면 된다.
언제나 0˚의 기준으로 속도의 방향을 구하기때문에 속도가 0이라면 항상 0˚가 된다.
[41. Jog Stop Blendspace]
이동 시작, 이동 중에는 애니메이션 재생에 문제가 없지만 정지 애니메이션에는 문제가 생긴다.
이유는 정지하는 순간 속도가 0이 되면서 OffsetYaw값이 AimRotation값으로 변해버리기 때문이다.
속도가 0이 아닐때 마지막 Yaw값을 저장해서 그걸 사용하면 문제를 해결할 수 있다.
'언리얼 엔진 > UE C++ Shooter Course' 카테고리의 다른 글
[UE C++ Shooter] Weapons (0) | 2022.11.07 |
---|---|
[UE C++ Shooter] Aiming and Crosshairs (0) | 2022.11.05 |