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: