Can't protect individual pointer

Hi guys,

I’m having a little trouble with one of my scripts that have gone a little beyond the course specifics and is requiring me to run a check on multiple pointers. Currently, all of my checks work fine for 5 of the 6 pointers. However, the last actor “SilverActor” won’t check and crashes the program anytime I try to run with it missing. I’ve tried multiple solutions and can’t seem to figure out what’s different. Does anybody have any ideas what I might be doing wrong?

#include "GlassDoorPuzzle.h"
#include "Engine/World.h"
#include "GameFramework/PlayerController.h"
#include "Runtime/Engine/Classes/Components/PrimitiveComponent.h"
#include "Runtime/Engine/Classes/GameFramework/Actor.h"

#define OUT

// Sets default values for this component's properties
UGlassDoorPuzzle::UGlassDoorPuzzle()
{
	PrimaryComponentTick.bCanEverTick = true;	
}


// Called when the game starts
void UGlassDoorPuzzle::BeginPlay()
{
	Super::BeginPlay();
	Owner = GetOwner();
	CheckPointers();
}


// Called every frame
void UGlassDoorPuzzle::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// Poll the Trigger Volume
	if (bCheckActorsOnPlate() == true) // TODO Make hardcode into an editable parameter
	{
		OpenDoor();
		LastDoorOpenTime = GetWorld()->GetTimeSeconds();
	}

	if (GetWorld()->GetTimeSeconds() - LastDoorOpenTime > DoorCloseDelay)
	{
		CloseDoor();
	}

	
}

void UGlassDoorPuzzle::OpenDoor()
{
	//FVector StartPosition = GetOwner()->GetActorLocation();
	//FVector NewPosition = StartPosition + FVector(0.0f, -0.1f, 0.0f) * CurrentSpeed;

	Owner->SetActorLocation(EndPosition);
}

void UGlassDoorPuzzle::CloseDoor()
{
	Owner->SetActorLocation(StartPosition);
}


bool UGlassDoorPuzzle::bCheckActorsOnPlate()
{
	// Find all overlapping actors
	TArray<AActor*> OverlappingActors;
	CheckPointersOnPlate();
	CopperPressurePlate->GetOverlappingActors(OUT OverlappingActors);


	// Iterate through them adding their masses
	for (const auto* Actor : OverlappingActors)
	{
		//UE_LOG(LogTemp, Warning, TEXT("%s on pressure plate"), *Actor->GetName())
		if (SilverActor->IsOverlappingActor(CopperPressurePlate) && CopperActor->IsOverlappingActor(GoldPressurePlate) && GoldActor->IsOverlappingActor(SilverPressurePlate))
		{
			// Opens door when true is returned
			return true;
		}
		else
		{
			return false;
		}
		
	}

	return false;
}

void UGlassDoorPuzzle::CheckPointers() // TODO Update to (!ensure(variable)) checks
{
	// Protecting Pointers
	if (!CopperPressurePlate) { UE_LOG(LogTemp, Error, TEXT("%s is missing CopperPressurePlate"), *GetOwner()->GetName()); }
	if (!GoldPressurePlate) { UE_LOG(LogTemp, Error, TEXT("%s is missing GoldPressurePlate"), *GetOwner()->GetName()); }
	if (!SilverPressurePlate) { UE_LOG(LogTemp, Error, TEXT("%s is missing SilverPressurePlate"), *GetOwner()->GetName()); }
	if (!CopperActor) { UE_LOG(LogTemp, Error, TEXT("%s is missing CopperActor"), *GetOwner()->GetName()); }
	if (!GoldActor) { UE_LOG(LogTemp, Error, TEXT("%s is missing GoldActor"), *GetOwner()->GetName()); }
	if (!SilverActor) { UE_LOG(LogTemp, Error, TEXT("%s is missing SilverActor"), *GetOwner()->GetName()); }
}

