Skip to content
Snippets Groups Projects
Commit 3b500ecd authored by David Gilbert's avatar David Gilbert :bug:
Browse files

Merge branch 'dev/5.4' into '5.4'

UE5.4-2024.1-rc1

Closes #659

See merge request !107
parents 3da9a6a2 0b09ea2f
No related branches found
No related tags found
2 merge requests!111Backport 5.4 Zenodo ref change,!107UE5.4-2024.1-rc1
Pipeline #492045 passed
Showing
with 211 additions and 47 deletions
...@@ -42,7 +42,7 @@ include: ...@@ -42,7 +42,7 @@ include:
variables: variables:
UNREAL_VERSION: "5.4" UNREAL_VERSION: "5.4"
CUSTOM_NDISPLAY_CONFIG: "aixcave_5_3_dev.ndisplay" CUSTOM_NDISPLAY_CONFIG: "aixcave_5_4.ndisplay"
stages: stages:
- analyze - analyze
...@@ -83,7 +83,7 @@ Generate_Project: ...@@ -83,7 +83,7 @@ Generate_Project:
RUN_SETUP: "false" RUN_SETUP: "false"
GEN_DEPENDENCIES: "( GEN_DEPENDENCIES: "(
[master@UnrealDTrackPlugin]='https://github.com/VRGroupRWTH/UnrealDTrackPlugin.git' [master@UnrealDTrackPlugin]='https://github.com/VRGroupRWTH/UnrealDTrackPlugin.git'
[dev/5.3@RWTHVRCluster]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-cluster-plugin.git' [dev/5.4@RWTHVRCluster]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-cluster-plugin.git'
)" )"
Generate_Project_Without_Cluster: Generate_Project_Without_Cluster:
......
...@@ -18,4 +18,15 @@ ...@@ -18,4 +18,15 @@
+FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginInteraction") +FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginInteraction")
+FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndInteraction") +FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndInteraction")
+PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousInteractableComponentsInRange") +PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousInteractableComponentsInRange")
+PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentInteractableComponentsInRange") +PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentInteractableComponentsInRange")
\ No newline at end of file +PropertyRedirects = (OldName="/Script/RWTHVRToolkit.TurnComponent.DesktopRotation",NewName="/Script/RWTHVRToolkit.TurnComponent.DesktopTurnCondition")
+PropertyRedirects = (OldName="/Script/RWTHVRToolkit.TurnComponent.Turn",NewName="/Script/RWTHVRToolkit.TurnComponent.XRTurn")
+PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent.WidgetClickInputAction",NewName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent.WidgetLeftClickInputAction")
+FunctionRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent.OnBeginClick",NewName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent.OnBeginLeftClick")
+FunctionRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent.OnEndClick",NewName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent.OnEndLeftClick")
+FunctionRedirects=(OldName="/Script/RWTHVRToolkit.UBaseInteractionComponent.OnBeginInteraction",NewName="/Script/RWTHVRToolkit.UBaseInteractionComponent.OnBeginInteractionInputAction")
+FunctionRedirects=(OldName="/Script/RWTHVRToolkit.UBaseInteractionComponent.OnEndInteraction",NewName="/Script/RWTHVRToolkit.UBaseInteractionComponent.OnEndInteractionInputAction")
+FunctionRedirects=(OldName="/Script/RWTHVRToolkit.UBaseInteractionComponent.MulticastHoverBehaviourStartRpc",NewName="/Script/RWTHVRToolkit.UBaseInteractionComponent.MulticastHoverBehaviourReplicationStartRpc")
+FunctionRedirects=(OldName="/Script/RWTHVRToolkit.UBaseInteractionComponent.MulticastActionBehaviourStartRpc",NewName="/Script/RWTHVRToolkit.UBaseInteractionComponent.MulticastActionBehaviourReplicationStartRpc")
+FunctionRedirects=(OldName="/Script/RWTHVRToolkit.ActionBehaviour.OnActionStart",NewName="/Script/RWTHVRToolkit.ActionBehaviour.OnActionEvent")
+PropertyRedirects=(OldName="/Script/RWTHVRToolkit.ActionBehaviour.OnActionBeginEvent",NewName="/Script/RWTHVRToolkit.ActionBehaviour.OnActionEventEvent")
\ No newline at end of file
No preview for this file type
No preview for this file type
File deleted
File added
File added
No preview for this file type
File added
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
...@@ -7,9 +7,15 @@ ...@@ -7,9 +7,15 @@
#include "GameFramework/SpectatorPawn.h" #include "GameFramework/SpectatorPawn.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Logging/StructuredLog.h" #include "Logging/StructuredLog.h"
#include "Pawn/ClusterRepresentationActor.h"
#include "Utility/RWTHVRUtilities.h" #include "Utility/RWTHVRUtilities.h"
ARWTHVRGameModeBase::ARWTHVRGameModeBase(const FObjectInitializer& ObjectInitializer)
{
PlayerStateClass = ARWTHVRPlayerState::StaticClass();
}
FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId, FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId,
const FString& Options, const FString& Portal) const FString& Options, const FString& Portal)
{ {
...@@ -17,6 +23,7 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle ...@@ -17,6 +23,7 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle
// but I don't really want to introduce a hard dependency here. // but I don't really want to introduce a hard dependency here.
const FString NodeNameKey = "node"; const FString NodeNameKey = "node";
const FString PrimaryNodeIdKey = "PrimaryNodeId"; const FString PrimaryNodeIdKey = "PrimaryNodeId";
const FString ClusterIdKey = "ClusterId";
// Check if we're using our custom PlayerState so that we can save the player type there. // Check if we're using our custom PlayerState so that we can save the player type there.
// If not, just ingore all related args. // If not, just ingore all related args.
...@@ -24,6 +31,7 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle ...@@ -24,6 +31,7 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle
if (State != nullptr) if (State != nullptr)
{ {
int32 ClusterId = -1;
if (UGameplayStatics::HasOption(Options, PrimaryNodeIdKey)) if (UGameplayStatics::HasOption(Options, PrimaryNodeIdKey))
{ {
const FString PrimaryNodeId = UGameplayStatics::ParseOption(Options, PrimaryNodeIdKey); const FString PrimaryNodeId = UGameplayStatics::ParseOption(Options, PrimaryNodeIdKey);
...@@ -34,10 +42,22 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle ...@@ -34,10 +42,22 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle
? UGameplayStatics::ParseOption(Options, NodeNameKey) ? UGameplayStatics::ParseOption(Options, NodeNameKey)
: PrimaryNodeId; : PrimaryNodeId;
ClusterId = UGameplayStatics::HasOption(Options, ClusterIdKey)
? FCString::Atoi(*UGameplayStatics::ParseOption(Options, ClusterIdKey))
: -1;
const EPlayerType Type = const EPlayerType Type =
NodeName == PrimaryNodeId ? EPlayerType::nDisplayPrimary : EPlayerType::nDisplaySecondary; NodeName == PrimaryNodeId ? EPlayerType::nDisplayPrimary : EPlayerType::nDisplaySecondary;
State->RequestSetPlayerType(Type); State->RequestSetPlayerType(Type);
} }
else if (GetNetMode() == NM_Standalone && URWTHVRUtilities::IsRoomMountedMode())
{
ClusterId = 0;
const EPlayerType Type =
URWTHVRUtilities::IsPrimaryNode() ? EPlayerType::nDisplayPrimary : EPlayerType::nDisplaySecondary;
State->RequestSetPlayerType(Type);
}
State->SetCorrespondingClusterId(ClusterId);
} }
return Super::InitNewPlayer(NewPlayerController, UniqueId, Options, Portal); return Super::InitNewPlayer(NewPlayerController, UniqueId, Options, Portal);
...@@ -45,8 +65,47 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle ...@@ -45,8 +65,47 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle
void ARWTHVRGameModeBase::PostLogin(APlayerController* NewPlayer) void ARWTHVRGameModeBase::PostLogin(APlayerController* NewPlayer)
{ {
if (const ARWTHVRPlayerState* State = Cast<ARWTHVRPlayerState>(NewPlayer->PlayerState); State != nullptr) if (ARWTHVRPlayerState* State = Cast<ARWTHVRPlayerState>(NewPlayer->PlayerState); State != nullptr)
{ {
// If we're in none-standalone netmode, this is only executed on the server, as the GM only exists there.
// On standalone, this is executed on every node.
int32 ClusterId = State->GetCorrespondingClusterId();
if (ClusterId >= 0) // we're either standalone (0) or in an acutal cluster
{
AClusterRepresentationActor** ClusterRepresentationPtr = ConnectedClusters.Find(ClusterId);
AClusterRepresentationActor* ClusterRepresentation;
if (!ClusterRepresentationPtr)
{
// No actor there yet, spawn it
FActorSpawnParameters SpawnParameters;
SpawnParameters.Name = FName(*FString::Printf(TEXT("ClusterRepresentation_%d"), ClusterId));
SpawnParameters.NameMode = FActorSpawnParameters::ESpawnActorNameMode::Requested;
ClusterRepresentation = GetWorld()->SpawnActor<AClusterRepresentationActor>(SpawnParameters);
UE_LOGFMT(Toolkit, Display,
"ARWTHVRGameModeBase: Spawned ClusterRepresentationActor {Name} for Cluster {Id}",
ClusterRepresentation->GetName(), ClusterId);
ConnectedClusters.Add(ClusterId, ClusterRepresentation);
}
else
{
ClusterRepresentation = *ClusterRepresentationPtr;
}
UE_LOGFMT(Toolkit, Display, "ARWTHVRGameModeBase: Using ClusterRepresentationActor {Name} for Cluster {Id}",
*ClusterRepresentation->GetName(), ClusterId);
// Double check for sanity
check(ClusterRepresentation != nullptr);
State->SetCorrespondingClusterActor(ClusterRepresentation);
if (State->GetPlayerType() == EPlayerType::nDisplayPrimary)
{
// We're the owner of the actor!
ClusterRepresentation->SetOwner(NewPlayer);
}
}
// Do we already have an auto-possessing pawn possessed? // Do we already have an auto-possessing pawn possessed?
if (NewPlayer->GetPawn() && NewPlayer->GetPawn()->IsValidLowLevelFast()) if (NewPlayer->GetPawn() && NewPlayer->GetPawn()->IsValidLowLevelFast())
{ {
...@@ -56,10 +115,11 @@ void ARWTHVRGameModeBase::PostLogin(APlayerController* NewPlayer) ...@@ -56,10 +115,11 @@ void ARWTHVRGameModeBase::PostLogin(APlayerController* NewPlayer)
return; return;
} }
// When we're not in standalone:
// If the new player is a secondary nDisplay node, spawn it only as a Spectator // If the new player is a secondary nDisplay node, spawn it only as a Spectator
// Potentially we can use MustSpectate instead. // Potentially we can use MustSpectate instead.
UClass* PawnClass; UClass* PawnClass;
if (State->GetPlayerType() == EPlayerType::nDisplaySecondary) if (GetNetMode() != NM_Standalone && State->GetPlayerType() == EPlayerType::nDisplaySecondary)
{ {
// For now, simply use the BP approach of spawning the pawn here. Can do this in a better way potentially. // For now, simply use the BP approach of spawning the pawn here. Can do this in a better way potentially.
PawnClass = SpectatorClass; PawnClass = SpectatorClass;
...@@ -83,11 +143,20 @@ void ARWTHVRGameModeBase::PostLogin(APlayerController* NewPlayer) ...@@ -83,11 +143,20 @@ void ARWTHVRGameModeBase::PostLogin(APlayerController* NewPlayer)
} }
} }
if (GetNetMode() == NM_Standalone)
{
const FName BaseName = PawnClass->HasAnyFlags(RF_ClassDefaultObject)
? PawnClass->GetFName()
: *PawnClass->GetFName().GetPlainNameString();
SpawnInfo.Name = BaseName;
SpawnInfo.NameMode = FActorSpawnParameters::ESpawnActorNameMode::Requested;
}
// Spawn and possess the pawn // Spawn and possess the pawn
APawn* ResultPawn = GetWorld()->SpawnActor<APawn>(PawnClass, StartSpot->GetTransform(), SpawnInfo); APawn* ResultPawn = GetWorld()->SpawnActor<APawn>(PawnClass, StartSpot->GetTransform(), SpawnInfo);
NewPlayer->Possess(ResultPawn); NewPlayer->Possess(ResultPawn);
} }
Super::PostLogin(NewPlayer); Super::PostLogin(NewPlayer);
} }
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
#include "Core/RWTHVRPlayerState.h" #include "Core/RWTHVRPlayerState.h"
#include "Logging/StructuredLog.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#include "Net/Core/PushModel/PushModel.h" #include "Net/Core/PushModel/PushModel.h"
#include "Utility/RWTHVRUtilities.h"
// Boilerplate, copies properties to new state // Boilerplate, copies properties to new state
void ARWTHVRPlayerState::CopyProperties(class APlayerState* PlayerState) void ARWTHVRPlayerState::CopyProperties(class APlayerState* PlayerState)
...@@ -17,6 +19,8 @@ void ARWTHVRPlayerState::CopyProperties(class APlayerState* PlayerState) ...@@ -17,6 +19,8 @@ void ARWTHVRPlayerState::CopyProperties(class APlayerState* PlayerState)
if (IsValid(RWTHVRPlayerState)) if (IsValid(RWTHVRPlayerState))
{ {
RWTHVRPlayerState->SetPlayerType(GetPlayerType()); RWTHVRPlayerState->SetPlayerType(GetPlayerType());
RWTHVRPlayerState->SetCorrespondingClusterId(CorrespondingClusterId);
RWTHVRPlayerState->SetCorrespondingClusterActor(CorrespondingClusterActor);
} }
} }
} }
...@@ -32,6 +36,8 @@ void ARWTHVRPlayerState::OverrideWith(class APlayerState* PlayerState) ...@@ -32,6 +36,8 @@ void ARWTHVRPlayerState::OverrideWith(class APlayerState* PlayerState)
if (IsValid(RWTHVRPlayerState)) if (IsValid(RWTHVRPlayerState))
{ {
SetPlayerType(RWTHVRPlayerState->GetPlayerType()); SetPlayerType(RWTHVRPlayerState->GetPlayerType());
SetCorrespondingClusterId(RWTHVRPlayerState->CorrespondingClusterId);
SetCorrespondingClusterActor(RWTHVRPlayerState->CorrespondingClusterActor);
} }
} }
} }
...@@ -45,6 +51,8 @@ void ARWTHVRPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& O ...@@ -45,6 +51,8 @@ void ARWTHVRPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& O
SharedParams.bIsPushBased = true; SharedParams.bIsPushBased = true;
DOREPLIFETIME_WITH_PARAMS_FAST(ARWTHVRPlayerState, PlayerType, SharedParams); DOREPLIFETIME_WITH_PARAMS_FAST(ARWTHVRPlayerState, PlayerType, SharedParams);
DOREPLIFETIME_WITH_PARAMS_FAST(ARWTHVRPlayerState, CorrespondingClusterId, SharedParams);
DOREPLIFETIME_WITH_PARAMS_FAST(ARWTHVRPlayerState, CorrespondingClusterActor, SharedParams);
} }
void ARWTHVRPlayerState::ServerSetPlayerTypeRpc_Implementation(const EPlayerType NewPlayerType) void ARWTHVRPlayerState::ServerSetPlayerTypeRpc_Implementation(const EPlayerType NewPlayerType)
...@@ -57,6 +65,28 @@ void ARWTHVRPlayerState::SetPlayerType(const EPlayerType NewPlayerType) ...@@ -57,6 +65,28 @@ void ARWTHVRPlayerState::SetPlayerType(const EPlayerType NewPlayerType)
MARK_PROPERTY_DIRTY_FROM_NAME(ARWTHVRPlayerState, PlayerType, this); MARK_PROPERTY_DIRTY_FROM_NAME(ARWTHVRPlayerState, PlayerType, this);
PlayerType = NewPlayerType; PlayerType = NewPlayerType;
} }
void ARWTHVRPlayerState::SetCorrespondingClusterId(int32 NewCorrespondingClusterId)
{
if (!HasAuthority())
{
UE_LOGFMT(Toolkit, Warning, "ARWTHVRPlayerState: Cannot set cluster Id on non-authority!");
return;
}
MARK_PROPERTY_DIRTY_FROM_NAME(ARWTHVRPlayerState, CorrespondingClusterId, this);
CorrespondingClusterId = NewCorrespondingClusterId;
}
void ARWTHVRPlayerState::SetCorrespondingClusterActor(AClusterRepresentationActor* NewCorrespondingClusterActor)
{
if (!HasAuthority())
{
UE_LOGFMT(Toolkit, Warning, "ARWTHVRPlayerState: Cannot set cluster actor ref on non-authority!");
return;
}
MARK_PROPERTY_DIRTY_FROM_NAME(ARWTHVRPlayerState, CorrespondingClusterActor, this);
CorrespondingClusterActor = NewCorrespondingClusterActor;
}
void ARWTHVRPlayerState::RequestSetPlayerType(const EPlayerType NewPlayerType) void ARWTHVRPlayerState::RequestSetPlayerType(const EPlayerType NewPlayerType)
{ {
......
...@@ -6,27 +6,14 @@ ...@@ -6,27 +6,14 @@
// We disable ticking here, as we are mainly interested in the events // We disable ticking here, as we are mainly interested in the events
UActionBehaviour::UActionBehaviour() { PrimaryComponentTick.bCanEverTick = false; } UActionBehaviour::UActionBehaviour() { PrimaryComponentTick.bCanEverTick = false; }
void UActionBehaviour::OnActionStart(USceneComponent* TriggeredComponent, const UInputAction* InputAction, void UActionBehaviour::OnActionEvent(USceneComponent* TriggerComponent, const EInteractionEventType EventType,
const FInputActionValue& Value) const FInputActionValue& Value)
{ {
} }
void UActionBehaviour::OnActionEnd(USceneComponent* TriggeredComponent, const UInputAction* InputAction,
const FInputActionValue& Value)
{
}
void UActionBehaviour::BeginPlay() void UActionBehaviour::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
OnActionBeginEvent.AddDynamic(this, &UActionBehaviour::OnActionStart); OnActionEventEvent.AddDynamic(this, &UActionBehaviour::OnActionEvent);
OnActionEndEvent.AddDynamic(this, &UActionBehaviour::OnActionEnd);
}
// Called every frame
void UActionBehaviour::TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
} }
// Fill out your copyright notice in the Description page of Project Settings.
#include "Interaction/Interactables/BaseBehaviour.h"
...@@ -3,10 +3,26 @@ ...@@ -3,10 +3,26 @@
#include "Interaction/Interactables/GrabBehavior.h" #include "Interaction/Interactables/GrabBehavior.h"
#include "Interaction/Interactables/InteractableComponent.h" #include "Interaction/Interactables/InteractableComponent.h"
#include "Interaction/Interactables/InteractionEventType.h"
#include "Logging/StructuredLog.h" #include "Logging/StructuredLog.h"
#include "Pawn/Navigation/CollisionHandlingMovement.h"
#include "Serialization/JsonTypes.h" #include "Serialization/JsonTypes.h"
#include "Utility/RWTHVRUtilities.h" #include "Utility/RWTHVRUtilities.h"
UGrabBehavior::UGrabBehavior()
{
SetIsReplicatedByDefault(true);
bExecuteOnServer = true;
bExecuteOnAllClients = false;
}
void UGrabBehavior::BeginPlay()
{
Super::BeginPlay();
OnActionReplicationStartedOriginatorEvent.AddDynamic(this, &UGrabBehavior::ReplicationOriginaterClientCallback);
}
UPrimitiveComponent* UGrabBehavior::GetFirstComponentSimulatingPhysics(const AActor* TargetActor) UPrimitiveComponent* UGrabBehavior::GetFirstComponentSimulatingPhysics(const AActor* TargetActor)
{ {
TArray<UPrimitiveComponent*> PrimitiveComponents; TArray<UPrimitiveComponent*> PrimitiveComponents;
...@@ -33,16 +49,79 @@ UPrimitiveComponent* UGrabBehavior::GetHighestParentSimulatingPhysics(UPrimitive ...@@ -33,16 +49,79 @@ UPrimitiveComponent* UGrabBehavior::GetHighestParentSimulatingPhysics(UPrimitive
return Comp; return Comp;
} }
void UGrabBehavior::ReplicationOriginaterClientCallback(USceneComponent* TriggerComponent,
const EInteractionEventType EventType,
const FInputActionValue& Value)
{
const USceneComponent* CurrentAttachParent = Cast<USceneComponent>(TriggerComponent->GetAttachParent());
HandleCollisionHandlingMovement(CurrentAttachParent, EventType);
}
void UGrabBehavior::OnActionStart(USceneComponent* TriggeredComponent, const UInputAction* InputAction, void UGrabBehavior::HandleCollisionHandlingMovement(const USceneComponent* CurrentAttachParent,
const EInteractionEventType EventType)
{
auto CHM = CurrentAttachParent->GetOwner()->GetComponentByClass<UCollisionHandlingMovement>();
if (!CHM)
return;
if (EventType == EInteractionEventType::InteractionStart)
{
// Add to ignore list for collision handling movement, if it exists
if (bIgnoreGrabbedActorInCollisionMovement)
{
bWasAddedToIgnore = CHM->AddActorToIgnore(GetOwner());
}
}
else
{
// If our attach parent has a collision handling component, remove
if (bWasAddedToIgnore)
{
CHM->RemoveActorFromIgnore(GetOwner());
}
}
}
void UGrabBehavior::OnActionEvent(USceneComponent* TriggerComponent, const EInteractionEventType EventType,
const FInputActionValue& Value) const FInputActionValue& Value)
{
if (EventType == EInteractionEventType::InteractionStart)
{
StartGrab(TriggerComponent);
}
else
{
EndGrab(TriggerComponent);
}
}
bool UGrabBehavior::TryRelease()
{
if (!bObjectGrabbed)
{
UE_LOGFMT(Toolkit, Display, "UGrabBehavior::TryRelease: bObjectGrabbed was false!");
return false;
}
if (MyPhysicsComponent)
{
MyPhysicsComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
MyPhysicsComponent->SetSimulatePhysics(bWasSimulatingPhysics);
}
else
{
GetOwner()->GetRootComponent()->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
}
bObjectGrabbed = false;
return true;
}
void UGrabBehavior::StartGrab(USceneComponent* TriggerComponent)
{ {
if (bObjectGrabbed) if (bObjectGrabbed)
{ {
return; return;
} }
USceneComponent* CurrentAttachParent = Cast<USceneComponent>(TriggeredComponent->GetAttachParent()); USceneComponent* CurrentAttachParent = Cast<USceneComponent>(TriggerComponent->GetAttachParent());
const FAttachmentTransformRules Rules = FAttachmentTransformRules(EAttachmentRule::KeepWorld, false); const FAttachmentTransformRules Rules = FAttachmentTransformRules(EAttachmentRule::KeepWorld, false);
if (MyPhysicsComponent = GetFirstComponentSimulatingPhysics(GetOwner()); MyPhysicsComponent != nullptr) if (MyPhysicsComponent = GetFirstComponentSimulatingPhysics(GetOwner()); MyPhysicsComponent != nullptr)
...@@ -72,18 +151,19 @@ void UGrabBehavior::OnActionStart(USceneComponent* TriggeredComponent, const UIn ...@@ -72,18 +151,19 @@ void UGrabBehavior::OnActionStart(USceneComponent* TriggeredComponent, const UIn
GetOwner()->GetComponents<UInteractableComponent>(Interactables, false); GetOwner()->GetComponents<UInteractableComponent>(Interactables, false);
for (UInteractableComponent* Interactable : Interactables) for (UInteractableComponent* Interactable : Interactables)
{ {
Interactable->RestrictInteractionToComponent(TriggeredComponent); Interactable->RestrictInteractionToComponent(TriggerComponent);
} }
} }
OnGrabStartEvent.Broadcast(CurrentAttachParent, MyPhysicsComponent); OnGrabStartEvent.Broadcast(CurrentAttachParent, MyPhysicsComponent);
// Add to ignore list for collision handling movement, if it exists
HandleCollisionHandlingMovement(CurrentAttachParent, InteractionStart);
} }
void UGrabBehavior::OnActionEnd(USceneComponent* TriggeredComponent, const UInputAction* InputAction, void UGrabBehavior::EndGrab(USceneComponent* TriggerComponent)
const FInputActionValue& Value)
{ {
USceneComponent* CurrentAttachParent = Cast<USceneComponent>(TriggerComponent->GetAttachParent());
USceneComponent* CurrentAttachParent = Cast<USceneComponent>(TriggeredComponent->GetAttachParent());
// We try to release the attached component. If it is not succesful we log and return. Otherwise, we continue. // We try to release the attached component. If it is not succesful we log and return. Otherwise, we continue.
if (!TryRelease()) if (!TryRelease())
...@@ -106,24 +186,7 @@ void UGrabBehavior::OnActionEnd(USceneComponent* TriggeredComponent, const UInpu ...@@ -106,24 +186,7 @@ void UGrabBehavior::OnActionEnd(USceneComponent* TriggeredComponent, const UInpu
Interactable->ResetRestrictInteraction(); Interactable->ResetRestrictInteraction();
} }
} }
}
bool UGrabBehavior::TryRelease() // If our attach parent has a collision handling component, remove
{ HandleCollisionHandlingMovement(CurrentAttachParent, InteractionEnd);
if (!bObjectGrabbed)
{
return false;
}
if (MyPhysicsComponent)
{
MyPhysicsComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
MyPhysicsComponent->SetSimulatePhysics(bWasSimulatingPhysics);
}
else
{
GetOwner()->GetRootComponent()->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
}
bObjectGrabbed = false;
return true;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment