Hello!
I have a physics handle component that is grabbing another static mesh, the setTargetLocation is working properly the object changes location, however I was expecting that the object would rotate around his center of mass by default when floating in air, right?
That’s not happening, I have done setSimulatePhysics true on the grabbed mesh as well.
Here is my physics handle current settings:
And here is my code:
The c++ class that contains the mesh to be grabbed:
AGameCube::AGameCube()
{
// 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;
UStaticMesh* cubeMesh = nullptr;
static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeMeshAsset(TEXT("/Game/Meshes/GameCube"));
if (CubeMeshAsset.Succeeded()) {
cubeMesh = CubeMeshAsset.Object;
}
CubeMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("GameCube"), false);
if(CubeMesh && cubeMesh) {
CubeMesh->SetStaticMesh(cubeMesh);
}
CubeMesh->SetSimulatePhysics(true);
CubeMesh->SetCollisionObjectType(ECollisionChannel::ECC_PhysicsBody);
CubeMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_PhysicsBody, ECollisionResponse::ECR_Overlap);
CubeMesh->SetWorldScale3D(FVector(1.f,1.f,1.f));
CubeMesh->SetMassOverrideInKg(NAME_None, 50.f);
SetRootComponent(CubeMesh);
}
Here I am grabbing the object:
void UGrabber::Grab()
{
FHitResult Hit = GetFirstPhysicsBodyInReach();
UPrimitiveComponent* ComponentToGrab = Hit.GetComponent();
AActor* ActorHit = Hit.GetActor();
if (ActorHit)
{
if(!PhysicsHandle)
{
UE_LOG(LogTemp, Error, TEXT("Gonna return no Physics Handle"));
return;
}
AGameCube* GameCube = Cast<AGameCube>(Hit.GetActor());
FVector Location;
FRotator Rotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(OUT Location, OUT Rotation);
FVector newLoc = (Location + Rotation.Vector() * Reach);
FVector compLoc = ComponentToGrab->GetComponentLocation();
float distance = FVector::Dist(newLoc, compLoc);
Reach = Reach - distance;
PhysicsHandle->GrabComponentAtLocation(ComponentToGrab, NAME_None, compLoc);
}
}
And here is the tick function to update the location of the grabbed object:
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if(!PhysicsHandle)
{
return;
}
if (PhysicsHandle->GrabbedComponent)
{
FVector Location;
FRotator Rotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(OUT Location, OUT Rotation);
//Ray-cast out to a certain distance (reach)
FVector newDestination = (Location + Rotation.Vector() * Reach);
PhysicsHandle->SetTargetLocation(newDestination);
}
}