[UE5] Boss - Melee Attack Skill

윤정민·2023년 4월 28일

1. 개요

Melee Attack을 구현하는 방법은 다양하다. 이번 포스트에서는 fist에 collision component를 붙여 공격하는 법과 Trace를 사용하는 방법을 알아보자.

2. Collision Component

2.1. 초기 설정

  • 양쪽 주먹에 Box Collision을 붙여주자
    • Skeletal에 들어가 Hand 왼쪽 오른쪽 모두 소켓을 생성한 뒤 해당 소켓에 붙이면 됨
  LeftBox->AttachToComponent(GetMesh(), AttachmentRules, "LeftFist");
  RightBox->AttachToComponent(GetMesh(), AttachmentRules, "RightFist");

  • 해당 콜리전을 OverlapAll로 설정
LeftBox->SetCollisionProfileName(TEXT("OverlapAll"));
RightBox->SetCollisionProfileName(TEXT("OverlapAll"));
  • 콜리전이 overlap될 때 공격을 실행할 수 있도록 공격함수를 bind 하자
LeftBox->OnComponentBeginOverlap.AddDynamic(this, &AMonsterBase::OnOverlapBegin);
RightBox->OnComponentBeginOverlap.AddDynamic(this, &AMonsterBase::OnOverlapBegin);

2.2 콜리전 활성화

항상 주먹에 닿일 때 공격이 된다면 이상할 것이다. 그러니 공격시에만 콜리전을 활성화 시켜주자

  • 콜리전 활성화
LeftBox->SetGenerateOverlapEvents(true);
RightBox->SetGenerateOverlapEvents(true);
  • 콜리전 비활성화
LeftBox->SetGenerateOverlapEvents(false);
RightBox->SetGenerateOverlapEvents(false);
  • Animation notify
    • Attack Notify: Enable Collision
    • AttackEnd Notify: Disable Collision

3.Trace 생성

3.1. Trace 생성 타이밍

  • ChargedAtk Notify가 실행될 때 Collsion을 생성

3.2. Trace 생성 위치

나는 콤보 공격으로 구성했기 때문에 왼손으로 공격시엔 왼손 위치에 Trace를 생성하고 오른손으로 공격시엔 오른손 위치에 Trace를 생성해야 한다.

  • 구현방법: Montage slot Name으로 해당 공격이 어느손으로 진행되고 있는지 판별
switch (FistIndex)
{
case 1:
	FistLoc = GetMesh()->GetSocketLocation(FName("LeftFist"));
	break;
case 0:
	FistLoc = GetMesh()->GetSocketLocation(FName("RightFist"));
	break;
}

3.3. Trace 생성

  • SweepSingleByChannel: Trace를 생성하는 함수
  • 구한 위치에 trace를 생성
FHitResult HitResult;
FCollisionQueryParams Params(NAME_None, false, this);
bool bResult = GetWorld()->SweepSingleByChannel(
	HitResult,
	FistLoc,
	FistLoc+ 50.f,
	FQuat::Identity,
	ECollisionChannel::ECC_GameTraceChannel1,
	FCollisionShape::MakeSphere(50.f),
	Params
);

3.4. 공격

  • 해당 Trace가 인식한 객체에 Damage를 입힘
if (bResult)
{
	if (HitResult.GetActor()->IsValidLowLevel())
	{
		FDamageEvent DamageEvent;
		HitResult.GetActor()->TakeDamage(ChargedAttackDamage, DamageEvent, GetController(), this);
	}
}

3.5. 참고

Trace가 생성되는 모양을 보고싶다면 DrawDebug로 똑같이 그려줘야된다. 좀 귀찮다.. 하는김에 결과에 따라 색도 변경해보자

	FColor DrawColor = bResult ? FColor::Green : FColor::Red;
	DrawDebugCapsule(
		GetWorld(),
		TargetLoc,
		100.f,
		100.f,
		FRotationMatrix::MakeFromZ(GetActorForwardVector()).ToQuat(),
		DrawColor,
		false,
		3.f);

4. 스킬 구현

멀리있는 플레이어에게 점프하여 공격하는 스킬을 구현하기 위해 필요한 기능을 생각해보자. 해당 위치로 이동하여 똑같이 Trace를 생성하면 된다.

4.1. 해당 위치로 이동

  • MoveComponentTo: Component를 원하는 위치로 이동해주는 함수
  • TargetLoc: player의 위치
  • Rotation: 몬스터가 Player를 바라보는 Rot로 설정(PlayerLoc-MonsterLoc)
    FLatentActionInfo Info;
	Info.CallbackTarget = this;
	UKismetSystemLibrary::MoveComponentTo(
		GetCapsuleComponent(),
		TargetLoc,
		(Target->GetActorLocation() - GetActorLocation()).Rotation(),
		true,
		true,
		0.35f,
		false,
		EMoveComponentAction::Type::Move,
		Info);
profile
그냥 하자

0개의 댓글