apply the hand's velocity to the grabbed actor after release
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user