본문 바로가기

게임프로그래밍/실습1

[언리얼 실습] 41. C++에서 액터 스폰하기 & 부서진 액터랑 충돌방지


목차

  1. UClass로 설정한 액터 스폰하기
  2. TSubclassOf 사용하기
  3. 부서진 액터랑 충돌방지

1. UClass 액터 스폰하기

 

항아리를 부시면 보물이 나오게 할 것이다. 그러기 위해서 액터를 스폰할 줄 알아야한다.

 

BreakableActor 클래스에 GetHit 함수가 있다. 부실 수 있는 액터가 부셔지면 스폰을 해야하니 여기서 액터를 스폰해보자.

 

함수를 쓰면 7개나 되는 오버로드된 함수들을 볼 수 있다. 여기서 2번째 버전을 사용하려고 한다. (참고로 현재 비주얼스튜디오 2022를 사용하고 있다.)

 

SpawnActor는 탬플릿 함수이기 때문에 타입 지정이 필요하다. 타입지정을 어떻게 해야할까? 단순히 ATreasure라고 지정하면 블루프린트 클래스가 아닌 C++ 클래스 타입이 생성되고 이것은 우리가 원하는 것이 아니다.

 

올바른 클래스를 지정하기 위해서는 블루프린트 클래스를 저장할 포인터가 필요하다. 일단 지금은 UClass 타입을 써보려고 한다.

 

private:
	UPROPERTY(VisibleAnywhere)
	class UGeometryCollectionComponent* GeometryCollection;

	UPROPERTY(EditAnywhere)
	UClass* TreasureClass;

 

이제 에티터에서 원하는 클래스로 할당해주면 된다. 스폰할 액터를 선택하는 법도 알았으니 실제로 생성을 해보자.

 

void ABreakableActor::GetHit_Implementation(const FVector& ImpactPoint)
{
	UWorld* World = GetWorld();
	if (World && TreasureClass)
	{
		FVector Location = GetActorLocation();
		Location.Z += 75.f;
		World->SpawnActor<ATreasure>(TreasureClass, Location, GetActorRotation());
	}
}

 

첫번째 매개변수는 생성할 액터 클래스,

두번째 매개변수는 생성할 위치 (부서지는 액터 클래스의 높이에서 75를 더한 위치)

세번째 매개변수는 회전이다.

네번째 매개변수는 기본값을 사용하였다.

 

이렇게 하면 액터를 무사히 소환할 수 있다.

 

컴파일하고 확인해보자,

 

중요한 점은 블루프린트에서 설정을 해줘야한다는 것이다. 이때 한가지 문제점이 발생한다.

 

 

UClass 타입으로 지정해서 모든 클래스가 나온다는 것이다. 이 경우 실수로 잘못된 클래스를 선택할 위험이 있다. 우리가 원하는 클래스만 나오게 하고 싶다. 그럴려면 어떻게 해야할까?


2. TSubclassOf 사용하기
TSubclassOf 는 언리얼 엔진에서 특정 클래스 또는 그 클래스를 상속받은 서브클래스 타입을 참조할 수 있게 하는 템플릿 클래스입니다. - ChatGPT

 

TSubclassOf  로 타입을 지정해 특정 클래스만 사용하게 할 것이다.

 

UPROPERTY(EditAnywhere)
TSubclassOf<class ATreasure> TreasureClass;

 

이제 타입을 이렇게 바꿔보자.

 

 

이제 블루프린트에서 우리가 원하는 타입의 클래스만 지정할 수 있는 것을 볼 수 있다.


3. 부서진 액터랑 충돌방지

 

현재 박살이난 항아리랑 캐릭터가 충돌하여 카메라가 흔들리는 등 문제가 발생한다. 액터가 부서지면 더이상 캐릭터와 충돌을 하지 않게 바꿀 것이다.

 

ABreakableActor::ABreakableActor()
{
// 생략
  GeometryCollection->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
}

 

생성자로 가서 카메라의 충돌을 없앴던 것처럼 폰과의 충돌도 없애자.

 

이렇게 하면 이제 부서진 액터와 충돌을 하지는 않지만 부저지지 않아도 충돌을 하지 않을 것이다. 이부분을 막을 필요가 있다.

 

캡슐을 이용해 이를 막아보려고 한다.

 

// ABreakableActor 클래스

protected:
	virtual void BeginPlay() override;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	class UGeometryCollectionComponent* GeometryCollection;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	class UCapsuleComponent* Capsule;
ABreakableActor::ABreakableActor()
{
 // 생략
 
 Capsule = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
 Capsule->SetupAttachment(GetRootComponent());
 Capsule->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
 Capsule->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Block);

}

 

이제 컴파일하고 블루프린트로 들어가 캡슐의 사이즈를 조절하자.

 

 

이제 이 캡슐을 액터가 부서지면 사라지게 해야한다. 이 작업은 블루프린트의 이벤트 그래프에서 하도록 하자.

 

 

 

이렇게 액터가 사라질때 콜리전도 사라지게 하면 된다.

 

이렇게 하면 이제 콜리전 설정이 완료된다.


추가사항

 

콜리전 설정을 해도 지오메트리 컬렉션에 카메라와 폰에 대한 콜리전 설정이 제대로 되지 않는다.

 

 

에디터에서 직접 설정하도록 하자. 원인이 무엇인지는 모르겠다.