try an alternative approach for the grab/release functionality by disabling/enabling physics simulation

This commit is contained in:
Mamadou Babaei
2023-05-19 18:14:01 +02:00
parent a29cba310e
commit 63fe65b071
3 changed files with 66 additions and 47 deletions
@@ -1215,14 +1215,14 @@ bool ASGPawn::IsGrabbing(const USGVirtualHandComponent* Hand, AActor*& OutActor)
return Hand == HandLeft ? IsLeftHandGrabbing(OutActor) : IsRightHandGrabbing(OutActor);
}
void ASGPawn::GrabLeft(AActor* Actor)
void ASGPawn::Grab(USGVirtualHandComponent* Hand, AActor* Actor)
{
if (!ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!")))
{
return;
}
const USGGrabComponent* GrabComponent = USGGrabComponent::GetGrabComponent(Actor);
const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(Actor)};
if (!GrabComponent)
{
return;
@@ -1238,7 +1238,23 @@ void ASGPawn::GrabLeft(AActor* Actor)
const FName SocketName{GrabComponent->GetAttachmentSocketName()};
ensureAlwaysMsgf(SocketName != NAME_None, TEXT("invalid attachment socket name!"));
const bool bAttached = Actor->AttachToComponent(HandLeft, MoveTemp(AttachmentRules), SocketName);
const USceneComponent* ActorRootComponent{Cast<USceneComponent>(Actor->GetRootComponent())};
if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("%s"), TEXT("ERROR: invalid actor's root component!")))
{
return;
}
TArray<USceneComponent*> ActorChildrenComponents;
ActorRootComponent->GetChildrenComponents(true, ActorChildrenComponents);
for (USceneComponent* SceneComponent : ActorChildrenComponents)
{
UPrimitiveComponent* PrimitiveComponent{Cast<UPrimitiveComponent>(SceneComponent)};
if (IsValid(PrimitiveComponent))
{
PrimitiveComponent->SetSimulatePhysics(false);
}
}
const bool bAttached = Actor->AttachToComponent(Hand, MoveTemp(AttachmentRules), SocketName);
if (bAttached)
{
ActorLeftHandGrabbing = Actor;
@@ -1249,40 +1265,6 @@ void ASGPawn::GrabLeft(AActor* Actor)
}
}
void ASGPawn::GrabRight(AActor* Actor)
{
if (!ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!")))
{
return;
}
const USGGrabComponent* GrabComponent = USGGrabComponent::GetGrabComponent(Actor);
if (!GrabComponent)
{
return;
}
FAttachmentTransformRules AttachmentRules{
FAttachmentTransformRules(GrabComponent->GetAttachmentLocationRule(),
GrabComponent->GetAttachmentRotationRule(),
GrabComponent->GetAttachmentScaleRule(),
GrabComponent->GetAttachmentWeldSimulatedBodies())
};
const FName SocketName{GrabComponent->GetAttachmentSocketName()};
ensureAlwaysMsgf(SocketName != NAME_None, TEXT("invalid attachment socket name!"));
const bool bAttached = Actor->AttachToComponent(HandRight, MoveTemp(AttachmentRules), SocketName);
if (bAttached)
{
ActorRightHandGrabbing = Actor;
}
else
{
SGLOG_ERROR("Failed to grab the actor with the right hand!", Actor, SocketName);
}
}
void ASGPawn::ReleaseLeft()
{
if (!IsValid(ActorLeftHandGrabbing))
@@ -1290,7 +1272,7 @@ void ASGPawn::ReleaseLeft()
return;
}
const USGGrabComponent* GrabComponent = USGGrabComponent::GetGrabComponent(ActorLeftHandGrabbing);
const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(ActorLeftHandGrabbing)};
if (!IsValid(GrabComponent))
{
return;
@@ -1303,6 +1285,23 @@ void ASGPawn::ReleaseLeft()
GrabComponent->GetDetachmentInCallModify())
);
const UPrimitiveComponent* ActorRootComponent{
Cast<UPrimitiveComponent>(ActorLeftHandGrabbing->GetRootComponent())
};
if (ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("%s"), TEXT("ERROR: invalid actor's root component!")))
{
TArray<USceneComponent*> ActorChildrenComponents;
ActorRootComponent->GetChildrenComponents(true, ActorChildrenComponents);
for (USceneComponent* SceneComponent : ActorChildrenComponents)
{
UPrimitiveComponent* PrimitiveComponent{Cast<UPrimitiveComponent>(SceneComponent)};
if (IsValid(PrimitiveComponent))
{
PrimitiveComponent->SetSimulatePhysics(true);
}
}
}
ActorLeftHandGrabbing = nullptr;
}
@@ -1313,7 +1312,7 @@ void ASGPawn::ReleaseRight()
return;
}
const USGGrabComponent* GrabComponent = USGGrabComponent::GetGrabComponent(ActorRightHandGrabbing);
const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(ActorRightHandGrabbing)};
if (!IsValid(GrabComponent))
{
return;
@@ -1326,6 +1325,23 @@ void ASGPawn::ReleaseRight()
GrabComponent->GetDetachmentInCallModify())
);
const UPrimitiveComponent* ActorRootComponent{
Cast<UPrimitiveComponent>(ActorLeftHandGrabbing->GetRootComponent())
};
if (ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("%s"), TEXT("ERROR: invalid actor's root component!")))
{
TArray<USceneComponent*> ActorChildrenComponents;
ActorRootComponent->GetChildrenComponents(true, ActorChildrenComponents);
for (USceneComponent* SceneComponent : ActorChildrenComponents)
{
UPrimitiveComponent* PrimitiveComponent{Cast<UPrimitiveComponent>(SceneComponent)};
if (IsValid(PrimitiveComponent))
{
PrimitiveComponent->SetSimulatePhysics(true);
}
}
}
ActorRightHandGrabbing = nullptr;
}
@@ -206,7 +206,7 @@ void ASGPlayerController::BeginPlay()
SGPawn->OnGrabStateUpdated().AddWeakLambda(
this, [=](
const USGVirtualHandComponent* Hand,
USGVirtualHandComponent* Hand,
AActor* ActorThumbCanGrab, const AActor* ActorIndexCanGrab,
const AActor* ActorMiddleCanGrab) -> void
{
@@ -55,7 +55,7 @@ class SENSEGLOVE_API ASGPawn : public APawn
public:
DECLARE_EVENT_FourParams(
ASGPawn, FGrabStateUpdatedEvent,
const USGVirtualHandComponent*, AActor*, const AActor*, const AActor*);
USGVirtualHandComponent*, AActor*, const AActor*, const AActor*);
FGrabStateUpdatedEvent& OnGrabStateUpdated()
{
@@ -631,15 +631,18 @@ public:
}
public:
void GrabLeft(AActor* Actor);
void GrabRight(AActor* Actor);
FORCEINLINE void Grab(const USGVirtualHandComponent* Hand, AActor* Actor)
FORCEINLINE void GrabLeft(AActor* Actor)
{
return Hand == HandLeft ? GrabLeft(Actor) : GrabRight(Actor);
Grab(HandLeft, Actor);
}
FORCEINLINE void GrabRight(AActor* Actor)
{
Grab(HandRight, Actor);
}
void Grab(USGVirtualHandComponent* Hand, AActor* Actor);
void ReleaseLeft();
void ReleaseRight();