언리얼 엔진/25.01.23 2차프로젝트 기술

에너미 충돌 콜리전 세팅하기

odkokdh 2025. 2. 25. 09:54

이번에는 일단 에너미가 플레이어의 총알에 맞았을 경우 체력이 감소하는 것을 구현하려고 한다.

 

먼저 에너미의 콜리전 프리셋을 제작한다.

 

언리얼 엔진 창의 좌측 상단에서 Edit을 누른 다음 Project Settigs...를 클릭한다.

 

그러면 Project Settings 창이 나오는데 좌측에서 Engine의 Collision을 클릭해주자. 그러면 콜리전을 세팅하는 창이 된다.

 

이후 자신이 원하는 콜리전을 하나 새로 만들어 주자. Object Channels에서 New Object Channel...을 클릭하여 새로운 콜리전 채널을 만든다. 이름은 자신이 파악할 수 있는 것으로 지어주며 Default Response는 다른 콜리전 채널과 충돌 처리 설정을 무엇으로 기본으로 할지 정하는 것이다. 나는 일단은 Ignore로 설정하였다.

 

더보기

콜리전의 설정은 Ignore, Overlap, Block으로 세가지가 있다. Ignore는 무시, Overlap은 충돌 감지, Block은 막아버리는 것이다.

콜리전 세팅을 할때 주의할 점은 Ignore, Overlap, Block의 우선 순위가 있다. 만약 콜리전 A와 콜리전 B의 충돌이 일어날 경우 각각의 기본 설정에 따라 다음과 같이 충돌이 이루어진다.

 

  Ignore Overlap Block
Ignore Ignore Ignore Ignore
Overlap Ignore Overlap Overlap
Block Ignore Overlap Block

Ignore 상태의 콜리전은 무엇과 부딪혀도 Ignore로, 충돌 무시가 된다.

Overlap 상태의 콜리전은 Ignore를 제외하고 다른 것과 충돌할 경우 Overlap처리가 된다 .

Block 상태의 콜리전은 서로 Block 설정을 해줘야된다 .

 

위에 콜리전을 표로 나타냈지만 간단하게 우선순위만 표시하자면 다음과 같다.

①. Ignore ②. Overlap ③. Block 

우선순위가 높은 것이 우위를 갖고 있어 해당 처리로 이루어진다. 이와 같이 충돌 우선순위가 이루어지는 이유는 Ignore는 그냥 충돌 무시로 충돌 처리가 더 적기 때문이다. 반대로 아예 충돌을 막아버리는 Block은 충돌 처리가 많아 Block 우선순위가 떨어진다.

그래서 Ignore는 다른 것과 부딪혀도 Ignore 처리가 되는 것이다.

콜리전 채널을 새로 만들었다면 이제 프리셋을 만들 것이다.

같은 화면에서 Preset의 New를 눌러 새로운 프리셋을 만들었다. 나는 일단 Enemy라 프리셋의 이름을 정하였다.

 

New를 눌렀을 때 다음과 같은 창이 새로 나온다.

Name 해당 프리셋의 이름, 자신이 해당 프리셋이 뭔지 알 수 있는 이름을 적어주자.
Collision Enabled 해당 콜리전이 감지 또는 물리작용을 하는지 설정하는 칸, 자세한 설명은 후술
Object Type 해당 콜리전의 타입을 설정하는 칸, 위에서 만든 Object Channels 중에서 하나를 선택하자.
Description 해당 프리셋이 무엇인지 설명을 적는 칸, 딱히 적을 내용이 없으면 그대로 둬도 된다.
Collision Responses 만들어져 있는 각 콜리전 Type과 어떠한 충돌 처리를 할 것인지 설정하는 칸, 각 콜리전 타입에 맞게 설정을 바꿔주자.

 

더보기

Collision Enabled에 대한 설명이다. 무엇이 물리작용, 감지를 하는지 서술하였다.

 

No Collision 감지와 물리작용 둘다 사용하지 않음.
Query Only 감지 기능만 동작하는 상태
Physics Only 물리 작용만 동작하는 상태
Collision Enabled 감지와 물리작용 모두 동작하는 상태

위와 같이 되어 있으며 자신의 콜리전과 상황에 따라 설정해주면 된다.

 

위와 같이 콜리전을 만들고 프리셋을 만들었다면 이제 Collision에 직접 적용을 할 차례이다.

