Skip to content
Snippets Groups Projects
Commit 74a8ec8e authored by Simon Oehrl's avatar Simon Oehrl
Browse files

Merge branch 'feature/update_to_new_VRPawn' into 'develop'

Feature/update to new VRPawn structure and adding an interaction ray that is also available in shipping builds

See merge request VR-Group/unreal-development/widgetinteraction!2
parents 03405f79 3b079eab
No related branches found
No related tags found
1 merge request!2Feature/update to new VRPawn structure and adding an interaction ray that is also available in shipping builds
File added
File added
// Fill out your copyright notice in the Description page of Project Settings.
#include "RwthComponent.h"
#include "VRWidgetInteractionComponent.h"
#include "Runtime/InputCore/Classes/InputCoreTypes.h"
#include "Runtime/Engine/Classes/Components/InputComponent.h"
#include "ConstructorHelpers.h"
#include "Modules/ModuleManager.h"
#include "Interfaces/IPluginManager.h"
#include "VirtualRealityPawn.h"
URwthComponent::URwthComponent()
{
UVRWidgetInteractionComponent::UVRWidgetInteractionComponent() {
InteractionRay = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Interaction Ray"));
//this ray model as a inlayed cross with flipped normals so it can be seen as a cross in desktop mode where the right hand is attached to the head
ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(TEXT("/WidgetInteraction/Ray_Mesh"));
if (MeshAsset.Object != nullptr)
{
InteractionRay->SetStaticMesh(MeshAsset.Object);
}
bShowDebug = false;
}
void URwthComponent::Init()
void UVRWidgetInteractionComponent::Init(USceneComponent* parent)
{
SetVisibility(true);
SetVisibility(true);
InteractionDistance = 1000000.0f;
auto input_cmp = dynamic_cast<UInputComponent*>(GetOwner()->GetComponentByClass(UInputComponent::StaticClass()));
input_cmp->BindAction<FFireDelegate>("Fire", IE_Pressed, this, &URwthComponent::OnFire, true);
input_cmp->BindAction<FFireDelegate>("Fire", IE_Released, this, &URwthComponent::OnFire, false);
input_cmp->BindAction<FFireDelegate>("Fire", IE_Pressed, this, &UVRWidgetInteractionComponent::OnFire, true);
input_cmp->BindAction<FFireDelegate>("Fire", IE_Released, this, &UVRWidgetInteractionComponent::OnFire, false);
RegisterComponent();
InteractionRay->RegisterComponent();
if (parent != nullptr) {
InteractionRay->AttachToComponent(parent, FAttachmentTransformRules::KeepRelativeTransform);
this->AttachToComponent(parent, FAttachmentTransformRules::KeepRelativeTransform);
}
}
void URwthComponent::SetVisibility(bool visible) {
bShowDebug = visible;
void UVRWidgetInteractionComponent::SetVisibility(bool visible) {
InteractionRay->SetVisibility(visible);
}
void URwthComponent::OnFire(bool val)
void UVRWidgetInteractionComponent::OnFire(bool val)
{
if (val == true)
PressPointerKey(EKeys::LeftMouseButton);
else
ReleasePointerKey(EKeys::LeftMouseButton);
}
\ No newline at end of file
}
......@@ -8,6 +8,8 @@
#define LOCTEXT_NAMESPACE "FWidgetInteractionModule"
DEFINE_LOG_CATEGORY(WidgetIntLog);
void FWidgetInteractionModule::StartupModule()
{
on_world_tick_start_delegate_.BindRaw(this, &FWidgetInteractionModule::OnWorldTickStart);
......@@ -21,83 +23,49 @@ 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("HMDRightMotionController");
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("HMDRightMotionController");
component_class = UMotionControllerComponent::StaticClass();
}
}
else {
//if this is a cluster setup we attach it to the flystick
name = TEXT("flystick");
component_class = UDisplayClusterSceneComponent::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\", cannot attach widget interaction component"), *name);
}
//since OnWorldTickStart is called independent of the world/level we are in,
//we need to check whether the level changed and, if so, reattach the interaction component
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;
CreateWidgetInteraction(vr_pawn->GetRightHandComponent(), vr_pawn);
last_world = world;
UE_LOG(WidgetIntLog, Verbose, TEXT("VRInteractionComponent attached to right hand"));
}
}
URwthComponent* FWidgetInteractionModule::GetWidgetInteractionComponent() {
UVRWidgetInteractionComponent* FWidgetInteractionModule::GetWidgetInteractionComponent() {
return widget_interaction_cmp_;
}
void FWidgetInteractionModule::CreateWidgetInteraction(USceneComponent * parent, AVirtualRealityPawn* outer)
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();
widget_interaction_cmp_ = NewObject<UVRWidgetInteractionComponent>(outer, UVRWidgetInteractionComponent::StaticClass());
widget_interaction_cmp_->Init(parent);
}
#undef LOCTEXT_NAMESPACE
......
......@@ -4,24 +4,28 @@
#include "CoreMinimal.h"
#include "Components/WidgetInteractionComponent.h"
#include "RwthComponent.generated.h"
#include "Components/StaticMeshComponent.h"
#include "VRWidgetInteractionComponent.generated.h"
/**
*
*/
UCLASS()
class WIDGETINTERACTION_API URwthComponent : public UWidgetInteractionComponent
class WIDGETINTERACTION_API UVRWidgetInteractionComponent : public UWidgetInteractionComponent
{
GENERATED_BODY()
public:
URwthComponent();
UVRWidgetInteractionComponent();
void Init();
void Init(USceneComponent* parent);
void SetVisibility(bool visible);
void SetVisibility(bool visible);
protected:
void OnFire(bool val);
UPROPERTY(VisibleAnywhere) UStaticMeshComponent* InteractionRay;
DECLARE_DELEGATE_OneParam(FFireDelegate, bool);
};
......@@ -4,9 +4,11 @@
#include "CoreMinimal.h"
#include "VirtualRealityPawn.h"
#include "RwthComponent.h"
#include "VRWidgetInteractionComponent.h"
#include "Modules/ModuleManager.h"
DECLARE_LOG_CATEGORY_EXTERN(WidgetIntLog, Log, All);
class WIDGETINTERACTION_API FWidgetInteractionModule : public IModuleInterface
{
public:
......@@ -15,17 +17,16 @@ public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
UFUNCTION()
void OnWorldTickStart(ELevelTick, float);
UFUNCTION() void OnWorldTickStart(ELevelTick, float);
URwthComponent* GetWidgetInteractionComponent();
UVRWidgetInteractionComponent* GetWidgetInteractionComponent();
private:
void CreateWidgetInteraction(USceneComponent * parent, AVirtualRealityPawn* outer);
void CreateWidgetInteraction(USceneComponent* parent, AVirtualRealityPawn* outer);
private:
TBaseDelegate<void, ELevelTick, float> on_world_tick_start_delegate_;
URwthComponent * widget_interaction_cmp_;
UWorld* last_world;
UVRWidgetInteractionComponent* widget_interaction_cmp_;
UWorld* last_world;
};
......@@ -25,7 +25,7 @@ public class WidgetInteraction : ModuleRules
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"Core"
// ... add other public dependencies that you statically link with here ...
}
);
......@@ -35,15 +35,16 @@ public class WidgetInteraction : ModuleRules
new string[]
{
"CoreUObject",
"Engine",
"Projects",
"DisplayCluster",
"DisplayClusterInput",
"Engine",
"HeadMountedDisplay",
"DisplayClusterExtensions",
"InputCore",
"UMG",
"Slate",
"SlateCore",
"SlateCore"
// ... add private dependencies that you statically link with here ...
}
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment