Apply constraint only x and y component for physics-simulated falling actor

I have a ball with physics simulation. It is released from a certain high and falls due to gravity. I want to add circular constraint on this ball such that it also moves circularly if seen from top/bottom.

UOrbitingComponent provides the constraint applied on ABallActor as follows:

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "OrbitingComponent.generated.h"


UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class MYPROJECT_API UOrbitingComponent : public UActorComponent
{
	GENERATED_BODY()

private:
	UOrbitingComponent();
	void BeginPlay() override;
	void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

	FVector InitPos;
	void SetPosition(float Time);
};
#include "OrbitingComponent.h"

UOrbitingComponent::UOrbitingComponent()
{
	PrimaryComponentTick.bCanEverTick = true;
}

void UOrbitingComponent::BeginPlay()
{
        Super::BeginPlay();
	InitPos = GetOwner()->GetActorLocation();
	SetPosition(0.f);
}

void UOrbitingComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
	float Time = GetOwner()->GetGameTimeSinceCreation();
	SetPosition(Time);

	// UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent());
}

void UOrbitingComponent::SetPosition(float Time)
{
	float X = InitPos.X + 100 * FMath::Cos(2 * PI * 0.5f * Time);
	float Y = InitPos.Y + 100 * FMath::Sin(2 * PI * 0.5f * Time);
	float Z = InitPos.Z;

	GetOwner()->SetActorLocation(FVector(X, Y, Z));
}
#pragma once

#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "BallActor.generated.h"


UCLASS()
class MYPROJECT_API ABallActor : public AStaticMeshActor
{
	GENERATED_BODY()
		ABallActor();
};
#include "BallActor.h"
#include "OrbitingComponent.h"
#include "RotatingComponent.h"
#include "AxesComponent.h"

ABallActor::ABallActor()
{
	UStaticMeshComponent* SMC = GetStaticMeshComponent();

	SMC->SetRelativeScale3D(FVector(0.25f));

	SMC->SetMobility(EComponentMobility::Movable);

	static ConstructorHelpers::FObjectFinder<UStaticMesh> SM(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
	if (SM.Succeeded())
		SMC->SetStaticMesh(SM.Object);

	static ConstructorHelpers::FObjectFinder<UMaterial> M(TEXT("/Game/StarterContent/Materials/M_Metal_Gold.M_Metal_Gold"));
	if (M.Succeeded())
		SMC->SetMaterial(0, M.Object);

	SMC->SetSimulatePhysics(true);
	SMC->AddImpulse(FVector(0.f, 0.f, 5000.f));

	UOrbitingComponent* OC = CreateDefaultSubobject<UOrbitingComponent>(TEXT("Orbiting Component"));
}

I can actually use free fall equation as follows but I prefer physics simulation.

float Z = InitPos.Z - Gravity * Time * Time /2;

Question

How to apply position constraint only on x and y components and let the z component of the ball take its natural value due to gravity?

Does this work?

(I don’t know where this is in C++)

Setting bLockZTranslation to either false or true does NOT work.

void UOrbitingComponent::BeginPlay()
{
	Super::BeginPlay();
	UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent());
	PrimitiveComponent->GetBodyInstance()->bLockZTranslation = true; 
	InitPos = GetOwner()->GetActorLocation();
	SetPosition(0.f);
}

Do you have a test project I could use?

Dear @DanM

Thank you for being interested in this problem. :slight_smile:
Here is my repo : https://github.com/pstricks-fans/hybridconstraints

Note: The repo will be likely removed in the future. As a result, it makes this question contain a dangling pointer or reference.

Probably won’t have much time to look at it today as I have family visiting but will probably find time tomorrow.

1 Like

Yeah, I’m not sure. You’re using SetActorLocation and always setting the Z to it’s initial Z but even after changing to use adding offset falling doesn’t happen.

Perhaps there’s a virtual function that gets called after physics simulation happens where you can update the location? idk.

1 Like

Thank you. I will investigate it again later. :slight_smile:

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

Privacy & Terms