Unreal

[Unreal 4] 오브젝트 충돌 감지 - C++

TIM_0529 2023. 1. 15. 16:05
반응형

오브젝트 충돌감지 기능은 게임 개발에 전반적인 부분에서 사용이 되는것으로 보입니다.

캐릭터 충돌로 감지로 음악 재생, 물건 습득, 피격 판정 등등... 

 

알아두면 매우 중요한 개념이고, 또한 언리얼에서 구현하기도 크게 어렵지 않았습니다.

C++ 클래스를 하나 만들고 액터를 상속받고 이름은 Item 으로 합니다.

헤더파일에 다음을 추가합니다.

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Item.generated.h"

UCLASS()
class MINIMAL_DEFAULT_API AItem : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AItem();

	/** Base Shape Collision */
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category= "Item | Collision")
	class USphereComponent* CollisionVolume;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;

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

USphereComponent  클래스를 포인터로 생성합니다.

CollisionVolume 이 콜라이더라고 생각하면 됩니다.

 

다음으로 UFUNCTION() 으로 선언된 두가지 함수가 있습니다. 

 

UFUNCTION()에 대해서는 다음을 참고해 주세요

UFunction 은 특수 문법을 사용해서 함수 지정자 를 통해 선언에 함수 관련 추가 정보를 지정합니다.

 

UFunction

게임플레이 클래스용 함수 생성 및 구현 레퍼런스입니다.

docs.unrealengine.com

 

 

OnOverlapBegin 은 이름처럼 충돌이 시작이 되었을 때 한 번 출력이 됩니다.

 

OnOVerlapEnd 는 충돌이 종료될 때 한 번 출력이 됩니다.

 

다음은 CPP 파일에서 함수를 정의하겠습니다.

 

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


#include "Item.h"
#include "Components/SphereComponent.h"

// Sets default values
AItem::AItem()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CollisionVolume = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionVolume"));
	RootComponent = CollisionVolume;

}

// Called when the game starts or when spawned
void AItem::BeginPlay()
{
	Super::BeginPlay();
	CollisionVolume->OnComponentBeginOverlap.AddDynamic(this, &AItem::OnOverlapBegin);
	CollisionVolume->OnComponentEndOverlap.AddDynamic(this, &AItem::OnOverlapEnd);

}

// Called every frame
void AItem::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void AItem::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Warning, TEXT("Super::OnOverlapBegin()"));
}
void AItem::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	UE_LOG(LogTemp, Warning, TEXT("Super::OnOverlapEnd()"));
}

 

 

CollisionVolume 에 USphereComponent 를 초기화 해줍니다. ( #include "Components/SphereComponent.h" ) 선언

루트 컴포넌트를 CollisionVolume으로 지정합니다.

 

게임이 시작될 때

헬퍼 매키로 ( AddDynamic)을 사용해서 다이내믹 매크로 바인딩을 해 줍니다.

매개변수로는 AddDynamic( UserObject, FuncName ) 이 있습니다. 다음을 참고해 주세요

https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Dynamic/

 

다이내믹 델리게이트

serialize 가능하면서 리플렉션도 지원하는 델리게이트입니다.

docs.unrealengine.com

인자값을 무엇을 줘야 하는지 외우기 어려움으로 직접 매개변수를 확인하여 전달하는 방법이 있습니다.

정의를 피킹하여 확하고 매개변수를 선언합니다.

CollisionVolume->OnComponentBeginOverlap.AddDynamic(this, &AItem::OnOverlapBegin); 

이 줄에서 OnComponentBeginOverlap 에 마우스 우클릭 정의 피킹 또는 ( F12 + Alt)

그 다음 FComponentBeginOverlapSignature 에서 우클릭 정의 피킹 또는 ( F12 + Alt) 

그러면 

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams 라는 함수가 있습니다.

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);

이 함수에 매개변수 UPrimitiveComponent* 부터 끝까지 복사하여 OnOverlapBegin의 매개변수로 설정합니다.

OnOverlapEnd 도 같은 과정을 해 줍니다.

 

 

 

OnOverlapBegin 과 OnOverlapEnd 함수에 로그를 찍어서 잘 작동하는 지 확인해 봅니다.

로그에서 Super:: 를 사용한 이유는 이 클래스를 상속받는 두 개의 다른 클래스를 만들어서 입니다.  Super 는 없어도 됩니다.

 

 

반응형