Crashes with Access Violation on GetWorld()

I’m crashing when trying to GetWorld() in OpenDoor() line 27 of OpenDoor.cpp due to an Access Violation. I’ve tried rebuilding and it won’t go away. I’m in UE4.21. I’ve tried separating GetWorld() onto its own line and it is crashing, but I’m also calling GetWorld() in BeginPlay() without crashing. I’m fairly new to C++, so I’m looking understand what’s going wrong rather than just working around the issue. I even tried assigning GetWorld() to a variable in BeginPlay(), but when I go back to access the variable in OpenDoor() I still crash (I checked the UWorld assigned to the variable and it looks fine as far as I can tell).

OpenDoor.h

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GameFramework/Actor.h"
#include "Engine/TriggerVolume.h"
#include "Engine/World.h"
#include "OpenDoor.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ESCAPEROOM_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;

	void OpenDoor();

	void CloseDoor();

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

private:
	UPROPERTY(VisibleAnywhere)
		float OpenAngle = -60.f;

	UPROPERTY(EditAnywhere)
		ATriggerVolume* PressurePlate;

	UPROPERTY(EditAnywhere)
		float DoorCloseDelay = 1.f;

	float LastDoorOpenTime;

	AActor* ActorThatOpens;

	AActor* Owner;

	bool IsDoorOpen;
};

OpenDoor.cpp

#include "OpenDoor.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();
	ActorThatOpens = GetWorld()->GetFirstPlayerController()->GetPawn();
	AActor* Owner = GetOwner();
	IsDoorOpen = false;
	
}

void UOpenDoor::OpenDoor()
{
	Owner->SetActorRotation(FRotator(0.f, OpenAngle, 0.f));
	LastDoorOpenTime = GetWorld()->GetTimeSeconds(); //Access Violation Crash Here
	IsDoorOpen = true;
}

void UOpenDoor::CloseDoor()
{
	Owner->SetActorRotation(FRotator(0.f, 0.f, 0.f));
	IsDoorOpen = false;
}


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

	if (PressurePlate->IsOverlappingActor(ActorThatOpens)) {
		OpenDoor();
	}

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

I had “AActor* Owner;” in the header and “AActor* Owner = GetOwner();” in the .cpp, changing the .cpp to “Owner = GetOwner();” fixed it.

I had a similar issue and this question helped me figure it out. After destroying and respawning most of the actors (my way of changing the level) GetWorld() would trigger EXCEPTION_ACCESS_VIOLATION.

It was called from inside a class derived from UObject. This class has a valid AActor grand parent to properly execute GetWorld(). Apparently after destroying and respawning actors for the 5 time, it wouldn’t work.

My solution was to directly pass a pointer to an definety existing actor (freshly spawned) to the function where I call

GetWorld()->SpawnActor

and change it to

SomeActor->GetWorld()->SpawnActor

I hope this will be helpful to someone.