Access violation on C++ variable, set in BP

Hi All

I have a C++ variable, a directional light actor pointer, that I’m setting manually in blueprints. The first operation I tried on it, from C++, is to get its rotation in the world. MyDirectionalLightActor->GetActorRotation() this produces an access violation. I’m sure that the directional light is in the world and is assigned to the C++ variable when it’s called.

Is that expected behavior?

Thanks!

Could you post your exact code?

So you are sure that that varable you try to call too (MyDirectionalLightActor) is not a null pointer at moment you calling?

Ha! Hello!

FRotator SunRotation = SunComponent->GetActorRotation();
	SunRotation.Pitch += 120.f;
	SunComponent->SetActorRotation(SunRotation);

Its fairly arbitrary, I’m just seeing if I can manipulate it in C++

Sorry- I just put MyDirectionalLightActor for the sake of clarity in the question. The pointer is SunComponent. Thats the variable that the light actor was manually assigned to in BP.

I wanted the whole .cpp code or at least the function where you are calling it. Because i’m pretty sure it’s NULL.

The line it breaks on in debug mode is the one where sunrotation is declared. The whole cpp function is those three lines

So, just to clarify, here is what i’ve done. This should be your setup:

Header File:

#pragma once

#include "GameFramework/Actor.h"
#include "MySkySphereClass.generated.h"

/**
 * 
 */
UCLASS()
class PLAYGROUND_API AMySkySphereClass : public AActor
{
	GENERATED_UCLASS_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkySphereTest")
	ADirectionalLight* MyTestDirectionalLight;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkySphereTest")
		FRotator MyTestRotator;

	virtual void BeginPlay() override;
	
};

C++ File:

#include "Playground.h"
#include "MySkySphereClass.h"


AMySkySphereClass::AMySkySphereClass(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	
		
}


void AMySkySphereClass::BeginPlay()
{
	Super::BeginPlay();

	if (MyTestDirectionalLight)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(0, 60.0F, FColor::Black, TEXT("It's not NULL"));
		}

		MyTestRotator = MyTestDirectionalLight->GetActorRotation();
		MyTestRotator.Pitch += 200;
		MyTestDirectionalLight->SetActorRotation(MyTestRotator);
	}
	else
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(1, 60.0F, FColor::Black, TEXT("It's NULL"));
		}
	}

}

This works, since BeginPlay is called after the pointer is filled. If you would place the code into the Constructer, it wouldn’t work, because this would be called with the pointer being NULL. You would need to set the pointer in the constructor instead of the scene outliner.

You don’t need the MyTestRotator variable like i did. That was just for debugging etc.

It is NULL

Look at my answer (:

Hi eXi. The function is being fired by a call from a box trigger begin overlap function. Simply because I wanted to see if I could send a message from gameplay events, via C++, to the skydome. The skydome is referenced in the levelscriptactor in the same way as the suncomponent is. So the event is taking place seconds after initialization. But the break seems to be happening on that line. Although, debugging toold dont always hit the exact right point, maybe?

Just to be clear- the suncomponent is referenced in the skydome base class, and the skydome is referenced in the levelscriptactor.

That’s why i asked for the whole code. Would you now mind showing me the code you used for the ScriptActor class? And which BP has the Trigger on it? :open_mouth:

It jumps around a bit. This has been tested separately, but, for example, the refrence to the sub-level, which inherits from the persistent level, is kept in the game mode. So (Other is the actor reference from beginoverlap);

ARRDevelopGameMode* GameMode = Cast<ARRDevelopGameMode>(UGameplayStatics::GetGameMode(Other));
		ARRSubLevelScriptActor* CurrentLevel = GameMode->GetCurrentSubLevel();
	CurrentLevel->SkySphere->UpdateSkySphere();

The persistent level has the reference;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkySphere") ARRSkySphere* SkySphere;

Which is set in BP, same as the suncomponent

And then in SkySphere;

void ARRSkySphere::UpdateSkySphere() {

  FRotator SunRotation = SunComponent->GetActorRotation();
  SunRotation.Pitch += 120.f;
  SunComponent->SetActorRotation(SunRotation);
}

The first bit, the overlap function, is in a class of box trigger that is sitting in the current sublevel, just as a test to send messages to the skysphere

Try to stick to one comment :smiley:

Gimme a sec to recreate your Setup.

Hm, i can’t get this recreated. I made a custom LevelScriptActor and used a Boxtrigger with Overlapfunction to fire the Function.

The function gets fired and i don’t get an Access violation error.

Would you mind debugging your code with a few if’s?

Just check every pointer if it’s null and make some debug messages so you know at which point the a pointer is already null.

Hey eXi- not sure what you mean by that. “debugging your code with a few ifs”. Do you work for Epic, because this a pretty incredible level of commitment! Many thanks! I’m a noob, self-taught programmer.

Haha, no, i don’t directly work for Epic, but i’m a Moderator here. The answerhub is for you guys to ask questions and we try to solve them :smiley: That’s all. The Staff Guys do much more if you follow some of their answers.

But back to the problem. I mean if’s like this:

ARRDevelopGameMode* GameMode = Cast<ARRDevelopGameMode>(UGameplayStatics::GetGameMode(Other));
if(GameMode)
{
     if (GEngine)
     {
         GEngine->AddOnScreenDebugMessage(1, 60.0F, FColor::Black, TEXT("GameMode not Null"));
     }
     ARRSubLevelScriptActor* CurrentLevel = GameMode->GetCurrentSubLevel();

     if(CurrentLevel)
     {
          if (GEngine)
          {
                GEngine->AddOnScreenDebugMessage(1, 60.0F, FColor::Black, TEXT("CurrentLevel not NULL"));
          }
          CurrentLevel->SkySphere->UpdateSkySphere();
     }
}

And so on. Just to make sure that the access violation doesn’t happen somewhere else, not related to the Sphere. Because, like i already said, i made a custom LevelScriptActor, changed the LevelBlueprint to use it and created a Sphere BP reference that i filled with the BP that we put into our scene. Than i use a TriggerBox and it’s overlap event inside the LevelBlueprint and let it call the function. This is working (despite the fact that the refresh of the material is missing, but the pitch is changing :D).

And since i have the same LevelScriptActor with the Variable and the Sphere with the Light variables and the function, the problem needs to be somewhere else. Or at least i think so :smiley:

EDIT: Just a question: What is “Other” in the “GetGameMode(Other)” Parameter?

Ah ok. I did a few “if else” statements- two. And the skydome is NULL. For some reason the debugger is moving past that because the line its stopping on would be the next one.