블루아카이브 52

[UE5] 블루아카이브 TPS게임 개발일지 (44) - 피격 방향 표시기 구현 1

TPS/FPS 게임에는 일반적으로 플레이어가 피격당했을 때, 어느 방향에서 맞았는지 표시해주는 UI가 있다영어로는 Damage Indicator라고 부른다. 이번엔 이를 구현하는 과정을 담을 것이다.UserWidget을 부모로 하는 블루프린트를 만들어 WBP_DamageIndicator라 짓고, 구글링으로 찾은 적절한 이미지를 가져와 다음과 같이 배치하였다.이미지는 화면 중앙을 피봇으로 하여, 빙글빙글 돌아갈 것이다. 이번에도 용이한 관리를 위해서, 블루프린트의 부모를 C++클래스로 설정해주려고 한다.  코드를 살펴보기 전에, 위젯이 페이드아웃되는 애니메이션을 만들어놓을 것이다.피격을 받고 3초정도 피격을 받지 않으면, 위젯이 천천히 사라지도록 할 것이다. 에디터 상단의 Window탭을 열어 Animat..

[UE5] 블루아카이브 TPS게임 개발일지 (43) - 피격 구현

지금까지 칸나가 총을 맞아도 딱히 반응이 없었다.이제부터는 실제로 체력이 깎이고, 피격 애니메이션도 재생하도록 할 것이다.  KannaCharacter 클래스에도 적에게 달아주었던 UAttributeComponent를 달아주고, 피격 애니메이션에 해당하는 HitMontage와 StunMontage를 추가하였다. // KannaCharacter.h 중 일부 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true")) UAttributeComponent* Attributes; UPROPERTY(EditDefaultsOnly, Category = Montages) UAnimMontage* Hi..

[UE5] 블루아카이브 TPS게임 개발일지 (41) - 장전 애니메이션 구현 2