나는 C++를 이용하여 콜리전을 셋팅하였다.

 

MeleeEnemy.cpp

AMeleeEnemy::AMeleeEnemy()
{
	//콜리전을 이름이 Enemy인 프리셋으로 설정
	GetCapsuleComponent()->SetCollisionProfileName(FName("Enemy"));
	//충돌을 할 때 실행될 함수 설정
	GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AMeleeEnemy::OnEnemyOverlap);
	//콜리전의 높이 설정
	GetCapsuleComponent()->SetCapsuleHalfHeight(113.558517f);
	//콜리전의 지름 설정
	GetCapsuleComponent()->SetCapsuleRadius(51.428543f);
}

 

생성자에서 콜리전이 미리 세팅이 되도록 작성하였다.

해당 C++는 캐릭터를 부모로 하여 만들었기에 블루프린트로 만들면 캡슐 콜리전이 이미 만들어져 있다.

GetCapsuleComponent는 이미 만들어진 캡슐 콜리전을 가져오기 위해 작성한다.

SetCollisionProfileName(FName("Enemy"))를 사용해서 프리셋을 적용 시킨다. Enemy 는 자신이 만든 프리셋 이름을 똑같이 적어주면 된다.

OnComponentBeginOverlap.AddDynamic(this, &AMeleeEnemy::OnEnemyOverlap)는 충돌이 일어날 때 실행될 함수를 설정해주는 것이다.

SetCapsuleHalfHeight(113.558517f)는 해당 캡슐 콜리전의 높이를 조절해주는 줄이다.

SetCapsuleRadius(51.428543f)는 해당 캡슐 콜리전의 지름을 조절해준다.

SetCapsuleRadius() 와 SetCapsuleHalfHeight()는 블루프린트에서 미리 알맞는 크기를 찾아본 다음 설정하는 것이 편하다.

 

MeleeEnemy.h

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

 

헤더에서 충돌이 일어날 때 실행될 함수를 작성하였다. 나는 Delegate로 연결하여서 사용하는 방법을 사용했다. 이때 원래 이벤트에서 사용하는 것과 파라미터의 내용이 완전히 동일해야 한다.

그러면 원래 이벤트의 파라미터를 알아야 하는데 찾는 방법은 다음과 같다.

 

OnComponentBeginOverlap을 우클릭하여 선언으로 이동을 눌러준다. 그러면 다른 스크립트가 나온다.

해당 스크립트에서 위로 올려보면 위와 같은 코드가 있다. 만약 찾기 힘들다면 Ctrl + F로 찾아주자.

여러 매개변수가 있는데 빨강색으로 표시해둔 부분을 복사하자.

 

그 후 작성한 함수에 매개변수에 붙여놓기를 해준다.

주의점은 UFUNCTION()을 작성하여 해당 함수가 호출될 수 있다.

그리고 붙여놓으면 ,로 인해 오류줄이 생성될텐데 ,를 없애주자. 파악하기 어렵다면 위 사진과 같이 만들어주자.

그 다음 cpp에서 함수가 호출될 때 어떠한 동작이 이루어질지 작성하자.

 

MeleeEnemy.cpp

void AMeleeEnemy::OnEnemyOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	ADestiny2Projectile* bullet = Cast<ADestiny2Projectile>(OtherActor);

	if (bullet)
	{
		GetDamage(20.0f);

		bullet->Destroy();
	}
}

 

ADestiny2Projectile* bullet = Cast<ADestiny2Projectile>(OtherActor) 로 캐스트를 한다. 만약에 ADestiny2Projectile이 아닐 경우 bullet에는 null의 값이 들어가진다.

그 다음 if문을 사용하여 bullet이 참일 경우(값이 있을 경우) 조건문 안의 코드가 동작되도록 만들었다.

나의 경우는 에너미의 GetDamge() 함수를 호출하여 체력 감소가 일어나도록 만들었다. 각자 자신에게 맞는 코드를 작성하면 될 것이다.

이후 bullet이 파괴되도록 만들었다.

 

 

 

이렇게 코드를 작성한 다음 언리얼 엔진을 실행하였다.

 

 

블루프린트에서 콜리전 설정을 보니 내가 작성한 코드와 똑같이 설정이 되어있다.

 

이러한 방식으로 콜리전의 세팅을 C++코드로 설정을 할 수 있다. 똑같이 다른 에너미에도 콜리전을 세팅해주자.