블루프린트 없이 100% C++ 코드로만 문을 만들어보았다.
BoxCollision에 Overlap시 OnOverlapBegin과 OnOverlapEnd 함수를 바인딩했다.
Tick 함수에서 변수(DoorCurrentRotation, bIsOverlaped, bIsOverlaped)를 체크해서 OpenDoor, CloseDoor 함수로 분기되게 만들었다.
OpenDoor, CloseDoor 함수에서 DeltaTime을 받아 문의 각도를 조절했다.
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "Door2.generated.h"
UCLASS()
class DOORCPP_API ADoor2 : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ADoor2();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
UStaticMeshComponent* Door;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
UStaticMeshComponent* Frame;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
UBoxComponent* BoxCollision;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
float MaxDoorAngle = 90.f;
bool bIsOverlaped = false;
float DoorCurrentRotation = 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 OpenDoor(float DeltaTime);
UFUNCTION()
void CloseDoor(float DeltaTime);
};
#include "Door2.h"
// Sets default values
ADoor2::ADoor2()
{
// 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"));
BoxCollision->InitBoxExtent(FVector(150.f, 100.f, 100.f));
RootComponent = BoxCollision;
Frame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Frame"));
Frame->SetRelativeLocation(FVector(0.f, 0.f, -100.f));
Frame->SetupAttachment(RootComponent);
Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Door"));
Door->SetRelativeLocation(FVector(0.f, 45.f, -100.f));
Door->SetupAttachment(RootComponent);
static ConstructorHelpers::FObjectFinder<UStaticMesh>DoorSM(TEXT("'/Game/StarterContent/Props/SM_Door.SM_Door'"));
if (DoorSM.Succeeded())
{
Door->SetStaticMesh(DoorSM.Object);
}
static ConstructorHelpers::FObjectFinder<UStaticMesh>FrameSM(TEXT("'/Game/StarterContent/Props/SM_DoorFrame.SM_DoorFrame'"));
if (FrameSM.Succeeded())
{
Frame->SetStaticMesh(FrameSM.Object);
}
}
// Called when the game starts or when spawned
void ADoor2::BeginPlay()
{
Super::BeginPlay();
BoxCollision->OnComponentBeginOverlap.AddDynamic(this, &ADoor2::OnOverlapBegin);
BoxCollision->OnComponentEndOverlap.AddDynamic(this, &ADoor2::OnOverlapEnd);
}
// Called every frame
void ADoor2::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
UE_LOG(LogTemp, Warning, TEXT("bIsOverlaped : %s"), bIsOverlaped ? TEXT("true") : TEXT("false"));
UE_LOG(LogTemp, Warning, TEXT("DoorCurrentRotation : %f"), DoorCurrentRotation);
if (!bIsOverlaped && DoorCurrentRotation == 0.f)
{
return;
}
else if (bIsOverlaped)
{
OpenDoor(DeltaTime);
}
else
{
CloseDoor(DeltaTime);
}
}
void ADoor2::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 ADoor2::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 ADoor2::OpenDoor(float DeltaTime)
{
if (DoorCurrentRotation <= MaxDoorAngle)
{
FRotator NewRotation = FRotator(0.f, DeltaTime * 80, 0.f);
Door->AddRelativeRotation(NewRotation);
DoorCurrentRotation = Door->GetRelativeRotation().Yaw;
}
}
void ADoor2::CloseDoor(float DeltaTime)
{
if (DoorCurrentRotation >= 0.f)
{
FRotator NewRotation = FRotator(0.f, -DeltaTime * 80, 0.f);
Door->AddRelativeRotation(NewRotation);
DoorCurrentRotation = Door->GetRelativeRotation().Yaw;
}
}