장전 사운드는 Pixabay에서 구했다.탄창을 빼는 소리, 꼽는 소리, 슬라이드를 당기는 소리 이렇게 3개를 준비하였다.  그리고 장전 애니메이션에 Play Sound 노티파이를 추가해 각 상황에 맞는 소리를 재생하도록 하였다. 이렇게 사운드 추가도 완료되었다. 그런데 이미지를 보면 Sound 트랙 외에도 MagInOut 트랙이 있다.실제로 탄창이 빠지고 꼽히는 것을 구현하기 위해 만들어둔 노티파이들이다.  (이하의 내용은 다음 동영상의 도움을 받음https://www.youtube.com/watch?v=w-ouuDBSIao&ab_channel=UnrealDystopia)    현재 탄창은 Pistol 스켈레탈 메시의 일부로 박혀있다.탄창의 분리를 구현하기 위해서는, 총에 박혀있던 탄창은 없애고 단독 탄..

[UE5] 블루아카이브 TPS게임 개발일지 (40) - 장전 애니메이션 구현 1

이제 실제로 장전 애니메이션을 재생할 차례이다. Mixamo에서 받은 장전 애니메이션은 탄창을 넣는 것까지만 있고, 슬라이드를 당기는 것은 없었다. 개인적으로 꼭 넣고싶던 부분이기에, 애니메이션 시퀀스 편집창에서 수작업으로 추가해주었다.마지막에 ReloadEnd 애니메이션 Notify가 들어가있는데, 재장전을 끝내는 이벤트로써 활용할 것이다.    우선 CharacterStates.h의 ActionState에 재장전 스테이트를 추가해주었다.애니메이션 블루프린트가 현재 ActionState에 따라 애니메이션을 재생하고 있기 때문에, Reloading 스테이트도 추가해주는 것이다.UENUM(BlueprintType)enum class EActionState : uint8{ EAS_Neutral UMETA(D..

[UE5] 블루아카이브 TPS게임 개발일지 (39) - 탄약 UI 구현 2

KannaTPSOverlay의 탄약 개수가 실제로 업데이트되도록 할 것이다. 우선, KannaTPSOverlay 클래스 안에 탄약 개수를 설정하는 함수를 만들어주었다.void UKannaTPSOverlay::SetCurrentAmmoText(int32 Amount){ if (CurrentAmmoText) { FString String = FString::FromInt(Amount); CurrentAmmoText->SetText(FText::FromString(String)); }}void UKannaTPSOverlay::SetTotalAmmoText(int32 Amount){ if (TotalAmmoText) { FString String = FString::FromInt(Amount); Tota..

[UE5] 블루아카이브 TPS게임 개발일지 (38) - 탄약 UI 구현 1

슬슬 탄약 시스템과 재장전 시스템을 만들 때가 된 것 같다. 장전 로직의 핵심을 정리해보자면 다음과 같다. 총을 발사할 때마다 탄약 개수가 1씩 줄어든다.현재 탄약이 0이면 발사하지 못한다.장전을 통해 현재 탄약을 최대 탄약으로 채우고, 전체 탄약에서 채운 양을 제외한다. 실은 이러한 기본적인 것들은 이미 Gun 클래스에 구현해두었다.void AGun::Fire(FVector& StartPoint, FVector& Direction){ CurrentAmmo = FMath::Clamp(CurrentAmmo-1, 0, MaxAmmo); // 현재탄약 -1}/** MaxAmmo: 탄창에 들어가는 최대 탄약 개수* CurrentAmmo: 현재 탄창에 들어있는 탄약 개수* ReloadingAmmo: 전체 탄약 개..

[UE5] 블루아카이브 TPS게임 개발일지 (36) - 엄폐 시스템 구현 6

서서 엄폐한 상태에서 조준을 할 때, 기존 방식을 그대로 사용할 순 없다. 좌우로 막힌 상태에서 조준 버튼을 눌러도 조준을 해선 안되며, 좌 / 우로 트여있다면 그 방향으로 몸을 내밀면서 조준해야한다. 또한 카메라도 해당 방향으로 이동해야한다. 우선, CharacterStates.h에 조준 방향을 나타내는 EAimingDirection을 추가하였다.// CharacterStates.h#pragma onceUENUM(BlueprintType)enum class ECharacterState : uint8{ ECS_Unarmed UMETA(DisplayName = "Unarmed"), ECS_ArmedWithPistol UMETA(DisplayName = "Armed With Pistol"), ECS_Arme..

[UE5] 블루아카이브 TPS게임 개발일지 (35) - 엄폐 시스템 구현 5

카메라 좌우 전환을 만드는데는 블루프린트 쪽이 더 직관적일 것 같아, C++에서 함수를 BlueprintImplementableEvent를 사용하여 선언하였다. 그리고 현재 카메라가 좌우 중 어느 쪽에 있는지를 나타내는 플래그 변수를 선언하였다.// KannaCharacter.hUFUNCTION(BlueprintImplementableEvent)void SwitchCameraPos();UPROPERTY(BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))bool IsCameraAtRight SwitchCameraPos의 구현 내용은 다음과 같다.  플레이어가 탭을 눌러 수동으로 카메라를 좌우로 전환할 수 있도록, InputAction을 만들고 Input ..

[UE5] 블루아카이브 TPS게임 개발일지 (34) - 엄폐 시스템 구현 4

지난 포스팅까지 낮은 엄폐물에서의 엄폐의 구현을 완성했다. 이제 높은 엄폐물에서의 엄폐, 즉 서서 엄폐를 제작할 차례이다. 낮은 엄폐에서와 같은 메커니즘을 사용하되, 다음과 같은 변경/추가 요소가 있다.엄폐한 상태에서 가만히 있을 때 꼭 정면을 바라보지 않는다.서있는 상태에서의 엄폐는 방향이 정면으로 고정되어있는 것보다는 살짝 모서리를 바라보고 있는 편이 오히려 더 자연스럽기 때문이다.엄폐물의 오른쪽 끝에 붙어 조준하면 캐릭터가 오른쪽으로 조금 빠져나와 조준한다.엄폐물의 왼쪽 끝에 붙어 조준하면 캐릭터가 왼쪽으로 조금 빠져나와 조준한다.캐릭터가 빠져나와 조준하는 방향으로 카메라도 약간 이동한다. 먼저, 이전에 만들었던 StartCover에 낮은 엄폐인지 구분하는 파라미터를 하나 추가하였다.void AKa..

[UE5] 블루아카이브 TPS게임 개발일지 (33) - 엄폐 시스템 구현 3

엄폐 시에 이동을 담당하는 CoverTrace 함수는 굉장히 길고 복잡하다.따라서 이에 대한 설명을 포스팅 안에서보단, 코드에 주석을 최대한 많이 다는 것으로 대체하고자 한다.코드는 다음과 같다. (PC 환경에서 보는 것을 추천)void AKannaCharacter::CoverTrace(){ FHitResult HitResult; FCollisionQueryParams CollisionParameters; CollisionParameters.AddIgnoredActor(this); FVector ActorLocation = GetActorLocation(); UCharacterMovementComponent* Movement = GetCharacterMovement(); //현재 PlaneConstrai..