본문 바로가기
Unreal Engine5/KDT 2024

[UE5 KDT2024] 24. 충돌 2

by 유잉유잉유잉 2025. 3. 8.
728x90

 

1. 공격시 충돌처리 

 

1) 공격용 박스 컬라이더 추가 

PlayerKnight.h

protected:
	UPROPERTY( EditAnywhere, BlueprintReadWrite )
	UBoxComponent* mAttackCollision;

생성자에서 mAttackCollision 만들어주기

APlayerKnight::APlayerKnight()
{
...
	mAttackCollision = CreateDefaultSubobject<UBoxComponent>( L"WeaponBox" );
	mAttackCollision->SetupAttachment( meshCp, L"Sword_Mid");
	mAttackCollision->SetCollisionProfileName( L"PlayerAttack");
}

SetupAttachment의 두번째 인자에 붙일 소켓의 이름을 FText형으로 넣으면 된다.


소켓 이름 확인 : 스켈레톤 에디터에서 이렇게 생긴게 소켓임.  

 

2) 컬리전 설정에 PlayerAttack 추가 

(1) PlayerAttack 채널 추가  

 

(2) PlayerAttack 프로파일 추가 

 

(3) BP_PlayerKnight 에디터 가서 

mAttackCollision 사이즈를 박스크기 변경해가며 적절한 값을 찾기 -> 해당값을 코드에 적용해주기 

 

(4) AttackCollision 박스 크기 적용

APlayerKnight::APlayerKnight()
{
	...
	mAttackCollision->SetBoxExtent( FVector( 3, 10, 45 ) );
}

 

(5) 플레이어 공격으로 충돌 일어났을 때 충돌 감지할 함수 추가 

header

	UFUNCTION()
	void OnPlayerAttackCollision( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult );

BeginPlay  

void APlayerKnight::BeginPlay()
{
	...
	mAttackCollision->OnComponentBeginOverlap.AddDynamic( this, &APlayerKnight::OnPlayerAttackCollision );
}
void APlayerKnight::OnPlayerAttackCollision( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult )
{
	GEngine->AddOnScreenDebugMessage( 1, 10.f, FColor::Black, L"OnPlayerAttackCollision" );
}

=> 실행 수 플레이어 공격으로 몬스터 타격시 (충돌이 일어날 경우 ) OnPlayerAttackCollision이 호출된다. 



 

 


 

 

2. 공격할때만 mAttackCollision 활성화 그외엔 비활성화 처리하기  

 

1) PlayerBase.h : Attack 시작, 종료 함수 추가 -> 구현하고 비워두기

public : 
.. 
	virtual void AttackBegin();
	virtual void AttackEnd();

 

2) AnimBase에서 공격 시작/종료시 해당 함수 호출

void UAnimBase::AnimNotify_AttackBegin()
{
	mAttackCombo = false;

	// 플레이어 충돌체 켜주기 
	// TryGetPawnOwner() : 나를 가지고 있는 Owner를 가지고 온다.
	APawn* pawnOwner = TryGetPawnOwner();
	if ( !IsValid( pawnOwner ) )
		return;

	APlayerBase* ownerPlayer = Cast<APlayerBase>( pawnOwner );
	if ( !IsValid( ownerPlayer ) )
		return;

	ownerPlayer->AttackBegin();
}

void UAnimBase::AnimNotify_AttackEnd()
{
	APawn* pawnOwner = TryGetPawnOwner();
	if ( !IsValid( pawnOwner ) )
		return;

	APlayerBase* ownerPlayer = Cast<APlayerBase>( pawnOwner );
	if ( !IsValid( ownerPlayer ) )
		return;

	ownerPlayer->AttackEnd();
..
}

▶️TryGetPawnOwner() : 나를 가지고 있는 Owner를 가지고 온다. 

 

3)

PlayerKnight.h

public :
    ..
    virtual void AttackBegin() override ;
    virtual void AttackEnd() override;

 

4) cpp

void APlayerKnight::AttackBegin()
{
	mAttackCollision->SetCollisionEnabled( ECollisionEnabled::QueryAndPhysics );
}

void APlayerKnight::AttackEnd()
{
	mAttackCollision->SetCollisionEnabled( ECollisionEnabled::NoCollision );
}

 

5) 생성자에서 컬리전 비활성화 

APlayerKnight::APlayerKnight()
{
...
	mAttackCollision->SetCollisionEnabled( ECollisionEnabled::NoCollision );
}

 

 

 


 

 

3. 공격시 이펙트 출력 - 파티클 생성 

 

1) 공격 충돌시 처리 

void APlayerKnight::OnPlayerAttackCollision( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult )
{
	GEngine->AddOnScreenDebugMessage( 1, 10.f, FColor::Black, L"OnPlayerAttackCollision" );

	UParticleSystem* particle = LoadObject<UParticleSystem>( nullptr, L"/Script/Engine.ParticleSystem'/Game/ParagonAurora/FX/Particles/Abilities/Primary/FX/P_Aurora_Melee_SucessfulImpact.P_Aurora_Melee_SucessfulImpact'" );
	FVector loc = OtherActor->GetActorLocation();
	UParticleSystemComponent* particleCp = UGameplayStatics::SpawnEmitterAtLocation( GetWorld(), particle, loc, GetActorRotation(), true ); 
}

▶️ LoadObject : 생성자 말고 다른곳에서 에셋 가져오기 

  - 동기로딩. 로딩될때까지 멈춰있음 

▶️ SpawnEitterAtLocation() : 마지막 인자가 true면 파티클 실행 후 사라짐 

 

=> 실행하면 충돌시 파티클이 정상적으로 생성됨을 확인할 수 있다. 

 

=> 멀티로 실행하면 파티클 나오고 있음. 

 

하지만 충돌처리는 서버에서 처리해줘야 한다.

=> 찍어보면 서버한번, 클라한번 들어오고 호출되고 있다. 원래 서버에서 처리해야 한다. 

 

728x90

댓글