Skip to content
Snippets Groups Projects
Commit 726cb4c0 authored by Sebastian Pape's avatar Sebastian Pape
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request VR-Group/ndisplayextensions!3
parents 6512fd6f 222cc799
No related branches found
No related tags found
No related merge requests found
......@@ -5,11 +5,13 @@
#include "Game/IDisplayClusterGameManager.h"
#include "GameFramework/InputSettings.h"
#include "GameFramework/WorldSettings.h"
#include "Input/IDisplayClusterInputManager.h"
#include "Kismet/GameplayStatics.h"
#include "DisplayClusterSettings.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "IDisplayClusterConfigManager.h"
#include "IDisplayCluster.h"
#include "IXRTrackingSystem.h"
#include "Engine/Engine.h"
#include "Camera/CameraComponent.h"
AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
......@@ -24,43 +26,57 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial
RotatingMovement->PivotTranslation = FVector::ZeroVector;
RotatingMovement->RotationRate = FRotator::ZeroRotator;
LeftMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("LeftMotionController"));
LeftMotionController->SetupAttachment (RootComponent);
LeftMotionController->SetTrackingSource (EControllerHand::Left);
LeftMotionController->SetShowDeviceModel (true );
LeftMotionController->SetVisibility (false);
HmdLeftMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdLeftMotionController"));
HmdLeftMotionController->SetupAttachment(RootComponent);
HmdLeftMotionController->SetTrackingSource(EControllerHand::Left);
HmdLeftMotionController->SetShowDeviceModel(true);
HmdLeftMotionController->SetVisibility(false);
RightMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("RightMotionController"));
RightMotionController->SetupAttachment (RootComponent);
RightMotionController->SetTrackingSource (EControllerHand::Right);
RightMotionController->SetShowDeviceModel(true );
RightMotionController->SetVisibility (false);
HmdRightMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdRightMotionController"));
HmdRightMotionController->SetupAttachment(RootComponent);
HmdRightMotionController->SetTrackingSource(EControllerHand::Right);
HmdRightMotionController->SetShowDeviceModel(true);
HmdRightMotionController->SetVisibility(false);
}
void AVirtualRealityPawn::OnForward_Implementation(float Value)
{
AddMovementInput(Forward->GetForwardVector(), Value);
}
void AVirtualRealityPawn::OnRight_Implementation (float Value)
// Check if this function triggers correctly on ROLV.
if (NavigationMode == EVRNavigationModes::Nav_Mode_Fly || IsDesktopMode() || IsHeadMountedMode())
{
AddMovementInput(Forward->GetRightVector (), Value);
AddMovementInput(RightHand->GetForwardVector(), Value);
}
void AVirtualRealityPawn::OnTurnRate_Implementation (float Rate )
}
void AVirtualRealityPawn::OnRight_Implementation(float Value)
{
if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
if (NavigationMode == EVRNavigationModes::Nav_Mode_Fly || IsDesktopMode() || IsHeadMountedMode())
{
const FVector CameraLocation = IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()->GetComponentLocation();
RotatingMovement->PivotTranslation = RotatingMovement->UpdatedComponent->GetComponentTransform().InverseTransformPositionNoScale(CameraLocation);
RotatingMovement->RotationRate = FRotator(RotatingMovement->RotationRate.Pitch, Rate * BaseTurnRate, 0.0f);
AddMovementInput(RightHand->GetRightVector(), Value);
}
else
}
void AVirtualRealityPawn::OnTurnRate_Implementation(float Rate)
{
//if (IsRoomMountedMode())
//{
// //const FVector CameraLocation = IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()->GetComponentLocation();
// //RotatingMovement->PivotTranslation = RotatingMovement
// // ->UpdatedComponent->GetComponentTransform().
// // InverseTransformPositionNoScale(CameraLocation);
// //RotatingMovement->RotationRate = FRotator(RotatingMovement->RotationRate.Pitch, Rate * BaseTurnRate, 0.0f);
//}
//else
//{
// AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
//}
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
}
}
void AVirtualRealityPawn::OnLookUpRate_Implementation(float Rate)
{
if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
if (IsRoomMountedMode())
{
// User-centered projection causes simulation sickness on look up interaction hence not implemented.
}
......@@ -69,13 +85,108 @@ void AVirtualRealityPawn::OnLookUpRate_Implementation(float R
AddControllerPitchInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
}
}
void AVirtualRealityPawn::OnFire_Implementation(bool Pressed)
{
}
void AVirtualRealityPawn::OnAction_Implementation(bool Pressed, int32 Index)
{
}
bool AVirtualRealityPawn::IsDesktopMode()
{
return !IsRoomMountedMode() && !IsHeadMountedMode();
}
bool AVirtualRealityPawn::IsRoomMountedMode()
{
return IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster;
}
bool AVirtualRealityPawn::IsHeadMountedMode()
{
return GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed();
}
FString AVirtualRealityPawn::GetNodeName()
{
return IsRoomMountedMode() ? IDisplayCluster::Get().GetClusterMgr()->GetNodeId() : FString(TEXT("Localhost"));
}
float AVirtualRealityPawn::GetEyeDistance()
{
return IDisplayCluster::Get().GetConfigMgr()->GetConfigStereo().EyeDist;
}
float AVirtualRealityPawn::GetBaseTurnRate() const
{
return BaseTurnRate;
}
void AVirtualRealityPawn::SetBaseTurnRate(float Value)
{
BaseTurnRate = Value;
}
UFloatingPawnMovement* AVirtualRealityPawn::GetFloatingPawnMovement()
{
return Movement;
}
URotatingMovementComponent* AVirtualRealityPawn::GetRotatingMovementComponent()
{
return RotatingMovement;
}
UDisplayClusterSceneComponent* AVirtualRealityPawn::GetFlystickComponent()
{
return Flystick;
}
UMotionControllerComponent* AVirtualRealityPawn::GetHmdLeftMotionControllerComponent()
{
return HmdLeftMotionController;
}
UMotionControllerComponent* AVirtualRealityPawn::GetHmdRightMotionControllerComponent()
{
return HmdRightMotionController;
}
USceneComponent* AVirtualRealityPawn::GetHeadComponent()
{
return Head;
}
USceneComponent* AVirtualRealityPawn::GetLeftHandComponent()
{
return LeftHand;
}
USceneComponent* AVirtualRealityPawn::GetRightHandComponent()
{
return RightHand;
}
USceneComponent* AVirtualRealityPawn::GetCaveOriginComponent()
{
return CaveOrigin;
}
USceneComponent* AVirtualRealityPawn::GetCaveCenterComponent()
{
return CaveCenter;
}
USceneComponent* AVirtualRealityPawn::GetShutterGlassesComponent()
{
return ShutterGlasses;
}
UDisplayClusterSceneComponent* AVirtualRealityPawn::GetClusterComponent(const FString& Name)
{
return IDisplayCluster::Get().GetGameMgr()->GetNodeById(Name);
}
void AVirtualRealityPawn::BeginPlay()
......@@ -99,52 +210,43 @@ void AVirtualRealityPawn::BeginPlay ()
BaseTurnRate = Settings->RotationSpeed;
}
if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
if (IsRoomMountedMode())
{
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("TurnRate" )), EKeys::MouseX));
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("LookUpRate")), EKeys::MouseY));
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX));
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY));
// Requires a scene node called flystick in the config.
Flystick = IDisplayCluster::Get().GetGameMgr()->GetNodeById(TEXT("flystick"));
InitComponentReferences();
Forward = Flystick;
LeftHand = Flystick;
RightHand = Flystick;
RootComponent->SetWorldLocation(FVector(0, 2, 0), false, nullptr, ETeleportType::None);
}
else if (UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayConnected())
else if (IsHeadMountedMode())
{
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("TurnRate" )), EKeys::MouseX));
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("LookUpRate")), EKeys::MouseY));
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX));
UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY));
LeftMotionController ->SetVisibility(true);
RightMotionController->SetVisibility(true);
HmdLeftMotionController->SetVisibility(true);
HmdRightMotionController->SetVisibility(true);
Forward = LeftMotionController ;
LeftHand = LeftMotionController ;
RightHand = RightMotionController;
LeftHand = HmdLeftMotionController;
RightHand = HmdRightMotionController;
Head = GetCameraComponent();
}
else
{
Forward = RootComponent;
LeftHand = RootComponent;
RightHand = RootComponent;
Head = GetCameraComponent();
}
}
void AVirtualRealityPawn::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
// Flystick might not be available at start, hence is checked every frame.
if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster && !Flystick)
{
// Requires a scene node called flystick in the config.
Flystick = IDisplayCluster::Get().GetGameMgr()->GetNodeById(TEXT("flystick"));
Forward = Flystick;
LeftHand = Flystick;
RightHand = Flystick;
}
// Components might not be available at start, hence is checked every frame.
InitComponentReferences();
}
void AVirtualRealityPawn::BeginDestroy()
{
Super::BeginDestroy();
......@@ -161,22 +263,54 @@ void AVirtualRealityPawn::SetupPlayerInputComponent (UInputC
PlayerInputComponent->BindAxis("TurnRate", this, &AVirtualRealityPawn::OnTurnRate);
PlayerInputComponent->BindAxis("LookUpRate", this, &AVirtualRealityPawn::OnLookUpRate);
PlayerInputComponent->BindAction<FFireDelegate> ("Fire" , IE_Pressed , this, &AVirtualRealityPawn::OnFire , true );
PlayerInputComponent->BindAction<FActionDelegate>("Action1" , IE_Pressed , this, &AVirtualRealityPawn::OnAction , true , 1);
PlayerInputComponent->BindAction<FActionDelegate>("Action2" , IE_Pressed , this, &AVirtualRealityPawn::OnAction , true , 2);
PlayerInputComponent->BindAction<FActionDelegate>("Action3" , IE_Pressed , this, &AVirtualRealityPawn::OnAction , true , 3);
PlayerInputComponent->BindAction<FActionDelegate>("Action4" , IE_Pressed , this, &AVirtualRealityPawn::OnAction , true , 4);
PlayerInputComponent->BindAction<FActionDelegate>("Action5" , IE_Pressed , this, &AVirtualRealityPawn::OnAction , true , 5);
// The button names are based on the definitions in aixcave_422.cfg.
PlayerInputComponent->BindAction<FFireDelegate>("nDisplayButton0", IE_Pressed, this,
&AVirtualRealityPawn::OnFire, true);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton1", IE_Pressed, this,
&AVirtualRealityPawn::OnAction, true, 1);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton2", IE_Pressed, this,
&AVirtualRealityPawn::OnAction, true, 2);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton3", IE_Pressed, this,
&AVirtualRealityPawn::OnAction, true, 3);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton4", IE_Pressed, this,
&AVirtualRealityPawn::OnAction, true, 4);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton5", IE_Pressed, this,
&AVirtualRealityPawn::OnAction, true, 5);
PlayerInputComponent->BindAction<FFireDelegate> ("Fire" , IE_Released, this, &AVirtualRealityPawn::OnFire , false );
PlayerInputComponent->BindAction<FActionDelegate>("Action1" , IE_Released, this, &AVirtualRealityPawn::OnAction , false, 1);
PlayerInputComponent->BindAction<FActionDelegate>("Action2" , IE_Released, this, &AVirtualRealityPawn::OnAction , false, 2);
PlayerInputComponent->BindAction<FActionDelegate>("Action3" , IE_Released, this, &AVirtualRealityPawn::OnAction , false, 3);
PlayerInputComponent->BindAction<FActionDelegate>("Action4" , IE_Released, this, &AVirtualRealityPawn::OnAction , false, 4);
PlayerInputComponent->BindAction<FActionDelegate>("Action5" , IE_Released, this, &AVirtualRealityPawn::OnAction , false, 5);
PlayerInputComponent->BindAction<FFireDelegate>("nDisplayButton0", IE_Released, this,
&AVirtualRealityPawn::OnFire, false);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton1", IE_Released, this,
&AVirtualRealityPawn::OnAction, false, 1);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton2", IE_Released, this,
&AVirtualRealityPawn::OnAction, false, 2);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton3", IE_Released, this,
&AVirtualRealityPawn::OnAction, false, 3);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton4", IE_Released, this,
&AVirtualRealityPawn::OnAction, false, 4);
PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton5", IE_Released, this,
&AVirtualRealityPawn::OnAction, false, 5);
}
}
UPawnMovementComponent* AVirtualRealityPawn::GetMovementComponent() const
{
return Movement;
}
void AVirtualRealityPawn::InitComponentReferences()
{
if (!IsRoomMountedMode()) return;
if (!CaveOrigin) CaveOrigin = GetClusterComponent("cave_origin");
if (!CaveCenter) CaveCenter = GetClusterComponent("cave_center");
if (!ShutterGlasses) {
ShutterGlasses = GetClusterComponent("shutter_glasses");
Head = ShutterGlasses;
}
if (!Flystick)
{
Flystick = GetClusterComponent("flystick");
LeftHand = Flystick;
RightHand = Flystick;
}
}
......@@ -10,6 +10,13 @@
#include "VirtualRealityPawn.generated.h"
UENUM(BlueprintType)
enum class EVRNavigationModes : uint8
{
Nav_Mode_None UMETA(DisplayName = "Navigation Mode None"),
Nav_Mode_Fly UMETA(DisplayName = "Navigation Mode Fly")
};
UCLASS()
class DISPLAYCLUSTEREXTENSIONS_API AVirtualRealityPawn : public ADisplayClusterPawn
{
......@@ -23,6 +30,39 @@ public:
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnFire(bool Pressed);
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnAction(bool Pressed, int32 Index);
UFUNCTION(BlueprintPure, Category = "Pawn") static bool IsDesktopMode();
UFUNCTION(BlueprintPure, Category = "Pawn") static bool IsRoomMountedMode();
UFUNCTION(BlueprintPure, Category = "Pawn") static bool IsHeadMountedMode();
UFUNCTION(BlueprintPure, Category = "Pawn") static FString GetNodeName();
UFUNCTION(BlueprintPure, Category = "Pawn") static float GetEyeDistance();
UFUNCTION(Category = "Pawn") float GetBaseTurnRate() const;
UFUNCTION(Category = "Pawn") void SetBaseTurnRate(float Value);
UFUNCTION(Category = "Pawn") UFloatingPawnMovement* GetFloatingPawnMovement();
UFUNCTION(Category = "Pawn") URotatingMovementComponent* GetRotatingMovementComponent();
//Bunch of Getter Functions for components to avoid users having to know the names
UFUNCTION(Category = "Pawn") UDisplayClusterSceneComponent* GetFlystickComponent();
UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdLeftMotionControllerComponent();
UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdRightMotionControllerComponent();
UFUNCTION(Category = "Pawn") USceneComponent* GetHeadComponent();
UFUNCTION(Category = "Pawn") USceneComponent* GetLeftHandComponent();
UFUNCTION(Category = "Pawn") USceneComponent* GetRightHandComponent();
UFUNCTION(Category = "Pawn") USceneComponent* GetCaveOriginComponent();
UFUNCTION(Category = "Pawn") USceneComponent* GetCaveCenterComponent();
UFUNCTION(Category = "Pawn") USceneComponent* GetShutterGlassesComponent();
//Get Compenent of Display Cluster by it's name, which is specified in the nDisplay config
UFUNCTION(BlueprintPure, BlueprintCallable, Category = "Pawn") static UDisplayClusterSceneComponent* GetClusterComponent(
const FString& Name);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EVRNavigationModes NavigationMode =
EVRNavigationModes::Nav_Mode_Fly;
protected:
DECLARE_DELEGATE_OneParam(FFireDelegate, bool);
DECLARE_DELEGATE_TwoParams(FActionDelegate, bool, int32);
......@@ -33,21 +73,42 @@ protected:
virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;
virtual UPawnMovementComponent* GetMovementComponent() const override;
UPROPERTY(EditAnywhere , BlueprintReadWrite, Category = "Pawn", meta = (AllowPrivateAccess = "true")) float BaseTurnRate = 45.0f ;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UFloatingPawnMovement* Movement = nullptr;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) URotatingMovementComponent* RotatingMovement = nullptr;
UPROPERTY(EditAnywhere , BlueprintReadWrite, Category = "Pawn", meta = (AllowPrivateAccess = "true")) float
BaseTurnRate = 45.0f;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
UFloatingPawnMovement* Movement = nullptr;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
URotatingMovementComponent* RotatingMovement = nullptr;
// Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. CAVE/ROLV flystick.
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UDisplayClusterSceneComponent* Flystick = nullptr;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
UDisplayClusterSceneComponent* Flystick = nullptr;
// Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD left motion controller.
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UMotionControllerComponent* LeftMotionController = nullptr;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
UMotionControllerComponent* HmdLeftMotionController = nullptr;
// Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD right motion controller.
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UMotionControllerComponent* RightMotionController = nullptr;
// PC: RootComponent, HMD: LeftMotionController , CAVE/ROLV: Flystick. Movement follows this component.
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent* Forward = nullptr;
// PC: RootComponent, HMD: LeftMotionController , CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent* LeftHand = nullptr;
// PC: RootComponent, HMD: RightMotionController, CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent* RightHand = nullptr;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
UMotionControllerComponent* HmdRightMotionController = nullptr;
// PC: Camera, HMD: Camera, CAVE/ROLV: Shutter glasses.
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
USceneComponent* Head = nullptr;
// PC: RootComponent, HMD: HmdLeftMotionController , CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
USceneComponent* LeftHand = nullptr;
// PC: RootComponent, HMD: HmdRightMotionController, CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
USceneComponent* RightHand = nullptr;
// Holding the Cave Origin Component that is attached to this Pawn
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true"))
USceneComponent* CaveOrigin = nullptr;
// Holding the Cave Center Component that is attached to this Pawn
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true"))
USceneComponent* CaveCenter = nullptr;
// Holding the Shutter Glasses Component that is attached to this Pawn
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true"))
USceneComponent* ShutterGlasses = nullptr;
private:
void InitComponentReferences();
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment