FConstraintInstance GetCurrentXXX always returns 0

I’m trying to create a min/max constraint joint (which exists in Unity, but I couldn’t find such joint in UE) by soft limiting the FConstraintInstance when current twist or swing goes beyond min/max threshold. But… for some reason GetCurrentTwist/Swing always returns 0, although the joint is being violently shaken! So is there a way to get the joint current state?

I think I’m running into the same issue as well.

I want to use the angle of the constraint for another calculation, but it seems that constraint->GetCurrentXXX() always returns 0 for me as well.

If anyone has any ideas it would be really appreciated.

In case it’s helpful, my code right now:

MyActor1.h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PhysicsEngine/PhysicsConstraintComponent.h"
#include "Components/StaticMeshComponent.h"


#include "MyActor1.generated.h"


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

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Physics")
		class UStaticMeshComponent* Mesh1;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Physics")
	class UStaticMeshComponent* Mesh2;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Physics")
	class UPhysicsConstraintComponent* Constraint1;

	float time = 0.0f;
	float w = 2.0 * 3.1415 / 5.0f;

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

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

};

MyActor1.cpp

#include "MyActor1.h"

// Sets default values
MyActor1::MyActor1()
{
	UE_LOG(LogTemp, Warning, TEXT("Constructor"));

 	// 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;

	RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Scene Component"));

	Mesh1 = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh1"));
	Mesh1->SetupAttachment(RootComponent);

	Mesh2 = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh2"));
	Mesh2->SetupAttachment(RootComponent);
	Mesh2->SetSimulatePhysics(true);
	Mesh2->SetCollisionProfileName("Widget");

	

	Constraint1 = CreateDefaultSubobject<UPhysicsConstraintComponent>(TEXT("Constraint1"));
	Constraint1->SetupAttachment(RootComponent);

}

// Called when the game starts or when spawned
void MyActor1::BeginPlay()
{
	UE_LOG(LogTemp, Warning, TEXT("BeginPlay"));
	Super::BeginPlay();
}

// Called every frame
void MyActor1::Tick(float DeltaTime)
{
	UE_LOG(LogTemp, Warning, TEXT("Tick"));
	Super::Tick(DeltaTime);


	time += DeltaTime;
	float vel = sin(w * time);
	UE_LOG(LogTemp, Warning, TEXT("Tick - setting speed: %f"), vel);
	Constraint1->SetAngularVelocityTarget(FVector(vel));

	float swing1_angle = Constraint1->GetCurrentSwing1();
	float swing2_angle = Constraint1->GetCurrentSwing2();
	float twist_angle = Constraint1->GetCurrentTwist();

	UE_LOG(LogTemp, Warning, TEXT("Angles %f, %f, %f [%f]"), swing1_angle, swing2_angle, twist_angle, time);

}

After upgrading from 4.27 to 5.4 bumped in to the same issue, now my code doesn’t work. Did you find any solution fellow developer?

seems like its a targeted fix for 5.5. Check UE-158863 as a reference, basically the same behaviour.
should be fixable with a bit of math and the “look at” node for now.

Edit: an easy solution would be to use the Delta (Rotator) Node to get normalized yaw, pitch and roll angles between two bodies.

a c++ solution would look something like this:

1 Like