diff --git a/Source/SenseGlove/Private/SenseGlove/Components/SGGrabComponent.cpp b/Source/SenseGlove/Private/SenseGlove/Components/SGGrabComponent.cpp index 6396f895..375f5f39 100644 --- a/Source/SenseGlove/Private/SenseGlove/Components/SGGrabComponent.cpp +++ b/Source/SenseGlove/Private/SenseGlove/Components/SGGrabComponent.cpp @@ -99,12 +99,17 @@ USGGrabComponent::USGGrabComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer), Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { - AttachmentLocationRule = EAttachmentRule::KeepRelative; - AttachmentRotationRule = EAttachmentRule::KeepRelative; - AttachmentScaleRule = EAttachmentRule::KeepRelative; - bAttachmentWeldSimulatedBodies = false; + AttachmentLocationRule = EAttachmentRule::SnapToTarget; + AttachmentRotationRule = EAttachmentRule::SnapToTarget; + AttachmentScaleRule = EAttachmentRule::SnapToTarget; + bAttachmentWeldSimulatedBodies = true; AttachmentSocketName = NAME_None; + + DetachmentLocationRule = EDetachmentRule::KeepWorld; + DetachmentRotationRule = EDetachmentRule::KeepWorld; + DetachmentScaleRule = EDetachmentRule::KeepWorld; + bDetachmentCallModify = false; } USGGrabComponent::FImpl::FImpl(USGGrabComponent* InOwner) diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp index 5ec34659..1cfd01c3 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp @@ -430,6 +430,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer) ActorLeftThumbCanGrab = nullptr; ActorLeftIndexCanGrab = nullptr; ActorLeftMiddleCanGrab = nullptr; + ActorLeftHandGrabbing = nullptr; ActorLeftThumbTouching = nullptr; ActorLeftIndexTouching = nullptr; @@ -440,6 +441,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer) ActorRightThumbCanGrab = nullptr; ActorRightIndexCanGrab = nullptr; ActorRightMiddleCanGrab = nullptr; + ActorRightHandGrabbing = nullptr; ActorRightThumbTouching = nullptr; ActorRightIndexTouching = nullptr; @@ -1185,6 +1187,127 @@ void ASGPawn::OnRightPinkyFingertipTouchColliderOverlapEnds( } } +bool ASGPawn::IsLeftHandGrabbing(AActor*& OutActor) const +{ + if (IsValid(ActorLeftHandGrabbing)) + { + OutActor = ActorLeftHandGrabbing; + return true; + } + + return false; +} + +bool ASGPawn::IsRightHandGrabbing(AActor*& OutActor) const +{ + if (IsValid(ActorRightHandGrabbing)) + { + OutActor = ActorRightHandGrabbing; + return true; + } + + return false; +} + +bool ASGPawn::IsGrabbing(const USGVirtualHandComponent* Hand, AActor*& OutActor) const +{ + return Hand == HandLeft ? IsLeftHandGrabbing(OutActor) : IsRightHandGrabbing(OutActor); +} + +void ASGPawn::GrabLeft(AActor* Actor) +{ + if (ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!"))) + { + return; + } + + const USGGrabComponent* GrabComponent = USGGrabComponent::GetGrabComponent(Actor); + if (!GrabComponent) + { + return; + } + + Actor->AttachToComponent( + HandLeft, + FAttachmentTransformRules(GrabComponent->GetAttachmentLocationRule(), + GrabComponent->GetAttachmentRotationRule(), + GrabComponent->GetAttachmentScaleRule(), + GrabComponent->GetAttachmentWeldSimulatedBodies()), + GrabComponent->GetAttachmentSocketName()); + + ActorLeftHandGrabbing = 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; + } + + Actor->AttachToComponent( + HandRight, + FAttachmentTransformRules(GrabComponent->GetAttachmentLocationRule(), + GrabComponent->GetAttachmentRotationRule(), + GrabComponent->GetAttachmentScaleRule(), + GrabComponent->GetAttachmentWeldSimulatedBodies()), + GrabComponent->GetAttachmentSocketName()); + + ActorRightHandGrabbing = Actor; +} + +void ASGPawn::ReleaseLeft() +{ + if (!IsValid(ActorLeftHandGrabbing)) + { + return; + } + + const USGGrabComponent* GrabComponent = USGGrabComponent::GetGrabComponent(ActorLeftHandGrabbing); + if (!IsValid(GrabComponent)) + { + return; + } + + ActorLeftHandGrabbing->DetachFromActor( + FDetachmentTransformRules(GrabComponent->GetDetachmentLocationRule(), + GrabComponent->GetDetachmentRotationRule(), + GrabComponent->GetDetachmentScaleRule(), + GrabComponent->GetDetachmentInCallModify()) + ); + + ActorLeftHandGrabbing = nullptr; +} + +void ASGPawn::ReleaseRight() +{ + if (!IsValid(ActorRightHandGrabbing)) + { + return; + } + + const USGGrabComponent* GrabComponent = USGGrabComponent::GetGrabComponent(ActorRightHandGrabbing); + if (!IsValid(GrabComponent)) + { + return; + } + + ActorRightHandGrabbing->DetachFromActor( + FDetachmentTransformRules(GrabComponent->GetDetachmentLocationRule(), + GrabComponent->GetDetachmentRotationRule(), + GrabComponent->GetDetachmentScaleRule(), + GrabComponent->GetDetachmentInCallModify()) + ); + + ActorRightHandGrabbing = nullptr; +} + ASGPawn::FImpl::FImpl(ASGPawn* InOwner) : Owner(InOwner) { diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp index 3fb64d1e..663e396d 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp @@ -194,7 +194,7 @@ void ASGPlayerController::BeginPlay() SGPawn->OnGrabStateUpdated().AddWeakLambda( this, [&]( const USGVirtualHandComponent* Hand, - const AActor* ActorThumbCanGrab, const AActor* ActorIndexCanGrab, + AActor* ActorThumbCanGrab, const AActor* ActorIndexCanGrab, const AActor* ActorMiddleCanGrab) -> void { if (!IsValid(Hand)) @@ -202,10 +202,20 @@ void ASGPlayerController::BeginPlay() return; } - if (IsValid(ActorThumbCanGrab) && - ((ActorIndexCanGrab == ActorThumbCanGrab)) || ActorMiddleCanGrab == ActorThumbCanGrab) + if (SGPawn->IsGrabbing(Hand)) { - + if (!IsValid(ActorThumbCanGrab) || + (ActorIndexCanGrab != ActorThumbCanGrab || ActorMiddleCanGrab != ActorThumbCanGrab)) + { + SGPawn->Release(Hand); + } + } + else + { + if (SGPawn->CanGrab(Hand, ActorThumbCanGrab)) + { + SGPawn->Grab(Hand, ActorThumbCanGrab); + } } }); diff --git a/Source/SenseGlove/Public/SenseGlove/Components/SGGrabComponent.h b/Source/SenseGlove/Public/SenseGlove/Components/SGGrabComponent.h index 18bd1823..203e715f 100644 --- a/Source/SenseGlove/Public/SenseGlove/Components/SGGrabComponent.h +++ b/Source/SenseGlove/Public/SenseGlove/Components/SGGrabComponent.h @@ -65,11 +65,23 @@ private: EAttachmentRule AttachmentScaleRule; UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) - bool bAttachmentWeldSimulatedBodies; + uint8 bAttachmentWeldSimulatedBodies : 1; UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) FName AttachmentSocketName; + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EDetachmentRule DetachmentLocationRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EDetachmentRule DetachmentRotationRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EDetachmentRule DetachmentScaleRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + uint8 bDetachmentCallModify : 1; + private: struct FImpl; @@ -114,7 +126,7 @@ public: FORCEINLINE bool GetAttachmentWeldSimulatedBodies() const { - return bAttachmentWeldSimulatedBodies; + return !!bAttachmentWeldSimulatedBodies; } FORCEINLINE void SetAttachmentWeldSimulatedBodies(const bool bInAttachmentWeldSimulatedBodies) @@ -131,4 +143,44 @@ public: { AttachmentSocketName = InAttachmentSocketName; } + + FORCEINLINE EDetachmentRule GetDetachmentLocationRule() const + { + return DetachmentLocationRule; + } + + FORCEINLINE void SetDetachmentLocationRule(const EDetachmentRule InDetachmentLocationRule) + { + DetachmentLocationRule = InDetachmentLocationRule; + } + + FORCEINLINE EDetachmentRule GetDetachmentRotationRule() const + { + return DetachmentRotationRule; + } + + FORCEINLINE void SetDetachmentRotationRule(const EDetachmentRule InDetachmentRotationRule) + { + DetachmentRotationRule = InDetachmentRotationRule; + } + + FORCEINLINE EDetachmentRule GetDetachmentScaleRule() const + { + return DetachmentScaleRule; + } + + FORCEINLINE void SetDetachmentScaleRule(const EDetachmentRule InDetachmentScaleRule) + { + DetachmentScaleRule = InDetachmentScaleRule; + } + + FORCEINLINE bool GetDetachmentInCallModify() const + { + return !!bDetachmentCallModify; + } + + FORCEINLINE void SetDetachmentInCallModify(const bool bInDetachmentCallModify) + { + bDetachmentCallModify = bInDetachmentCallModify; + } }; \ No newline at end of file diff --git a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h index 29231fad..c399a8d3 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*, const AActor*, const AActor*, const AActor*); + const USGVirtualHandComponent*, AActor*, const AActor*, const AActor*); FGrabStateUpdatedEvent& OnGrabStateUpdated() { @@ -163,6 +163,9 @@ private: UPROPERTY(Transient) AActor* ActorLeftMiddleCanGrab; + UPROPERTY(Transient) + AActor* ActorLeftHandGrabbing; + UPROPERTY(Transient) AActor* ActorLeftThumbTouching; @@ -187,6 +190,9 @@ private: UPROPERTY(Transient) AActor* ActorRightMiddleCanGrab; + UPROPERTY(Transient) + AActor* ActorRightHandGrabbing; + UPROPERTY(Transient) AActor* ActorRightThumbTouching; @@ -573,13 +579,73 @@ protected: public: FORCEINLINE bool CanLeftHandGrab(const AActor* Actor) const { - return ((IsValid(Actor) && Actor == ActorLeftThumbCanGrab) + return !IsLeftHandGrabbing() && ((IsValid(Actor) && Actor == ActorLeftThumbCanGrab) && (Actor == ActorLeftIndexCanGrab || Actor == ActorLeftMiddleCanGrab)); } + FORCEINLINE bool IsLeftHandGrabbing(const AActor* Actor) const + { + return IsValid(Actor) && ActorLeftHandGrabbing == Actor; + } + + bool IsLeftHandGrabbing(AActor*& OutActor) const; + + FORCEINLINE bool IsLeftHandGrabbing() const + { + return IsValid(ActorLeftHandGrabbing); + } + FORCEINLINE bool CanRightHandGrab(const AActor* Actor) const { - return ((IsValid(Actor) && Actor == ActorRightThumbCanGrab) + return !IsRightHandGrabbing() && ((IsValid(Actor) && Actor == ActorRightThumbCanGrab) && (Actor == ActorRightIndexCanGrab || Actor == ActorRightMiddleCanGrab)); } + + FORCEINLINE bool IsRightHandGrabbing(const AActor* Actor) const + { + return IsValid(Actor) && ActorRightHandGrabbing == Actor; + } + + FORCEINLINE bool IsRightHandGrabbing() const + { + return IsValid(ActorRightHandGrabbing); + } + + bool IsRightHandGrabbing(AActor*& OutActor) const; + + FORCEINLINE bool CanGrab(const USGVirtualHandComponent* Hand, const AActor* Actor) const + { + return Hand == HandLeft ? CanLeftHandGrab(Actor) : CanRightHandGrab(Actor); + } + + FORCEINLINE bool IsGrabbing(const USGVirtualHandComponent* Hand, const AActor* Actor) const + { + return Hand == HandLeft ? IsLeftHandGrabbing(Actor) : IsRightHandGrabbing(Actor); + } + + bool IsGrabbing(const USGVirtualHandComponent* Hand, AActor*& OutActor) const; + + FORCEINLINE bool IsGrabbing(const USGVirtualHandComponent* Hand) const + { + return Hand == HandLeft ? IsLeftHandGrabbing() : IsRightHandGrabbing(); + } + +public: + void GrabLeft(AActor* Actor); + + void GrabRight(AActor* Actor); + + FORCEINLINE void Grab(const USGVirtualHandComponent* Hand, AActor* Actor) + { + return Hand == HandLeft ? GrabLeft(Actor) : GrabRight(Actor); + } + + void ReleaseLeft(); + + void ReleaseRight(); + + FORCEINLINE void Release(const USGVirtualHandComponent* Hand) + { + return Hand == HandLeft ? ReleaseLeft() : ReleaseRight(); + } }; \ No newline at end of file diff --git a/Source/SenseGloveKismet/Private/SGKismet/SGGrabComponentKismetLibrary.cpp b/Source/SenseGloveKismet/Private/SGKismet/SGGrabComponentKismetLibrary.cpp index 5d0e1c0d..1c3f8369 100644 --- a/Source/SenseGloveKismet/Private/SGKismet/SGGrabComponentKismetLibrary.cpp +++ b/Source/SenseGloveKismet/Private/SGKismet/SGGrabComponentKismetLibrary.cpp @@ -102,4 +102,48 @@ void UGrabComponentKismetLibrary::SetAttachmentSocketName(USGGrabComponent* Grab const FName& InAttachmentSocketName) { GrabComponent->SetAttachmentSocketName(InAttachmentSocketName); +} + +EDetachmentRule UGrabComponentKismetLibrary::GetDetachmentLocationRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentLocationRule(); +} + +void UGrabComponentKismetLibrary::SetDetachmentLocationRule(USGGrabComponent* GrabComponent, + const EDetachmentRule InDetachmentLocationRule) +{ + GrabComponent->SetDetachmentLocationRule(InDetachmentLocationRule); +} + +EDetachmentRule UGrabComponentKismetLibrary::GetDetachmentRotationRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentRotationRule(); +} + +void UGrabComponentKismetLibrary::SetDetachmentRotationRule(USGGrabComponent* GrabComponent, + const EDetachmentRule InDetachmentRotationRule) +{ + GrabComponent->SetDetachmentRotationRule(InDetachmentRotationRule); +} + +EDetachmentRule UGrabComponentKismetLibrary::GetDetachmentScaleRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentScaleRule(); +} + +void UGrabComponentKismetLibrary::SetDetachmentScaleRule(USGGrabComponent* GrabComponent, + const EDetachmentRule InDetachmentScaleRule) +{ + GrabComponent->SetDetachmentScaleRule(InDetachmentScaleRule); +} + +bool UGrabComponentKismetLibrary::GetDetachmentInCallModify(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentInCallModify(); +} + +void UGrabComponentKismetLibrary::SetDetachmentInCallModify(USGGrabComponent* GrabComponent, + const bool bInDetachmentInCallModify) +{ + GrabComponent->SetDetachmentInCallModify(bInDetachmentInCallModify); } \ No newline at end of file diff --git a/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp b/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp index 41e26f64..58fa429b 100644 --- a/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp +++ b/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp @@ -145,4 +145,64 @@ USphereComponent* UPawnKismetLibrary::GetRightRingFingertipTouchCollider(const A USphereComponent* UPawnKismetLibrary::GetRightPinkyFingertipTouchCollider(const ASGPawn* Pawn) { return Pawn->GetRightPinkyFingertipTouchCollider(); +} + +bool UPawnKismetLibrary::CanLeftHandGrab(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->CanLeftHandGrab(Actor); +} + +bool UPawnKismetLibrary::IsLeftHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->IsLeftHandGrabbing(Actor); +} + +bool UPawnKismetLibrary::IsLeftHandGrabbing_OutActor(const ASGPawn* Pawn, AActor*& OutActor) +{ + return Pawn->IsLeftHandGrabbing(OutActor); +} + +bool UPawnKismetLibrary::IsLeftHandGrabbing(const ASGPawn* Pawn) +{ + return Pawn->IsLeftHandGrabbing(); +} + +bool UPawnKismetLibrary::CanRightHandGrab(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->CanRightHandGrab(Actor); +} + +bool UPawnKismetLibrary::IsRightHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->IsRightHandGrabbing(Actor); +} + +bool UPawnKismetLibrary::IsRightHandGrabbing_OutActor(const ASGPawn* Pawn) +{ + return Pawn->IsRightHandGrabbing(); +} + +bool UPawnKismetLibrary::IsRightHandGrabbing(const ASGPawn* Pawn, AActor*& OutActor) +{ + return Pawn->IsRightHandGrabbing(); +} + +bool UPawnKismetLibrary::CanGrab(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor) +{ + return Pawn->CanGrab(Hand, Actor); +} + +bool UPawnKismetLibrary::IsGrabbing_Actor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor) +{ + return Pawn->IsGrabbing(Hand, Actor); +} + +bool UPawnKismetLibrary::IsGrabbing_OutActor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, AActor*& OutActor) +{ + return Pawn->IsGrabbing(Hand, OutActor); +} + +bool UPawnKismetLibrary::IsGrabbing(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand) +{ + return Pawn->IsGrabbing(Hand); } \ No newline at end of file diff --git a/Source/SenseGloveKismet/Public/SGKismet/SGGrabComponentKismetLibrary.h b/Source/SenseGloveKismet/Public/SGKismet/SGGrabComponentKismetLibrary.h index ce318377..6697388d 100644 --- a/Source/SenseGloveKismet/Public/SGKismet/SGGrabComponentKismetLibrary.h +++ b/Source/SenseGloveKismet/Public/SGKismet/SGGrabComponentKismetLibrary.h @@ -90,4 +90,32 @@ public: UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") static void SetAttachmentSocketName(UPARAM(ref) USGGrabComponent* GrabComponent, const FName& InAttachmentSocketName); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EDetachmentRule GetDetachmentLocationRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentLocationRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EDetachmentRule InDetachmentLocationRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EDetachmentRule GetDetachmentRotationRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentRotationRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EDetachmentRule InDetachmentRotationRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EDetachmentRule GetDetachmentScaleRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentScaleRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EDetachmentRule InDetachmentScaleRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static bool GetDetachmentInCallModify(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentInCallModify(UPARAM(ref) USGGrabComponent* GrabComponent, + bool bInDetachmentInCallModify); }; \ No newline at end of file diff --git a/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h b/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h index 1b52095e..28f567c2 100644 --- a/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h +++ b/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h @@ -124,4 +124,40 @@ public: UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") static USphereComponent* GetRightPinkyFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool CanLeftHandGrab(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsLeftHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsLeftHandGrabbing_OutActor(const ASGPawn* Pawn, AActor*& OutActor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsLeftHandGrabbing(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool CanRightHandGrab(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsRightHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsRightHandGrabbing_OutActor(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsRightHandGrabbing(const ASGPawn* Pawn, AActor*& OutActor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool CanGrab(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsGrabbing_Actor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsGrabbing_OutActor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, AActor*& OutActor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsGrabbing(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand); }; \ No newline at end of file