0. 개요

이제 게임 인스턴스와 저장 데이터, 저장 슬롯에서 플레이어 스타트를 저장하여 플레이어의 마지막 위치를 기억할 수 있게 되었다.

이를 이용하여 체크포인트에 도달하면 해당 지점에서 게임을 다시 시작할 수 있도록 체크포인트 액터를 만든다.

 

 

1. 플레이어 스타트를 상속받는 체크포인트 액터

(1) C++ 클래스 생성

PlayerStartTag를 활용하기 위하여 플레이어 스타트를 상속받는다.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerStart.h"
#include "CheckPoint.generated.h"

class USphereComponent;

UCLASS()
class AURA_API ACheckPoint : public APlayerStart
{
	GENERATED_BODY()
	
public:
	ACheckPoint(const FObjectInitializer& ObjectInitializer);

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

	virtual void BeginPlay() override;

private:
	UPROPERTY(VisibleAnywhere)
	TObjectPtr<UStaticMeshComponent> CheckpointMesh;

	UPROPERTY(VisibleAnywhere)
	TObjectPtr<USphereComponent> Sphere;
};

이 액터는 스태틱 매시와 겹침을 판정하기 위한 스피어 컴포넌트가 있다.

 

(2) 생성자에서 컴포넌트 구성

ACheckPoint::ACheckPoint(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	PrimaryActorTick.bCanEverTick = false;

	CheckpointMesh = CreateDefaultSubobject<UStaticMeshComponent>("CheckpointMesh");
	CheckpointMesh->SetupAttachment(GetRootComponent());
	CheckpointMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
	CheckpointMesh->SetCollisionResponseToAllChannels(ECR_Block);

	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
	Sphere->SetupAttachment(CheckpointMesh);
	Sphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	Sphere->SetCollisionResponseToAllChannels(ECR_Ignore);
	Sphere->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
}

스피어에 대해 겹침을 판정할 것이므로 위와 같이 콜리전 세팅을 한다.

 

(3) 오버랩 콜백 함수 바인딩

void ACheckPoint::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{

}

void ACheckPoint::BeginPlay()
{
	Super::BeginPlay();

	Sphere->OnComponentBeginOverlap.AddDynamic(this, &ACheckPoint::OnSphereOverlap);
}

BeginPlay를 오버라이드하여 콜백 함수를 바인딩한다.

 

한편, 체크포인트의 머티리얼 인스턴스를 살펴보면 Glow 매개 변수가 있어 이를 조정할 수 있게 되어있다.

해당 변수를 포함한 여러 변수를 선언하여 체크포인트에 도달하면 이펙트가 발생하도록 할 것이다.

 

 

2. 체크 포인트 액터

틱을 false로 만들었기 때문에 타임라인을 활용할 수 있다.

 

(1) 오버랩 콜백 함수

void ACheckPoint::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OtherActor->ActorHasTag(FName("Player")))
	{
		HandleGlowEffects();
	}
}

플레이어와 겹치면 이펙트를 활성화한다.

 

 

(2) 이펙트 발생 함수에서 동적 머티리얼 인스턴스 생성 및 전달

	UFUNCTION(BlueprintImplementableEvent)
	void CheckPointReached(UMaterialInstanceDynamic* DynamicMI);

	void HandleGlowEffects();
void ACheckPoint::HandleGlowEffects()
{
	// 콜리전 끄기
	Sphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);

	// 동적 머티리얼 인스턴스 생성
	UMaterialInstanceDynamic* DynamicMI = UMaterialInstanceDynamic::Create(CheckpointMesh->GetMaterial(0), this);

	// 머티리얼을 동적 머티리얼 인스턴스로 설정
	CheckpointMesh->SetMaterial(0, DynamicMI);

	// 블루프린트 함수 호출
	CheckPointReached(DynamicMI);
}

HandleGlowEffects 함수에서 체크포인트 메시의 머티리얼을 동적 머티리얼 인스턴스로 생성하여 설정한다.

이후에 블루프린트 정의 가능 함수로 동적 머티리얼 인스턴스를 넘겨준다.

 

 

(3) BP_Checkpoint 구성

체크 포인트 메시를 지정한다.

- 플레이어 스타트에서 다른 컴포넌트들이 약간 떨어져있게 만들어서, 캐릭터가 플레이어 스타트에 소환되면 겹치지 않도록 조정한다.

- 배치할 때 용이하게 하기 위해 플레이어 스타트의 바닥을 메시의 바닥과 일치시킨다.

 

 

(4) BP_Checkpoint에서 블루프린트 정의 가능 함수

해당 액터와 플레이어 캐릭터가 닿으면 타임라인에 따라 값이 변화하고, 해당 값에 따라 동적 머티리얼 인스턴스의 파라미터가 변화하도록 지정한다.