SetConstrainedComponents() causing hard crash [SOLVED]

Hi there. I’m using Unreal 4.23.2 and can’t seem to get around this issue:

  • I’ve set up SprungWheel and SpawnPoint just like in the videos
  • BodyRoot and Wheel both exist and are logged out
  • the crash occurs exactly when SetConstrainedComponents is called (tested with a timer)
  • it doesn’t seem to be the tanks fault: I tried it with a fresh BP containing just a cube set to simulate physics

SprungWheel.cpp:

Summary
#include "SprungWheel.h"
#include "Components/SceneComponent.h"
#include "TimerManager.h"
#include "Components/PrimitiveComponent.h"
#include "PhysicsEngine/PhysicsConstraintComponent.h"

// Sets default values
ASprungWheel::ASprungWheel()
{
 	// 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;

	MassWheelConstraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(FName("MassWheelConstraint"));
	SetRootComponent(MassWheelConstraint);

	Wheel = CreateDefaultSubobject<UStaticMeshComponent>(FName("Wheel"));
	Wheel->SetupAttachment(MassWheelConstraint);
}

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

	SetupConstraint();
	//FTimerHandle TimerHandle;
	// try doing SetupConstraint() later
	//GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &ASprungWheel::SetupConstraint, 1.0f, false);
}

void ASprungWheel::SetupConstraint()
{
	if (!GetAttachParentActor())
	{
		UE_LOG(LogTemp, Error, TEXT("Parent Actor not found"));
		return;
	}
	UPrimitiveComponent* BodyRoot = Cast<UPrimitiveComponent>(GetAttachParentActor()->GetRootComponent());
	if (!BodyRoot)
	{
		UE_LOG(LogTemp, Error, TEXT("Body Root not found"));
		return;
	}
	UE_LOG(LogTemp, Warning, TEXT("BodyRoot: %s"), *BodyRoot->GetFName().ToString());
	UE_LOG(LogTemp, Warning, TEXT("Wheel: %s"), *Cast<UPrimitiveComponent>(Wheel)->GetFName().ToString());
	// Causes a hard crash
	// It's not a construction/BeginPlay order issue, since it also crashes a second after game start
	MassWheelConstraint->SetConstrainedComponents(BodyRoot, NAME_None, Wheel, NAME_None);
}

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

}

SprungWheel.h:

Summary
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

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

class UPhysicsConstraintComponent;

UCLASS()
class BATTLETANKS_API ASprungWheel : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ASprungWheel();

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

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

private:
	void SetupConstraint();

	// Components

	UPROPERTY(VisibleAnywhere, category = "Components")
	UStaticMeshComponent* Wheel = nullptr;

	UPROPERTY(VisibleAnywhere, category = "Components")
	UPhysicsConstraintComponent* MassWheelConstraint = nullptr;

};

I couldn’t find any information on issues with this method in 4.23, so I’ll probably have to give it a try using BP tomorrow. Any help or pointers* in the right direction would really be appreciated.

Alright, some BP experiments helped me isolate the issue: MassWheelConstraint somehow always returned nullptr after being set as root component. The temporary fix looks like this:

Cast<UPhysicsConstraintComponent>(GetRootComponent())->SetConstrainedComponents(BodyRoot, NAME_None, Wheel, NAME_None);

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

Privacy & Terms