bool UGlassDoorPuzzle::CheckPointersOnPlate()
{
	// Protecting Pointers
	if (!CopperPressurePlate) { return false; }
	if (!GoldPressurePlate) { return false; }
	if (!SilverPressurePlate) { return false; }
	if (!CopperActor) { return false; }
	if (!GoldActor) { return false; }
	if (!SilverActor) { return false; } // TODO Find out why silver actor cannot be protected
	return false;
}

Some of the code seems to be not included and the line causing the crash isn’t either, etc so I’m not 100% sure of everything happening.

But if its crashing here (looks like the only spot you commented):

if (!SilverActor) { return false; }

the appropriate thing you can do is not treat null or nothing, etc as bool because it is technically not a bool that you should be looking for.

For example: https://blogs.msdn.microsoft.com/ericlippert/2012/03/26/null-is-not-false/

Its good to make sure anything has been initialized before using and before doing bool checks even on bools themselves just to be clear.

If that is what is happening, you gave too little info imo. But its obvious if its crashing on if (!___) then it cannot be used as a bool at that moment.

But If its crashing somewhere else like here then it may be a different problem:

SilverActor->IsOverlappingActor(CopperPressurePlate)

In this case, you may have checked too early and it changed or maybe CopperPressurePlate fails with its use in IsOverlappingActor(), etc.

Thank you for the response. I hope that I am explaining myself well as I am still very new to C++. I’m not entirely sure where the crash is occurring. I believe it is at the (!SilverActor). As I currently have it set up, I can remove all of the AActors and ATriggerVolumes from the component within Unreal and the program will still play and simply print an error message to the output log. All, except for the SilverActor. If I clear this property from the Owners script component menu, the game will immediately crash as soon as I hit play.

Here is the .h file

// Copyright B-Shift Software 2019

#pragma once

#include "CoreMinimal.h"
#include "Engine/TriggerVolume.h"
#include "Engine/TriggerBox.h"
#include "Components/ActorComponent.h"
#include "GlassDoorPuzzle.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class BUILDINGESCAPE_API UGlassDoorPuzzle : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UGlassDoorPuzzle();

	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

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

	void OpenDoor();
	void CloseDoor();
	void CheckPointers();
	bool CheckPointersOnPlate();

private:

	/// Trigger Boxes
	UPROPERTY(EditAnywhere)
		ATriggerVolume* CopperPressurePlate = nullptr;

	UPROPERTY(EditAnywhere)
		ATriggerVolume* GoldPressurePlate = nullptr;

	UPROPERTY(EditAnywhere)
		ATriggerVolume* SilverPressurePlate = nullptr;

	/// Door Opening Start and End
	UPROPERTY(EditAnywhere)
		FVector StartPosition; 

	UPROPERTY(EditAnywhere) 
		FVector EndPosition;


	/// Specific Actors for Overlap
	UPROPERTY(EditAnywhere)
		class AActor* CopperActor = nullptr;

	UPROPERTY(EditAnywhere)
		class AActor* GoldActor = nullptr;

	UPROPERTY(EditAnywhere)
		class AActor* SilverActor = nullptr;

	/// Door Opening Properties
	UPROPERTY(EditAnywhere)
		float CurrentSpeed;

	UPROPERTY(EditAnywhere)
		float DoorCloseDelay = 1.0f;

	float LastDoorOpenTime;
	bool bCheckActorsOnPlate();

	AActor* Owner = nullptr;

	/*
	UPROPERTY(EditAnywhere)
		class AActor* TerminalOne = nullptr;
	UPROPERTY(EditAnywhere)
		class UMaterialInterface* OnMaterial = nullptr;
	*/
};

You have

	UPROPERTY(EditAnywhere)
		ATriggerVolume* SilverPressurePlate = nullptr;

Did you use the UPROPERTY in Unreal editor? It will just be null if its not doing anything. Check any others too.

Privacy & Terms