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?