Pointer to C++ Class invalid after start, Accessed None trying to read property

Hello guys, I have a problem that I don’t quite understand.
I have a blueprint derived from a C++ class that is something like this



// FirstPlayer.h

UCLASS()
class MYPROJECT_API AFirstPlayer : public ACharacter
{
  ...]
public:
  UPROPERTY(BlueprintReadOnly)
  UStatistics* Statistics;
}

// FirstPlayer.cpp

AFirstPlayer::AFirstPlayer()
{
  // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
  PrimaryActorTick.bCanEverTick = true;

  Statistics = CreateDefaultSubobject<UProgressiveStatistics>(TEXT("Statistics"));  
}



UStatistics

is a C++ class derived from a UObject. When I try to use the variable Statistics in the event graph like this


I receive the error “Accessed None trying to read property …]”. Moreover, using IsValid returns always false.
What am I missing here? Do I need to specify something to the GC in order for it not to delete the variable?

Yeah, GC is fully automated for Actors, but not for UObjects and you have to do some legwork for proper behavior. The easiest way is just to set variable as UPROPERTY and GC will automatically “know” how to handle the object.
I recommend this wiki article, it explains quite well what is going on with Uobjects and GC

Ok, but as you can see here


UPROPERTY(BlueprintReadOnly)
UStatistics* Statistics;

the variable is actually a UPROPERTY. That’s why I have some concerns…

Hey! Could you verify that the object is actually created?
Use



 Statistics = CreateDefaultSubobject<UProgressiveStatistics>(TEXT("Statistics"));
check(Statistics);

 //also you can log something here and check if it exists in your logs:

UE_Log(LogClass, Log, TEXT("Statistics object created"));  

Just to check if you are missing something simple! Because I don’t think GC is the issue here…

The check macro doesn’t trigger anything. I can print the Log after the check.

If inside AFirstPlayer class I do something like this


    class UStatistics* Stastistics;

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

public:    

    UFUNCTION(BlueprintCallable)
    class UStatistics* GetStat() const
    {
        return Stastistics;
    }

The blueprint works without problems. FYI I didn’t change how I’m initializing the Statistics variable, always with CreateDefaultSubobject function.
I can call all functions from the event graph of the blueprint without any problem. I really don’t understand why this is happening.

I still have this issue.
I can get it work with the get function, but if I set the variable as UPROPERTY(BlueprintReadOnly), after I stop the game pressing ESC I get the error reported in the first post.

I would really like to understand what is going on here, a help would be much appreciated.

1 Like

Hi. This was a long time ago, but did you ever figure this out?

This may be a case of the blueprint classes defaults having serialized a nullptr value for the Statistics object already.

You could probably try marking the Property with EditDefaultsOnly and then look at the default value for the variable in the blueprint class defaults. You might be able to reset the default from the native or blueprint parent class there as well.
Another way to test this would be to create a completely new empty blueprint class from your native class, I’d expect the value to be set in this case.

Is this just a case of the property needing the “Instanced” property specifier?