Component Stack Overflows on a C++ Character but not on a Blueprint one

So I created an actor component in C++. The component on the BeginPlay() function gets the Character owner and its MovementComponent, and saves it for later use (because they are called multiple time in the class)

// Called when the game starts
void UParkourMovement::BeginPlay()
{
	Super::BeginPlay();

	Character = Cast <ACharacter>(GetOwner());
	MovementComponent = Character->GetCharacterMovement();

	DefaultGravityScale = MovementComponent->GravityScale;
}

And later for example during a function I may use:

if(MovementComponent->IsFalling())

So this code works fine if I add this component to a character like the starter FPS character, but if I create my own C++ Character, and I declare inside my component:

	UPROPERTY(VisibleAnywhere, Category = "Components")
	class UParkourMovement* ParkourComponent;

then inside the constructor I create one:

AMovementBasedCharacter::AMovementBasedCharacter()
{
 	// 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;

	ParkourComponent = CreateDefaultSubobject<UParkourMovement>(TEXT("Parkour Movement"));
}

So the editor compiles, the game runs untill I try to use that component:

When I am calling the function that uses IsFalling() the code stops for a stack overflow, while using it in a blueprint character it just works.
Also the strange thing is that I can access to some values like the GravityScale but calling the “IsFalling” just breaks eveything

Can you post the crash log?

Does this: CustomComponent = CreateDefaultSubobject(TEXT(“My own component”)); even compile? It should be this:

CustomComponent = CreateDefaultSubobject<UMyCustomComponent>(TEXT(“My own component”));

And make sure you #include "MyCustomComponent.h" in .cpp if it’s not included in .h

Additionally in .h: class UMyCustomComponent* CustomComponent; with forward declaration, you can write pretty much anything after class and the compiler will be okay with that, but it doesn’t mean it will work. Don’t forget about prefixes.

2 Likes

@Roy_Wierer.Seda145 the log is simply:

Exception thrown at 0x00007FFC9F574B16 (UnrealEditor-MovementFPS.dll) in UnrealEditor.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000A61E203FC8).
Unhandled exception at 0x00007FFC9F574B16 (UnrealEditor-MovementFPS.dll) in UnrealEditor.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000A61E203FC8).

Also @Tuerer the quote block I was using escaped the part, I editet the message, so yeah I have that part. And also I had the prefixes, I didn’t copy-pasted the code so I forgot about the U, but the code had the prefixes

Also sorry if this wasn’t clear:

MovementBasedCharacter.h contains:

#include "ParkourMovement.h"`

//...

UPROPERTY(VisibleAnywhere, Category = Components)
class UMyCustomComponent* CustomComponent;

ParkourMovement.cpp contains:

// Called when the game starts
void UParkourMovement::BeginPlay()
{
	Super::BeginPlay();

	Character = Cast <ACharacter>(GetOwner());
	MovementComponent = Character->GetCharacterMovement();

	DefaultGravityScale = MovementComponent->GravityScale;
}
//...
//in another function
if(MovementComponent->IsFalling())

try and see where it breaks:

// Called when the game starts
void UParkourMovement::BeginPlay() {
	Super::BeginPlay();

	ACharacter* Character = Cast<ACharacter>(GetOwner());
	if (IsValid(Character)) {
		if (IsValid(Character->GetCharacterMovement())) {
			float DefaultGravityScale = Character->GetCharacterMovement()->GravityScale;
			bool bIsFalling = Character->GetCharacterMovement()->IsFalling()
		}
	}
}

Also if you declare a pointer to a UObject you should initialize it as nullptr:

UPROPERTY(VisibleAnywhere, Category = Components)
UMyCustomComponent* CustomComponent = nullptr;

This still works, just like before the BeginPlay works normally. But while debugging I found the error (but not the solution):

For some reason when I press my spacebar my jump function gets called so many times that I reach stackoverflow, it’s like it’s in a infinite loop of being called. Tried with a log and I got a thousand of lines for a simple spacebar pressed once.

I am not sure why this is happening, maybe I got something wrong, my code is the following:

// Called to bind functionality to input
void AMovementBasedCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	PlayerInputComponent->BindAxis("Move Forward / Backward", this, &AMovementBasedCharacter::MoveForward);
	PlayerInputComponent->BindAxis("Move Right / Left", this, &AMovementBasedCharacter::MoveRight);
	PlayerInputComponent->BindAxis("Turn Right / Left Gamepad", this, &AMovementBasedCharacter::MoveRight);
	PlayerInputComponent->BindAxis("Look Up / Down Mouse", this, &AMovementBasedCharacter::LookUp);
	PlayerInputComponent->BindAxis("Look Up / Down Gamepad", this, &AMovementBasedCharacter::LookUp);
	PlayerInputComponent->BindAxis("Turn Right / Left Mouse", this, &AMovementBasedCharacter::Turn);
	PlayerInputComponent->BindAxis("Turn Right / Left Gamepad", this, &AMovementBasedCharacter::Turn);

	PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AMovementBasedCharacter::Jump);
}

void AMovementBasedCharacter::Jump()
{
	ParkourComponent->Jump(ForwardAxis, RightAxis);
}

What does the UParkourMovement::Jump method look like?

It’s doing various stuff but for centranly it’s not calling himself or the MovementBasedCharacter::Jump()

The fact is that this does not work with a C++ Character but works with a basic blueprint Chaeacter.
Probably the problem is in the input binding, but I don’t understand how

void UParkourMovement::Jump(float Forward, float Right)
{
	if (!MovementComponent->IsFalling())
	{
		Character->Jump();
	}

So, I don’t know why but even tho I did not have overridden the Jump function my AMovementBasedCharacter::Jump was being called from my component even tho I wanted to call the ACharacter::Jump

So I modified the name of my custom jump to “JumpAction” and it works. It caused an infinite loop because the component instead of calling the ACharacter::Jump he would call back the AMovementBasedCharacter::Jump that would call the component, that would call himself again,…

Your input calls Jump on the character, which calls jump on the component, which calls jump on the character… in your last two posts.

2 Likes