Why Does CharacterMovement->MaxWalkSpeed = WalkSpeed; Crash my Engine?

This is my Actor Component header file

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "SprintCrouchMovement.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class SURVIVALHORRORTUT_API USprintCrouchMovement : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	USprintCrouchMovement();

	void Initialize(ACharacter* Character);

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

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

private:
	UPROPERTY(EditAnywhere)
	float SprintSpeed = 800.0f;
	UPROPERTY(EditAnywhere)
	float WalkSpeed = 1200.0f;
};

Initialize Function Where the problem code is called, inside the ActorComponent.cpp

void USprintCrouchMovement::Initialize(ACharacter* Character)
{
	UE_LOG(LogTemp, Warning, TEXT("SprintCrouchMovementInitailized"));
	if (IsValid(Character))
	{
		UE_LOG(LogTemp, Warning, TEXT("We Found the Player Character"));
		UCharacterMovementComponent* CharacterMovement = Character->GetCharacterMovement();
		if (CharacterMovement)
		{
			UE_LOG(LogTemp, Warning, TEXT("We Found the Player Character Movement Component"));
			UE_LOG(LogTemp, Warning, TEXT("Character Address: %p"), static_cast<void*>(Character));
			UE_LOG(LogTemp, Warning, TEXT("Character Movement Address: %p"), static_cast<void*>(CharacterMovement));
			//CharacterMovement->MaxWalkSpeed = WalkSpeed;
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("Failed to Initialize Walk Speed"));
		}
	}
}

And Where I am passing the character from in my PlayerCharacter.cpp

void AHG_PlayerCharacter::Initialize()
{
	ACharacter* PlayerCharacter = GetWorld()->GetFirstPlayerController()->GetCharacter();
	if (PlayerCharacter && PlayerCharacter->GetCharacterMovement())
	{
		UE_LOG(LogTemp, Warning, TEXT("Character Address: %p"), static_cast<void*>(PlayerCharacter));
		UE_LOG(LogTemp, Warning, TEXT("Character Movement Address: %p"), static_cast<void*>(PlayerCharacter->GetCharacterMovement()));
		SprintCrouchMovementComponent->Initialize(PlayerCharacter);
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("Failed to get the player character."));
	}
	

	if (IsValid(WidgetClass))
	{
		UE_LOG(LogTemp, Warning, TEXT("WidgetClassValid"))
		MainHUDWidget = Cast<UMainHUDWidget>(CreateWidget(GetWorld(), WidgetClass));
		if (MainHUDWidget)
		{
			UE_LOG(LogTemp, Warning, TEXT("AddedMainHUDWidget to Viewport"))
			MainHUDWidget->AddToViewport();
		}
	}
}

I have confirmed that the addresses of the components match using UE_LOG and cannot figure out why this is crashing the engine. Any help would be greatly appreciated.

After some more digging and tweaking, it appears that the member variable WalkSpeed is invalid inside the initalize function, if I hardcode the value with a literal it works just fine.
I can also print the value of the variable inside BeginPlay(), and set it in the constructor.
The engine only crashes when I put that variable inside Initialize.

I still don’t know why I couldn’t access the variables in that function, but passing them as parameters from my character class to the component function works.

If anyone can explain why that problem happened that’d be great.

What a doozy to debug!

It turned out declaring my ActorComponent with a UPROPERTY() in my character class was voiding the memory, after removing the UPROPERTY, code is now function as expected.

declaring my ActorComponent with a UPROPERTY() in my character class was voiding the memory, after removing the UPROPERTY, code is now function as expected.

I won’t recommend removing the UPROPERTY() on the component’s property, as it can lead to component being gathered by garbage collector, which you want even less.

But looking at your “solution”, it’s looks like blueprint is overriding your component with a… lets say “a broken one”. I suggest you to try to return UPROPERTY() declaration and instead alter the string name of the component you pass during its creation. In some cases such approach does solves similar problem for me

I guess I forgot to update more of what I did after I got it working thinking UPROPERTY() shouldn’t have messed it up.

I just needed to move them to public since the character class needed access to those variables in my implementation.
Not sure if this is a great idea, but it made sense to me seeing as UPROPERTY() shouldn’t be voiding the memory.
Thanks for your reply.

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