월드가 제공하는 충돌 판정 서비스를 사용
• 월드는 크게 세 가지의 충돌 판정 서비스를 제공함.
• 월드 내 배치된 충돌체와 충돌하는지 파악하고, 충돌한 액터 정보를 얻을 수 있음.

• 액션 판정을 위한 트레이스 채널의 생성 : ABAction. 기본 반응은 무시
• 캐릭터 캡슐용 프로필 : ABAction 트레이스 채널에 반응. 오브젝트 타입은 Pawn
• 스켈레탈 메시용 프로필 : 랙돌 구현을 위해 주로 활용됨.
• 기믹 트리거용 프로필 : 폰 캡슐에만 반응하도록 설정. 오브젝트 타입은 WorldStatic

월드 트레이싱 함수의 선택

• 세 가지 카테고리로 원하는 함수 이름을 얻을 수 있음.
 • 카테고리 1 : 처리 방법
 • 카테고리 2 : 대상
  • Test : 무언가 감지되었는지를 테스트
  • Single 또는 AnyTest : 감지된 단일 물체 정보를 반환
  • Multi : 감지된 모든 물체 정보를 배열로 반환
 • 카테고리 3 : 처리 설정
  • ByChannel : 채널 정보를 사용해 감지 • ByObjectType : 물체에 지정된 물리 타입 정보를 사용해 감지 • ByProfile : 프로필 정보를 사용해 감지

{처리방법}{대상}{처리설정}

캐릭터 공격 판정의 구현

• 캐릭터의 위치에서 시선 방향으로 물체가 있는지 감지
• 작은 구체를 제작하고 시선 방향으로 특정 거리까지만 투사.
• 하나의 물체만 감지
• 트레이스 채널을 사용해 감지

물리 충돌 테스트

• 디버그 드로잉 함수를 사용해 물리 충돌을 시각적으로 테스트
• 90도로 회전시킨 캡슐을 그리기
  • Origin
  • HalfHeight
  • Radius

<코드 예시>

몽타주에서 충돌체크할 노티파이를 클래스로 생성.

<.h>

UCLASS()
class ARENABATTLEDEMO_API UAnimNotify_AttackHitCheck : public UAnimNotify
{
	GENERATED_BODY()

protected:
	//애니메이션 노티파이가 발생할때 호출되는 이벤트 함수.
	virtual void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference) override;
	
	
};

<CPP>

// Fill out your copyright notice in the Description page of Project Settings.


#include "Animation/AnimNotify_AttackHitCheck.h"
#include "Interface/ABAnimationAttackInterface.h"

void UAnimNotify_AttackHitCheck::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
	const FAnimNotifyEventReference& EventReference)
{
	Super::Notify(MeshComp, Animation, EventReference);

	if (MeshComp)
	{
		//애니메이션을 소유하는 액터가 인터페이스를 구현했는지 확인.
		IABAnimationAttackInterface* AttackInterface = Cast<IABAnimationAttackInterface>(MeshComp->GetOwner());

		//인터페이스를 구현한 경우, 함수 호출.
		if (AttackInterface)
		{
			AttackInterface->AttackHitCheck();
		}
	}
}

생성한 노티파이를 몽타주에 설정.

인터페이스 생성.

공격충돌 체크를 순수 가상함수로 만든다.<CPP>

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ABAnimationAttackInterface.generated.h"

// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UABAnimationAttackInterface : public UInterface
{
	GENERATED_BODY()
};

/**
 * 
 */
class ARENABATTLEDEMO_API IABAnimationAttackInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	virtual void AttackHitCheck() = 0;
};

캐릭터클래스에서 인터페이스를 상속.

class ARENABATTLEDEMO_API AABCharacterBase : public ACharacter, public IABAnimationAttackInterface

해당 함수를 구현.<CPP>

void AABCharacterBase::AttackHitCheck()
{
	//공격 판정 진행.
	//UE_LOG(LogTemp, Log, TEXT("AttackHitCheck!!"));

	//충돌 시작 지점 계산.
	//캐릭터 몸통에서 약간 앞으로(캡슐의 반지름 만큼) 설정.
	FVector Start = GetActorLocation() + GetActorForwardVector() * GetCapsuleComponent()->GetScaledCapsuleRadius();

	//공격 거리.
	const float AttackRange = 50.0f;
	FVector End = Start + GetActorForwardVector() * AttackRange;

	//SCENE_QUERY_STAT: 언리얼에서 지원하는 분석 툴에 태그를 추가.
	//두번째 인자: 복잡한 형태의 충돌체를 감지할지 여부.
	//세번째 인자: 무시할 액터 목록.
	FCollisionQueryParams Params(SCENE_QUERY_STAT(Attack), false,this);

	//트레이스에 사용할 구체의 반지름.
	const float AttakcRadius = 50.0f;

	//트레이스를 활용해 충돌 검사.
	FHitResult OutHitResult;
	bool HitDetected = GetWorld()->SweepSingleByChannel(
		OutHitResult,
		Start,
		End,
		FQuat::Identity
		, CCHANNEL_ABACTION,
		FCollisionShape::MakeSphere(AttakcRadius),
		Params);

	// 충돌 감지된 경우의 처리.
	if (HitDetected)
	{
		//Damage 양.
		const float AttackDamage = 30.0f;

		//데미지 이벤트.
		FDamageEvent DamageEvent;
		
		//데미지 전달.
		OutHitResult.GetActor()->TakeDamage(AttackDamage, DamageEvent, GetController(), this);
		
	}

	//충돌 디버그(시각적으로 확인할 수 있도록).
#if ENABLE_DRAW_DEBUG
	//캡슐의 중심 위치.
	FVector CapsuleOrigin = Start + (End - Start) * 0.5f;

	//캡슐의 높이 절반 값.
	float CapsuleHalfHeight = AttackRange * 0.5f;

	//표시할 생상(안맞으면 빨강, 맞으면 초록)
	FColor DrawColor = HitDetected ? FColor::Red : FColor::Green;

	//캡슐 그리기.
	DrawDebugCapsule(GetWorld(),
		CapsuleOrigin,
		CapsuleHalfHeight,
		AttakcRadius,
		FRotationMatrix::MakeFromZ(GetActorForwardVector()).ToQuat(),
		DrawColor,
		false,
		5.0f
		);
	
#endif
	
}

 

'언리얼 엔진 공부 > 언리얼C++' 카테고리의 다른 글

아이템 시스템(트리거)  (0) 2025.04.21
캐릭터 애니메이션 시스템  (0) 2025.04.14
데이터 애셋  (0) 2025.04.14
언리얼 엔진 게임 제작 기초  (0) 2025.04.10
어설션(Assertion)  (0) 2025.04.08

+ Recent posts