Full OpenDoor code.
OpenDoor.cpp
// Copyright Douglas Taggart 5/2020
#include "OpenDoor.h"
#include "Components/AudioComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Components/PrimitiveComponent.h"
#include "Engine/World.h"
#include "GameFramework/Actor.h"
#include "GameFramework/PlayerController.h"
// Sets default values for this component's properties
UOpenDoor::UOpenDoor()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void UOpenDoor::BeginPlay()
{
Super::BeginPlay();
if(!UseLeftDoor)
{
InitialYaw = GetOwner()->GetActorRotation().Yaw;
} else
{
// get the right components to use for LeftDoor
TArray<UStaticMeshComponent*> components;
GetOwner()->GetComponents(components);
for (int32 i = 0; i < components.Num(); i++)
{
UE_LOG(LogTemp, Warning, TEXT("%i: component is included on this object, mesh name %s."), i, *components[i]->GetName());
if(components[i]->GetName().Equals("Metal_Door_Left"))
{
LeftDoor = components[i];
UE_LOG(LogTemp, Warning, TEXT("LeftDoor has been assigned to %s."), *LeftDoor->GetName())
//LeftDoor->AttachToComponent();
}
}
InitialYaw = LeftDoor->GetComponentRotation().Yaw;
// AActor* LeftDoor =
}
CurrentYaw = InitialYaw;
TargetYaw = InitialYaw + TargetYaw;
CheckPressurePlateSet();
FindAudioComponent();
}
void UOpenDoor::CheckPressurePlateSet() const
{
if(!PressurePlate)
{
UE_LOG(LogTemp, Error, TEXT("%s has the OpenDoor component on it, but no PressurePlate set."), *GetOwner()->GetName());
}
}
// Called every frame
void UOpenDoor::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (TotalMassOfActors() > MassRequiredToOpenDoor)
{
if(LeftDoor)
{
OpenLeftDoor(DeltaTime);
}
else
{
OpenDoor(DeltaTime);
}
DoorLastOpened = GetWorld()->GetTimeSeconds();
}
else
{
if ((GetWorld()->GetTimeSeconds() - DoorLastOpened) >= DoorCloseDelay)
{
if(LeftDoor)
{
CloseLeftDoor(DeltaTime);
}
else
{
CloseDoor(DeltaTime);
}
}
}
}
void UOpenDoor::OpenDoor(float DeltaTime)
{
FRotator CurrentRotation = GetOwner()->GetActorRotation();
CurrentRotation.Yaw = FMath::FInterpConstantTo(CurrentRotation.Yaw, TargetYaw, DeltaTime, DoorOpenSpeed);
GetOwner()->SetActorRotation(CurrentRotation);
CloseDoorSound = false;
if(!AudioComponent){return;}
if (!OpenDoorSound)
{
AudioComponent->Play();
OpenDoorSound = true;
}
}
void UOpenDoor::OpenLeftDoor(float DeltaTime)
{
FRotator CurrentRotation = LeftDoor->GetComponentRotation();
UE_LOG(LogTemp, Warning, TEXT("I'm in OpenLeftDoor executing."));
CurrentRotation.Yaw = FMath::FInterpConstantTo(CurrentRotation.Yaw, TargetYaw, DeltaTime, DoorOpenSpeed);
LeftDoor->SetWorldRotation(CurrentRotation);
CloseDoorSound = false;
if(!AudioComponent){return;}
if (!OpenDoorSound)
{
AudioComponent->Play();
OpenDoorSound = true;
}
}
void UOpenDoor::CloseDoor(float DeltaTime)
{
FRotator CurrentRotation = GetOwner()->GetActorRotation();
CurrentRotation.Yaw = FMath::FInterpConstantTo(CurrentRotation.Yaw, InitialYaw, DeltaTime, DoorOpenSpeed);
GetOwner()->SetActorRotation(CurrentRotation);
OpenDoorSound = false;
if (!AudioComponent){return;}
if (!CloseDoorSound)
{
AudioComponent->Play();
CloseDoorSound = true;
}
}
void UOpenDoor::CloseLeftDoor(float DeltaTime)
{
FRotator CurrentRotation = LeftDoor->GetComponentRotation();
CurrentRotation.Yaw = FMath::FInterpConstantTo(CurrentRotation.Yaw, InitialYaw, DeltaTime, DoorOpenSpeed);
LeftDoor->SetWorldRotation(CurrentRotation);
// GetOwner()->SetActorRotation(CurrentRotation);
OpenDoorSound = false;
if (!AudioComponent){return;}
if (!CloseDoorSound)
{
AudioComponent->Play();
CloseDoorSound = true;
}
}
void UOpenDoor::FindAudioComponent()
{
AudioComponent = GetOwner()->FindComponentByClass<UAudioComponent>();
if(!AudioComponent)
{
UE_LOG(LogTemp, Error, TEXT("%s missing audio component!"), *GetOwner()->GetName());
}
}
float UOpenDoor::TotalMassOfActors() const
{
float TotalMass = 0.f;
// Find all overlapping actors
TArray<AActor*> OverlappingActors;
if(!PressurePlate){return TotalMass;}
PressurePlate->GetOverlappingActors(OverlappingActors);
for (AActor* Actor : OverlappingActors)
{
TotalMass += Actor->FindComponentByClass<UPrimitiveComponent>()->GetMass();
}
// Add up their masses.
return TotalMass;
}
OpenDoor.h
// Copyright Douglas Taggart 5/2020
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Components/AudioComponent.h"
#include "Engine/TriggerVolume.h"
#include "OpenDoor.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class BUILDINGESCAPE_API UOpenDoor : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UOpenDoor();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void OpenDoor(float DeltaTime);
void CloseDoor(float DeltaTime);
float TotalMassOfActors() const;
void FindAudioComponent();
void OpenLeftDoor(float DeltaTime);
void CloseLeftDoor(float DeltaTime);
// Tracks whether sound has been played
bool OpenDoorSound = false;
bool CloseDoorSound = true;
private:
void CheckPressurePlateSet() const;
float InitialYaw;
float CurrentYaw;
float DoorLastOpened = 0.f;
UStaticMeshComponent* LeftDoor = nullptr;
UPROPERTY(EditAnywhere)
float TargetYaw = -90.f;
UPROPERTY(EditAnywhere)
float DoorOpenSpeed = 10.0f;
UPROPERTY(EditAnywhere)
ATriggerVolume* PressurePlate = nullptr;
UPROPERTY(EditAnywhere)
float DoorCloseDelay = 2.f;
UPROPERTY(EditAnywhere)
float MassRequiredToOpenDoor = 50.f;
UPROPERTY(EditAnywhere)
bool UseLeftDoor = false;
UPROPERTY(EditAnywhere)
UAudioComponent* AudioComponent = nullptr;
};