diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp index 83256f10..33383796 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp @@ -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(Actor->GetRootComponent())}; + if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("%s"), TEXT("ERROR: invalid actor's root component!"))) + { + return; + } + TArray ActorChildrenComponents; + ActorRootComponent->GetChildrenComponents(true, ActorChildrenComponents); + for (USceneComponent* SceneComponent : ActorChildrenComponents) + { + UPrimitiveComponent* PrimitiveComponent{Cast(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(ActorLeftHandGrabbing->GetRootComponent()) + }; + if (ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("%s"), TEXT("ERROR: invalid actor's root component!"))) + { + TArray ActorChildrenComponents; + ActorRootComponent->GetChildrenComponents(true, ActorChildrenComponents); + for (USceneComponent* SceneComponent : ActorChildrenComponents) + { + UPrimitiveComponent* PrimitiveComponent{Cast(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(ActorLeftHandGrabbing->GetRootComponent()) + }; + if (ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("%s"), TEXT("ERROR: invalid actor's root component!"))) + { + TArray ActorChildrenComponents; + ActorRootComponent->GetChildrenComponents(true, ActorChildrenComponents); + for (USceneComponent* SceneComponent : ActorChildrenComponents) + { + UPrimitiveComponent* PrimitiveComponent{Cast(SceneComponent)}; + if (IsValid(PrimitiveComponent)) + { + PrimitiveComponent->SetSimulatePhysics(true); + } + } + } + ActorRightHandGrabbing = nullptr; } diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp index cce14853..df152f24 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp @@ -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 { diff --git a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h index c399a8d3..3a6ee2fc 100644 --- a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h +++ b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h @@ -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();