add a partial workaround for a bug when the virtual hand inside the game is not visible but still have collisions with other objects inside the scene
This commit is contained in:
@@ -88,6 +88,12 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
|
||||
return FAnimInstanceProxy::Evaluate(Output);
|
||||
}
|
||||
|
||||
const bool bIsVisible = VirtualHand->IsVisible() && VirtualHand->GetVisibleFlag();
|
||||
if (!bIsVisible)
|
||||
{
|
||||
return FAnimInstanceProxy::Evaluate(Output);
|
||||
}
|
||||
|
||||
const USkeletalMesh* HandMesh{VirtualHand->GetSkeletalMeshAsset()};
|
||||
if (!IsValid(HandMesh))
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "Animation/Skeleton.h"
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Engine/EngineTypes.h"
|
||||
#include "Engine/SkeletalMesh.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "IXRTrackingSystem.h"
|
||||
@@ -94,6 +95,12 @@ struct USGVirtualHandComponent::FImpl
|
||||
return Settings->GetTrackingSettings().VirtualHandTrackingSettings;
|
||||
}
|
||||
|
||||
/************************
|
||||
* Member variables
|
||||
************************/
|
||||
|
||||
FCollisionResponseContainer CachedCollisionResponse;
|
||||
|
||||
/************************
|
||||
* Owner object
|
||||
************************/
|
||||
@@ -130,12 +137,11 @@ struct USGVirtualHandComponent::FImpl
|
||||
USkeleton* GetSkeleton() const;
|
||||
const FReferenceSkeleton& GetRefSkeleton() const;
|
||||
|
||||
void UpdateGloveVisibility() const;
|
||||
void DisableCollisionResponse();
|
||||
void RestoreCollisionResponse() const;
|
||||
|
||||
FORCEINLINE void SetVisibility(const bool bInVisible) const
|
||||
{
|
||||
Owner->SetVisibility(bInVisible, true);
|
||||
}
|
||||
void SetVisibility(const bool bInVisible);
|
||||
void UpdateVisibility();
|
||||
|
||||
void DrawDebugVirtualHand() const;
|
||||
};
|
||||
@@ -202,7 +208,7 @@ USGVirtualHandComponent::USGVirtualHandComponent(const FObjectInitializer& Objec
|
||||
Super::SetAnimClass(USGVirtualHandAnimInstance::StaticClass());
|
||||
|
||||
bRight = true;
|
||||
bHiddenInGameIfNoHandDataAvailable = false;
|
||||
bVisibleWhenHandDataUnavailable = false;
|
||||
|
||||
AnimationBoneRotationCorrectionOffset = FRotator{0.0f, 90.0f, 90.0f};
|
||||
bAnimationShouldApplyBoneLocation = true;
|
||||
@@ -289,7 +295,7 @@ void USGVirtualHandComponent::InitializeComponent()
|
||||
Pimpl->SetDefaultMesh();
|
||||
}
|
||||
|
||||
Pimpl->UpdateGloveVisibility();
|
||||
Pimpl->UpdateVisibility();
|
||||
}
|
||||
|
||||
void USGVirtualHandComponent::UninitializeComponent()
|
||||
@@ -308,7 +314,7 @@ void USGVirtualHandComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
Pimpl->UpdateGloveVisibility();
|
||||
Pimpl->UpdateVisibility();
|
||||
}
|
||||
|
||||
void USGVirtualHandComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
@@ -336,7 +342,7 @@ void USGVirtualHandComponent::TickComponent(
|
||||
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
Pimpl->UpdateGloveVisibility();
|
||||
Pimpl->UpdateVisibility();
|
||||
|
||||
if (DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
|
||||
{
|
||||
@@ -359,7 +365,7 @@ void USGVirtualHandComponent::SetSkeletalMesh(USkeletalMesh* NewMesh, const bool
|
||||
void USGVirtualHandComponent::EditorTick(
|
||||
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
Pimpl->UpdateGloveVisibility();
|
||||
Pimpl->UpdateVisibility();
|
||||
|
||||
if (DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
|
||||
{
|
||||
@@ -582,36 +588,49 @@ const FReferenceSkeleton& USGVirtualHandComponent::FImpl::GetRefSkeleton() const
|
||||
return Mesh->GetRefSkeleton();
|
||||
}
|
||||
|
||||
void USGVirtualHandComponent::FImpl::UpdateGloveVisibility() const
|
||||
void USGVirtualHandComponent::FImpl::DisableCollisionResponse()
|
||||
{
|
||||
FXRMotionControllerData MotionControllerData;
|
||||
const bool bGotMotionControllerData = Owner->GetMotionControllerData(MotionControllerData);
|
||||
const bool bIsHandDataAvailable = bGotMotionControllerData && MotionControllerData.bValid;
|
||||
const bool bIsVisible = Owner->IsVisible();
|
||||
CachedCollisionResponse = Owner->GetCollisionResponseToChannels();
|
||||
Owner->SetCollisionResponseToAllChannels(ECR_Ignore);
|
||||
}
|
||||
|
||||
if (Owner->bHiddenInGameIfNoHandDataAvailable)
|
||||
void USGVirtualHandComponent::FImpl::RestoreCollisionResponse() const
|
||||
{
|
||||
Owner->SetCollisionResponseToChannels(CachedCollisionResponse);
|
||||
}
|
||||
|
||||
void USGVirtualHandComponent::FImpl::SetVisibility(const bool bInVisible)
|
||||
{
|
||||
Owner->SetVisibility(bInVisible, true);
|
||||
|
||||
if (bInVisible)
|
||||
{
|
||||
if (bIsHandDataAvailable)
|
||||
{
|
||||
if (!bIsVisible)
|
||||
{
|
||||
SetVisibility(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bIsVisible)
|
||||
{
|
||||
SetVisibility(false);
|
||||
}
|
||||
}
|
||||
RestoreCollisionResponse();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bIsVisible)
|
||||
{
|
||||
SetVisibility(true);
|
||||
}
|
||||
DisableCollisionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
void USGVirtualHandComponent::FImpl::UpdateVisibility()
|
||||
{
|
||||
const bool bUpdateVisibility = !Owner->IsVisibleWhenHandDataUnavailable();
|
||||
if (!bUpdateVisibility)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FXRMotionControllerData MotionControllerData;
|
||||
const bool bGotMotionControllerData = Owner->GetMotionControllerData(MotionControllerData);
|
||||
const bool bHandDataAvailable = bGotMotionControllerData && MotionControllerData.bValid;
|
||||
const bool bVisibleHand = Owner->GetVisibleFlag();
|
||||
const bool bSetNewVisibility =
|
||||
(bHandDataAvailable && !bVisibleHand) || (!bHandDataAvailable && bVisibleHand);
|
||||
|
||||
if (bSetNewVisibility)
|
||||
{
|
||||
SetVisibility(bHandDataAvailable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
|
||||
HandLeft->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
|
||||
HandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
|
||||
HandLeft->SetRight(false);
|
||||
HandLeft->SetHiddenIfNoHandDataAvailable(true);
|
||||
HandLeft->SetVisibleWhenHandDataUnavailable(false);
|
||||
HandLeft->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
|
||||
false, nullptr, ETeleportType::None);
|
||||
HandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f},
|
||||
@@ -232,7 +232,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
|
||||
RealHandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap);
|
||||
RealHandLeft->SetRight(false);
|
||||
Pimpl->SetVisibility(RealHandLeft, false);
|
||||
RealHandLeft->SetHiddenIfNoHandDataAvailable(true);
|
||||
RealHandLeft->SetVisibleWhenHandDataUnavailable(false);
|
||||
RealHandLeft->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
|
||||
false, nullptr, ETeleportType::None);
|
||||
RealHandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f},
|
||||
@@ -430,7 +430,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
|
||||
HandRight->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
|
||||
HandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
|
||||
HandRight->SetRight(true);
|
||||
HandRight->SetHiddenIfNoHandDataAvailable(true);
|
||||
HandRight->SetVisibleWhenHandDataUnavailable(false);
|
||||
HandRight->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
|
||||
false, nullptr, ETeleportType::None);
|
||||
HandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f},
|
||||
@@ -454,7 +454,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
|
||||
RealHandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap);
|
||||
RealHandRight->SetRight(true);
|
||||
Pimpl->SetVisibility(RealHandRight, false);
|
||||
RealHandRight->SetHiddenIfNoHandDataAvailable(true);
|
||||
RealHandRight->SetVisibleWhenHandDataUnavailable(false);
|
||||
RealHandRight->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
|
||||
false, nullptr, ETeleportType::None);
|
||||
RealHandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f},
|
||||
|
||||
@@ -85,7 +85,7 @@ private:
|
||||
uint8 bRight : 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
||||
uint8 bHiddenInGameIfNoHandDataAvailable : 1;
|
||||
uint8 bVisibleWhenHandDataUnavailable : 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="SenseGlove | Animation", meta=(AllowPrivateAccess="false"))
|
||||
FRotator AnimationBoneRotationCorrectionOffset;
|
||||
@@ -290,14 +290,14 @@ public:
|
||||
DebugVirtualHandSettings = InDebugVirtualHandSettings;
|
||||
}
|
||||
|
||||
FORCEINLINE bool IsHiddenInGameIfNoHandDataAvailable() const
|
||||
FORCEINLINE bool IsVisibleWhenHandDataUnavailable() const
|
||||
{
|
||||
return !!bHiddenInGameIfNoHandDataAvailable;
|
||||
return !!bVisibleWhenHandDataUnavailable;
|
||||
}
|
||||
|
||||
FORCEINLINE void SetHiddenIfNoHandDataAvailable(const bool bInHiddenIfNoHandDataAvailable)
|
||||
FORCEINLINE void SetVisibleWhenHandDataUnavailable(const bool bInVisibleWhenHandDataUnavailable)
|
||||
{
|
||||
bHiddenInGameIfNoHandDataAvailable = bInHiddenIfNoHandDataAvailable;
|
||||
bVisibleWhenHandDataUnavailable = bInVisibleWhenHandDataUnavailable;
|
||||
}
|
||||
|
||||
FORCEINLINE void SetWristTracker(USGWristTrackerComponent* InWristTracker)
|
||||
|
||||
@@ -74,16 +74,16 @@ void UVirtualHandComponentKismetLibrary::SetRight(
|
||||
VirtualHandComponent->SetRight(bInRight);
|
||||
}
|
||||
|
||||
bool UVirtualHandComponentKismetLibrary::IsHiddenInGameIfNoHandDataAvailable(
|
||||
bool UVirtualHandComponentKismetLibrary::IsVisibleWhenHandDataUnavailable(
|
||||
const USGVirtualHandComponent* VirtualHandComponent)
|
||||
{
|
||||
return VirtualHandComponent->IsHiddenInGameIfNoHandDataAvailable();
|
||||
return VirtualHandComponent->IsVisibleWhenHandDataUnavailable();
|
||||
}
|
||||
|
||||
void UVirtualHandComponentKismetLibrary::SetHiddenIfNoHandDataAvailable(
|
||||
USGVirtualHandComponent* VirtualHandComponent, const bool bInHiddenIfNoHandDataAvailable)
|
||||
void UVirtualHandComponentKismetLibrary::SetVisibleWhenHandDataUnavailable(
|
||||
USGVirtualHandComponent* VirtualHandComponent, const bool bInIsVisibleWhenHandDataUnavailable)
|
||||
{
|
||||
VirtualHandComponent->SetHiddenIfNoHandDataAvailable(bInHiddenIfNoHandDataAvailable);
|
||||
VirtualHandComponent->SetVisibleWhenHandDataUnavailable(bInIsVisibleWhenHandDataUnavailable);
|
||||
}
|
||||
|
||||
const FRotator& UVirtualHandComponentKismetLibrary::GetAnimationBoneRotationCorrectionOffset(
|
||||
|
||||
@@ -81,11 +81,11 @@ public:
|
||||
static void SetRight(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent, bool bInRight);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
|
||||
static bool IsHiddenInGameIfNoHandDataAvailable(const USGVirtualHandComponent* VirtualHandComponent);
|
||||
static bool IsVisibleWhenHandDataUnavailable(const USGVirtualHandComponent* VirtualHandComponent);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
|
||||
static void SetHiddenIfNoHandDataAvailable(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
|
||||
bool bInHiddenIfNoHandDataAvailable);
|
||||
static void SetVisibleWhenHandDataUnavailable(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
|
||||
bool bInIsVisibleWhenHandDataUnavailable);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
|
||||
static const FRotator& GetAnimationBoneRotationCorrectionOffset(
|
||||
|
||||
Reference in New Issue
Block a user