apply the hand's velocity to the grabbed actor after release

This commit is contained in:
Mamadou Babaei
2023-08-14 17:25:48 +02:00
parent d4e92546e3
commit bb63748644
2 changed files with 95 additions and 54 deletions
+6
View File
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Now, the hand's velocity is applied to grabbed actors after being released from the hand.
## [1.5.3] - 2023-07-19 ## [1.5.3] - 2023-07-19
This is a hotfix release mostly addressing Android Bluetooth performance issues. This is a hotfix release mostly addressing Android Bluetooth performance issues.
@@ -83,6 +83,14 @@ struct ASGPawn::FImpl
void DisableActorPhysics(const AActor* Actor) const; void DisableActorPhysics(const AActor* Actor) const;
void EnableActorPhysics(const AActor* Actor) const; void EnableActorPhysics(const AActor* Actor) const;
void ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabState) const;
void SetGrabbedActor(FSGGrabState& GrabState, AActor* Actor) const;
void SetLeftHandGrabbedActor(AActor* Actor) const;
void SetRightHandGrabbedActor(AActor* Actor) const;
void Release(FSGGrabState& GrabState) const;
}; };
ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer) ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
@@ -1147,11 +1155,11 @@ void ASGPawn::Grab(USGVirtualHandComponent* Hand, AActor* Actor)
{ {
if (Hand->IsRight()) if (Hand->IsRight())
{ {
RightHandGrabState.GrabbedActor = Actor; Pimpl->SetRightHandGrabbedActor(Actor);
} }
else else
{ {
LeftHandGrabState.GrabbedActor = Actor; Pimpl->SetLeftHandGrabbedActor(Actor);
} }
} }
else else
@@ -1169,69 +1177,23 @@ void ASGPawn::Grab(USGVirtualHandComponent* Hand, AActor* Actor)
Actor->AttachToComponent(Hand, MoveTemp(AttachmentRules), SocketName); Actor->AttachToComponent(Hand, MoveTemp(AttachmentRules), SocketName);
if (Hand->IsRight()) if (Hand->IsRight())
{ {
RightHandGrabState.GrabbedActor = Actor; Pimpl->SetRightHandGrabbedActor(Actor);
} }
else else
{ {
LeftHandGrabState.GrabbedActor = Actor; Pimpl->SetLeftHandGrabbedActor(Actor);
} }
#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 2 */ #endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 2 */
} }
void ASGPawn::ReleaseLeft() void ASGPawn::ReleaseLeft()
{ {
if (!IsValid(LeftHandGrabState.GrabbedActor)) Pimpl->Release(LeftHandGrabState);
{
return;
}
const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(LeftHandGrabState.GrabbedActor)};
if (!IsValid(GrabComponent))
{
return;
}
LeftHandGrabState.GrabbedActor->DetachFromActor(
FDetachmentTransformRules(GrabComponent->GetDetachmentLocationRule(),
GrabComponent->GetDetachmentRotationRule(),
GrabComponent->GetDetachmentScaleRule(),
GrabComponent->GetDetachmentInCallModify())
);
if (GrabComponent->GetAffectPhysicsState())
{
Pimpl->EnableActorPhysics(LeftHandGrabState.GrabbedActor);
}
LeftHandGrabState.GrabbedActor = nullptr;
} }
void ASGPawn::ReleaseRight() void ASGPawn::ReleaseRight()
{ {
if (!IsValid(RightHandGrabState.GrabbedActor)) Pimpl->Release(RightHandGrabState);
{
return;
}
const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(RightHandGrabState.GrabbedActor)};
if (!IsValid(GrabComponent))
{
return;
}
RightHandGrabState.GrabbedActor->DetachFromActor(
FDetachmentTransformRules(GrabComponent->GetDetachmentLocationRule(),
GrabComponent->GetDetachmentRotationRule(),
GrabComponent->GetDetachmentScaleRule(),
GrabComponent->GetDetachmentInCallModify())
);
if (GrabComponent->GetAffectPhysicsState())
{
Pimpl->EnableActorPhysics(RightHandGrabState.GrabbedActor);
}
RightHandGrabState.GrabbedActor = nullptr;
} }
ASGPawn::FImpl::FImpl(ASGPawn* InOwner) ASGPawn::FImpl::FImpl(ASGPawn* InOwner)
@@ -1429,7 +1391,6 @@ void ASGPawn::FImpl::UnbindFingerTouchOverlapEvents()
void ASGPawn::FImpl::DisableActorPhysics(const AActor* Actor) const void ASGPawn::FImpl::DisableActorPhysics(const AActor* Actor) const
{ {
UPrimitiveComponent* ActorRootComponent{Cast<UPrimitiveComponent>(Actor->GetRootComponent())}; UPrimitiveComponent* ActorRootComponent{Cast<UPrimitiveComponent>(Actor->GetRootComponent())};
if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("RootComponent is not a valid UPrimativeComponent!"))) if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("RootComponent is not a valid UPrimativeComponent!")))
{ {
return; return;
@@ -1437,6 +1398,7 @@ void ASGPawn::FImpl::DisableActorPhysics(const AActor* Actor) const
ActorRootComponent->SetEnableGravity(false); ActorRootComponent->SetEnableGravity(false);
ActorRootComponent->SetSimulatePhysics(false); ActorRootComponent->SetSimulatePhysics(false);
ActorRootComponent->PutRigidBodyToSleep();
} }
void ASGPawn::FImpl::EnableActorPhysics(const AActor* Actor) const void ASGPawn::FImpl::EnableActorPhysics(const AActor* Actor) const
@@ -1447,7 +1409,6 @@ void ASGPawn::FImpl::EnableActorPhysics(const AActor* Actor) const
} }
UPrimitiveComponent* ActorRootComponent{Cast<UPrimitiveComponent>(Actor->GetRootComponent())}; UPrimitiveComponent* ActorRootComponent{Cast<UPrimitiveComponent>(Actor->GetRootComponent())};
if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("RootComponent is not a valid UPrimativeComponent!"))) if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("RootComponent is not a valid UPrimativeComponent!")))
{ {
return; return;
@@ -1455,6 +1416,80 @@ void ASGPawn::FImpl::EnableActorPhysics(const AActor* Actor) const
ActorRootComponent->SetEnableGravity(true); ActorRootComponent->SetEnableGravity(true);
ActorRootComponent->SetSimulatePhysics(true); ActorRootComponent->SetSimulatePhysics(true);
ActorRootComponent->WakeRigidBody();
}
void ASGPawn::FImpl::ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabState) const
{
if (!IsValid(GrabState.Hand))
{
return;
}
if (!IsValid(GrabState.GrabbedActor))
{
return;
}
UPrimitiveComponent* ActorRootComponent{Cast<UPrimitiveComponent>(GrabState.GrabbedActor->GetRootComponent())};
if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("RootComponent is not a valid UPrimativeComponent!")))
{
return;
}
/// NOTE: this produces almost the same values
// FVector ActorVelocity{
// (GrabState.GrabbedActor->GetActorLocation() - GrabState.PreviousLocation) / DeltaSeconds
// };
FVector ActorVelocity{GrabState.GrabbedActor->GetVelocity()};
ActorRootComponent->SetPhysicsLinearVelocity(ActorVelocity);
ActorRootComponent->AddImpulse(MoveTemp(ActorVelocity), NAME_None, true);
}
void ASGPawn::FImpl::SetGrabbedActor(FSGGrabState& GrabState, AActor* Actor) const
{
GrabState.GrabbedActor = Actor;
}
void ASGPawn::FImpl::SetLeftHandGrabbedActor(AActor* Actor) const
{
SetGrabbedActor(Owner->LeftHandGrabState, Actor);
}
void ASGPawn::FImpl::SetRightHandGrabbedActor(AActor* Actor) const
{
SetGrabbedActor(Owner->RightHandGrabState, Actor);
}
void ASGPawn::FImpl::Release(FSGGrabState& GrabState) const
{
if (!IsValid(GrabState.GrabbedActor))
{
return;
}
const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(GrabState.GrabbedActor)};
if (!IsValid(GrabComponent))
{
return;
}
GrabState.GrabbedActor->DetachFromActor(
FDetachmentTransformRules(GrabComponent->GetDetachmentLocationRule(),
GrabComponent->GetDetachmentRotationRule(),
GrabComponent->GetDetachmentScaleRule(),
GrabComponent->GetDetachmentInCallModify())
);
if (GrabComponent->GetAffectPhysicsState())
{
EnableActorPhysics(GrabState.GrabbedActor);
}
ApplyHandVelocityToGrabbedActor(GrabState);
SetGrabbedActor(GrabState, nullptr);
} }
ASGPawn::FImpl::~FImpl() = default; ASGPawn::FImpl::~FImpl() = default;