I made a door with a single static mesh component that will open when colliding with the player.
The door class codes are as below:
header file
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "Components/StaticMeshComponent.h"
#include "TimerManager.h"
#include "FPSCharacter.h"
#include "Engine/Engine.h"
#include "Door.generated.h"
UCLASS()
class CPPTESTPROJECT_API ADoor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ADoor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// a static mesh component
UPROPERTY(VisibleAnyWhere)
UStaticMeshComponent *DoorMeshComponent;
// a timer handle
FTimerHandle DoorTimerHandle;
// An event that rotates the door open
void DoorOpen();
// An event that closes the door
void DoorClose();
// Function called when the projectile hits something
UFUNCTION()
void OnHit(UPrimitiveComponent *HitComponent, AActor *OtherActor, UPrimitiveComponent *OtherComponent, FVector NormalImpulse, const FHitResult &Hit);
};
cpp file
// Fill out your copyright notice in the Description page of Project Settings.
#include "Door.h"
// Sets default values
ADoor::ADoor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
DoorMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMeshComponent"));
RootComponent = DoorMeshComponent;
}
// Called when the game starts or when spawned
void ADoor::BeginPlay()
{
Super::BeginPlay();
DoorMeshComponent->OnComponentHit.AddDynamic(this, &ADoor::OnHit);
}
// Called every frame
void ADoor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ADoor::DoorOpen()
{
// Set a timer
GetWorldTimerManager().SetTimer(DoorTimerHandle, this, &ADoor::DoorClose, 3.0f, false);
// Rotate the door
SetActorRotation(FRotator(0.f, 90.f, 0.f));
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Collision Happened"));
}
}
void ADoor::DoorClose()
{
// Clear timer
GetWorldTimerManager().ClearTimer(DoorTimerHandle);
SetActorRotation(FRotator(0.f, 0.f, 0.f));
}
void ADoor::OnHit(UPrimitiveComponent * HitComponent, AActor * OtherActor, UPrimitiveComponent * OtherComponent, FVector NormalImpulse, const FHitResult & Hit)
{
if (OtherActor !=this && OtherActor->IsA(AFPSCharacter::StaticClass()))
{
DoorOpen();
}
}
The bp extended from this class is like this:
as you can see Simulation generates hit events is ticked off. However, the instance generated from this bp class still fires off its OnComponentHit event in the world.
What’s the problem here?