필요한 개념
적을 Hitted 시킬때 플레이어의 타격감
타격감을 구현하는 요소
- 사운드(PlaySound)
- 애니메이션(AnimMontage)
- 이펙트(파티클, ParticleSystem)
- 카메라 흔들림(CameraShake)
- 진동
- 경직(HitStop)
- 칼 Trail
<HitEffect>
적이 Hitted된 떄에 Effect가 나타남
* 보정된 위치에 Effect 플레이 시킴
// ACDoAction_Melee.cpp의 OnAttachmentBeginOverlap()
UParticleSystem* hitEffect = Datas[Index].Effect;
if (!!hitEffect)
{
FTransform transform = Datas[Index].EffectTransform;
// EffectTransform 보정 만큼 이동
transform.AddToTranslation(InOtherCharacter->GetActorLocation());
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), hitEffect, transform);
}
<HitStop>
일반적인 PC게임에서 진동은 어려움, 스마트폰은 가능
사운드 중요, 애니메이션..
HitStop이 제일 중요
HitStop(경직) : 타격을 주면 일시적으로 잠깐 멈추는 느낌
* 경직을 어떤 아이디어로 구현해야 하냐?
UGameplayStatics::SetGlobalTimeDilation() : 지정한 배속으로 게임의 속도를 조정(게임을 느리게 해줌)
ex) 게임에서 무기 선택할때, 게임자체가 느리게 진행되면서 무기 선택가능
// 원본 속도 1, 0.1이라면 10배 느려짐
// 0.1배 만큼 느리게 만듬
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), 0.1f);
ex) 우리는 적이 칼에 충돌될때 100배 정도 느리게 한다음 충돌이 멈추면 다시 원본 1로 돌아오게 만듬
우리는 DataAsset에 hitStop값을 넣어놓았었다.
이 값을 불러들인 다음 사용
ex) hitStop값이 1이라면 1초 이따가 다시 GlobalTimeDilation이 원래 1로 돌아옴..
-> 이렇게 되면 적은 1초간 경직 상태가 됨
// CDoAction_Melee.cpp
float hitStop = Datas[Index].HitStop;
// 0 이랑 가깝지 않으면 함
if (FMath::IsNearlyZero(hitStop) == false)
{
// 1e-3f -> 10^-3 -> 1 / 1000초 -> 0.001
// 1000배 정도 느리게 만듬
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), 1e-3f);
// 월드가 느려지만 타이머도 느려진다. 그래서 다시 그 시간만큼 곱해서 회복시킴
// 즉, hitStop만큼 딜레이 시킴
UKismetSystemLibrary::K2_SetTimer(this, "RestoreDilation", hitStop * 1e-3f, false);
}
void ACDoAction_Melee::RestoreDilation()
{
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), 1.0f);
}
hitStop을 0.075로 주었을때, 살짝 끊기면서 잘나옴
그러나 결과를 보면 뭔가 심심?
-> 카메라 효과(CameraShake) BP를 만들어서 추가
<카메라 효과 세팅>
언리얼 좌표계에 의하면 Y가 좌우, Z가 상하
* Y, Z 중심으로 흔듬
* 3번째 동작이 옆으로 공격하는 동작이라, 좌우(Y)로 더 흔들어야 있어보임
* DA_OneHand에다가 CameraShake 세팅
* CDoAction_Melee.cpp OnAttachmentBeginOverlap()에 CameraShake 플레이
TSubclassOf<UCameraShake> shake = Datas[Index].ShakeClass;
if (!!shake)
UGameplayStatics::GetPlayerController(GetWorld(), 0)->PlayerCameraManager->PlayCameraShake(shake);
* 지금 경직이 먼저 실행되고, 이따가 Effect가 플레이되어서 어색한 현상이 있다.
-> 경직은 타격 이후 약간의 시간 후에 경직을 주는 것이 좀 더 자연스럽다.
-> Effect 먼저 주고 일정 시간 뒤에 HitStop(경직)주면 된다.
CDoAction_Melee.h 수정된 내용
...
UCLASS()
class UONLINE_04_ACTION_API ACDoAction_Melee : public ACDoAction
{
GENERATED_BODY()
...
private:
UFUNCTION()
void RestoreDilation();
};
CDoAction_Melee.cpp 수정된 내용
...
void ACDoAction_Melee::OnAttachmentBeginOverlap(class ACharacter* InAttacker, class AActor* InAttackCauser, class ACharacter* InOtherCharacter)
{
Super::OnAttachmentBeginOverlap(InAttacker, InAttackCauser, InOtherCharacter);
CheckNull(InOtherCharacter);
for (const ACharacter* other : HittedCharacters)
{
if (InOtherCharacter == other)
return;
}
HittedCharacters.Add(InOtherCharacter);
UParticleSystem* hitEffect = Datas[Index].Effect;
if (!!hitEffect)
{
FTransform transform = Datas[Index].EffectTransform;
// EffectTransform 보정 만큼 이동
transform.AddToTranslation(InOtherCharacter->GetActorLocation());
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), hitEffect, transform);
}
float hitStop = Datas[Index].HitStop;
// 0 이랑 가깝지 않으면 함
if (FMath::IsNearlyZero(hitStop) == false)
{
// 1e-3f -> 10^-3 -> 1 / 1000초 -> 0.001
// 1000배 정도 느리게 만듬
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), 1e-3f);
// 월드가 느려지만 타이머도 느려진다. 그래서 다시 그 시간만큼 곱해서 회복시킴
// 즉, hitStop만큼 딜레이 시킴
UKismetSystemLibrary::K2_SetTimer(this, "RestoreDilation", hitStop * 1e-3f, false);
}
TSubclassOf<UCameraShake> shake = Datas[Index].ShakeClass;
if (!!shake)
UGameplayStatics::GetPlayerController(GetWorld(), 0)->PlayerCameraManager->PlayCameraShake(shake);
// 데미지 추가 정보를 넘길때
FDamageEvent e;
// 1. 데미지, 2. 데미지 이벤트, 3 : Instigator(컨트롤러), 4 : DamageCursor(데미지 야기하는 친구)
InOtherCharacter->TakeDamage(Datas[Index].Power, e, OwnerCharacter->GetController(), this);
}
void ACDoAction_Melee::RestoreDilation()
{
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), 1.0f);
}
결과
'Unreal Engine 4 > C++' 카테고리의 다른 글
<Unreal C++> 55 - Action RPG (Fist Mode) (0) | 2022.05.16 |
---|---|
<Unreal C++> 54 - Action RPG (TwoHand Mode) (0) | 2022.05.16 |
<Unreal C++> 51 - Action RPG(Enemy Hitted) (0) | 2022.05.16 |
<Unreal C++> 50 - Action RPG (Enemy UI) (0) | 2022.05.16 |
<Unreal C++> 48 - Action RPG (Create Enemy & Collision) (0) | 2022.05.16 |