// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. #include "WidgetInteraction.h" #include "HeadMountedDisplayFunctionLibrary.h" #include "IDisplayCluster.h" #include "IDisplayClusterClusterManager.h" #include "Engine.h" #define LOCTEXT_NAMESPACE "FWidgetInteractionModule" void FWidgetInteractionModule::StartupModule() { on_world_tick_start_delegate_.BindRaw(this, &FWidgetInteractionModule::OnWorldTickStart); FWorldDelegates::OnWorldTickStart.Add(on_world_tick_start_delegate_); } void FWidgetInteractionModule::ShutdownModule() { } void FWidgetInteractionModule::OnWorldTickStart(ELevelTick level_tick, float val) { //called every Tick() auto worlds = GEngine->GetWorldContexts(); for (auto world_context : worlds) { auto world = world_context.World(); if (last_world == world && widget_interaction_cmp_ != nullptr) { if (widget_interaction_cmp_->IsValidLowLevel() == true) { continue; } else { widget_interaction_cmp_ = nullptr; } } if (world == nullptr) continue; auto player_controller = world->GetFirstPlayerController(); if (player_controller == nullptr) continue; auto vr_pawn = dynamic_cast<AVirtualRealityPawn*>(player_controller->AcknowledgedPawn); if (vr_pawn == nullptr) continue; UE_LOG(LogTemp, Warning, TEXT("OnWorldTickStart called and interaction component will be updated")); FString name = ""; UClass* component_class = UMotionControllerComponent::StaticClass(); if (IDisplayCluster::Get().GetClusterMgr()->IsStandalone()) { //if this is a standalone setup ... if (UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayEnabled()) { //.. with an HMD, we attach the intercation component to the right hand name = FString("RightMotionController"); component_class = UMotionControllerComponent::StaticClass(); } else { //... without an HMD, we also attach it to the virtual right hand, since it exists in this case name = TEXT("RightMotionController"); component_class = UMotionControllerComponent::StaticClass(); } } else { //if this is a cluster setup we attach it to the flystick name = TEXT("flystick"); component_class = UMotionControllerComponent::StaticClass(); } auto parent_vec = vr_pawn->GetComponentsByClass(component_class); bool success; for (auto parent : parent_vec) { if (parent->GetName() == FString(name)) { CreateWidgetInteraction(dynamic_cast<USceneComponent*>(parent), vr_pawn); success = true; last_world = world; } } if (!success) UE_LOG(LogTemp, Error, TEXT("Failed to load widget asset \"%s"), *name); } } void FWidgetInteractionModule::CreateWidgetInteraction(USceneComponent * parent, AVirtualRealityPawn* outer) { widget_interaction_cmp_ = NewObject<URwthComponent>(outer, URwthComponent::StaticClass()); widget_interaction_cmp_->AttachToComponent(parent, FAttachmentTransformRules(EAttachmentRule::KeepRelative, false)); widget_interaction_cmp_->Init(); } #undef LOCTEXT_NAMESPACE IMPLEMENT_MODULE(FWidgetInteractionModule, WidgetInteraction)