[BP & C++] 문 업그레이드하기

Woogle·2022년 9월 11일
0

언리얼 엔진 5

목록 보기
15/59
post-thumbnail

기존에 만들었던 C++, BP 문을 개선해보았다.
https://velog.io/@woojoo0407/C-문-만들기

  • 기존의 BeginOverlap, EndOverlap 대신 LineTrace를 써서 E 버튼을 눌러야 문이 열린다.
  • 문이 부드럽게 열린다. (Timeline, FloatCurve)
  • 블루프린트를 최소한으로 활용하였다. (Mesh, FloatCurve, Collision 설정)

1. 캐릭터

  • 언리얼 삼인칭 템플릿 캐릭터에 Interact 함수, InteractLineTraceLength 변수 추가
  • 플레이어가 Line Trace하면 문이 OnInteract 메소드를 호출하게 만들었다.

📄 헤더 파일

	void Interact();						// 추가 함수

	UPROPERTY(EditAnywhere)
	float InteractLineTraceLength = 350.f;	// 추가 변수

📄 소스 파일

void ADoorCppCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
	// ......
	PlayerInputComponent->BindAction("Interact", IE_Pressed, this, &ADoorCppCharacter::Interact);	
	// ......
}

void ADoorCppCharacter::Interact()
{
	if (FollowCamera == nullptr)
		return;

	FHitResult HitResult;
	FVector Start = GetActorLocation();
	FVector End = Start + GetActorForwardVector() * InteractLineTraceLength;
	GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECollisionChannel::ECC_Visibility);

	ADoor_Cpp* Door = Cast<ADoor_Cpp>(HitResult.GetActor());
	if (Door)
	{
		Door->OnInteract();		// 문의 메소드를 호출
	}
}

2. 문

  • 문이 OnInteract 메소드 호출 시, Timeline과 Float Curve로 문이 부드럽게 열리게 수정했다.

📄 헤더 파일

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GameFramework/Character.h"
#include "Components/TimelineComponent.h"
#include "Components/BoxComponent.h"
#include "Door_Cpp.generated.h"

UCLASS()
class DOORCPP_API ADoor_Cpp : public AActor
{
	GENERATED_BODY()

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
	UBoxComponent* BoxCollision;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
	UStaticMeshComponent* Door;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
	UStaticMeshComponent* Frame;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
	float DoorRotateAngle = 90.f;		// 문의 최대 회전 각도

	UPROPERTY(EditAnywhere)
	FTimeline Timeline;					// Timeline 생성

	UPROPERTY(EditAnywhere)
	UCurveFloat* CurveFloat;			// Timeline 커브

	bool bIsDoorClosed = true;

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

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

	UFUNCTION()
	void OnInteract();				// 캐릭터의 LineTrace를 받는 메소드

	UFUNCTION()
	void OpenDoor(float Value);		// Bind function
};

📄 소스 파일

#include "Door_Cpp.h"		// 추가 헤더

// Sets default values
ADoor_Cpp::ADoor_Cpp()
{
	// 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;

	BoxCollision = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxCollision"));
	Frame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Frame"));
	Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Door"));

	RootComponent = BoxCollision;
	Frame->SetupAttachment(RootComponent);
	Door->SetupAttachment(RootComponent);
}

// Called when the game starts or when spawned
void ADoor_Cpp::BeginPlay()
{
	Super::BeginPlay();

	if (CurveFloat)			// Timeline에 OpenDoor 함수를 바인딩
	{
		FOnTimelineFloat TimelineProgress;
		TimelineProgress.BindDynamic(this, &ADoor_Cpp::OpenDoor);
		Timeline.AddInterpFloat(CurveFloat, TimelineProgress);
	}
}

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

	Timeline.TickTimeline(DeltaTime);	// Timeline에 DeltaTime을 적용

}

void ADoor_Cpp::OpenDoor(float Value)
{
	FRotator Rot = FRotator(0.f, DoorRotateAngle * Value, 0.f);

	Door->SetRelativeRotation(Rot);
}

void ADoor_Cpp::OnInteract()
{
	UE_LOG(LogTemp, Warning, TEXT("Interact!"));

	if (bIsDoorClosed)
	{
		UE_LOG(LogTemp, Warning, TEXT("Open!"));
		Timeline.Play();	// Open the door
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("Close!"));
		Timeline.Reverse();	// Close the door
	}

	bIsDoorClosed = !bIsDoorClosed;	// Flip flop
}

3. 블루프린트

  • 콜리전 설정 (BoxCollision)
  • Curve Float 설정


참고자료

profile
노력하는 게임 개발자

0개의 댓글