블루프린트 없이 100% C++ 코드로만 엘리베이터를 만들어보았다.
지난번에 만든 C++ 문의 코드를 응용했다.
https://velog.io/@woojoo0407/C-문-만들기
CapsuleCollision에 Overlap시 OnOverlapBegin과 OnOverlapEnd 함수를 바인딩했다.
Tick 함수에서 변수(bIsOverlaped, CurrentPlatformHeight, MaxPlatformHeight)를 체크해서 OpenDoor, CloseDoor 함수로 분기되게 만들었다.
RaisePlatform, LowerPlatform 함수에서 DeltaTime을 받아 문의 각도를 조절했다.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/CapsuleComponent.h"
#include "Elevator.generated.h"
UCLASS()
class DOORCPP_API AElevator : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AElevator();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Elevator")
UStaticMeshComponent* Button;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Elevator")
UStaticMeshComponent* Platform;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Elevator")
UCapsuleComponent* CapsuleCollision;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Elevator")
float MaxPlatformHeight = 500.f;
bool bIsOverlaped = false;
float CurrentPlatformHeight = 0.f;
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 OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION()
void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
UFUNCTION()
void RaisePlatform(float DeltaTime);
UFUNCTION()
void LowerPlatform(float DeltaTime);
};
#include "Elevator.h"
// Sets default values
AElevator::AElevator()
{
// 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;
Platform = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Platform"));
Platform->SetRelativeScale3D(FVector(3.f, 3.f, 3.f));
RootComponent = Platform;
CapsuleCollision = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleCollision"));
CapsuleCollision->InitCapsuleSize(15.f, 30.0f);
CapsuleCollision->SetupAttachment(RootComponent);
Button = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Button"));
Button->SetRelativeLocation(FVector(0.f, 0.f, 5.f));
Button->SetRelativeScale3D(FVector(0.3f, 0.3f, 0.1f));
Button->SetupAttachment(CapsuleCollision);
static ConstructorHelpers::FObjectFinder<UStaticMesh>ButtonSM(TEXT("'/Game/LevelPrototyping/Meshes/SM_Cylinder.SM_Cylinder'"));
if (ButtonSM.Succeeded())
{
Button->SetStaticMesh(ButtonSM.Object);
}
static ConstructorHelpers::FObjectFinder<UStaticMesh>PlatformSM(TEXT("'/Game/StarterContent/Architecture/SM_AssetPlatform.SM_AssetPlatform'"));
if (PlatformSM.Succeeded())
{
Platform->SetStaticMesh(PlatformSM.Object);
}
}
// Called when the game starts or when spawned
void AElevator::BeginPlay()
{
Super::BeginPlay();
CapsuleCollision->OnComponentBeginOverlap.AddDynamic(this, &AElevator::OnOverlapBegin);
CapsuleCollision->OnComponentEndOverlap.AddDynamic(this, &AElevator::OnOverlapEnd);
}
// Called every frame
void AElevator::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!bIsOverlaped && CurrentPlatformHeight == 0.f)
{
return;
}
else if (bIsOverlaped)
{
RaisePlatform(DeltaTime);
}
else
{
LowerPlatform(DeltaTime);
}
}
void AElevator::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor != nullptr && OtherActor != this && OtherComp != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Overlap Begin"));
bIsOverlaped = true;
}
}
void AElevator::OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
if (OtherActor != nullptr && OtherActor != this && OtherComp != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Overlap End"));
bIsOverlaped = false;
}
}
void AElevator::RaisePlatform(float DeltaTime)
{
if (CurrentPlatformHeight <= MaxPlatformHeight)
{
FVector NewRocation = FVector(0.f, 0.f, DeltaTime * 100);
Platform->AddRelativeLocation(NewRocation);
CurrentPlatformHeight = Platform->GetRelativeLocation().Z;
}
}
void AElevator::LowerPlatform(float DeltaTime)
{
if (CurrentPlatformHeight >= 0.f)
{
FVector NewRocation = FVector(0.f, 0.f, -DeltaTime * 100);
Platform->AddRelativeLocation(NewRocation);
CurrentPlatformHeight = Platform->GetRelativeLocation().Z;
}
}