C++ How to get Actor/Sprite bounds?

BackgroundPart.h

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BackgroundPart.generated.h"

UCLASS()
class FLY_BIRD_FLY_API ABackgroundPart : public AActor {
	GENERATED_BODY()

	public:
		// Sets default values for this actor's properties
		ABackgroundPart();

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

	public:
		// Called every frame
		virtual void Tick(float DeltaTime) override;

	private:
		UPROPERTY(EditDefaultsOnly, Category = "Components")
		class UPaperSpriteComponent* Main;

		UPROPERTY(EditDefaultsOnly, Category = "Components")
		class UPaperSpriteComponent* Grass;

};

BackgroundPart.cpp

#include "BackgroundPart.h"
#include "PaperSpriteComponent.h"
#include "PaperSprite.h"

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

	Main = CreateDefaultSubobject<UPaperSpriteComponent>(TEXT("Main"));
	Grass = CreateDefaultSubobject<UPaperSpriteComponent>(TEXT("Grass"));

	Main->SetupAttachment(RootComponent);
	Grass->SetupAttachment(Main);

	auto a = Main;
	auto b = a->GetSprite();
	if (b) {
		auto c = b->GetSourceSize();

		auto x = c.ToString();
		UE_LOG(LogTemp, Warning, TEXT("XXXXXX %s"), *x);
	} else {
		UE_LOG(LogTemp, Warning, TEXT("ERROR GET_SPRITE"));
	}
}

// Called when the game starts or when spawned
void ABackgroundPart::BeginPlay() {
	Super::BeginPlay();
}

// Called every frame
void ABackgroundPart::Tick(float DeltaTime) {
	Super::Tick(DeltaTime);
}

I have 2 questions:

  1. Why do I get my custom log “ERROR GET_SPRITE”?
  2. How to solve this problem?

I need to access to the sprite directly to get its size to automate some stuff.

It will be perfect if you also can help to get the size of whole component including all sprites. I mean the minimum rectangle which contain all sprites

You are trying to access the sprite before the blueprint is ready.

You need to move some pieces of code to PostInitializeComponents

Also make sure the sprite is not a 100% transparent (empty example files can return zero size)

I basically moved everything past auto a = Main and replaced the auto with real variable definitions.

in header file

virtual void PostInitializeComponents() override;

in cpp file

void ABackgroundPart::PostInitializeComponents() {

	Super::PostInitializeComponents();

	UPaperSpriteComponent* a = Main;
	UPaperSprite* b = a->GetSprite();
	if (b) {				
		FVector2D c = b->GetSourceSize();							
		FString x = c.ToString();
		UE_LOG(LogTemp, Warning, TEXT("XXXXXX %s"), *x);		
	}
	else {
		UE_LOG(LogTemp, Warning, TEXT("ERROR GET_SPRITE"));
	}
}


Text output

Thank you so much! I forgot that constructor is called before almost everything :slight_smile:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.