Monday, August 14, 2017

How to set up Vive controllers in Unreal in C++

How to set up Vive controllers in Unreal in C++

I am going to show you exactly how to set up HTC Vive controllers in Unreal 4 using C++. 

This was a pain in the ass with snippets of code and information scattered everywhere. This may be easy for seasoned UE4 developers. For noobs like myself, it was not. The Blueprint hides things and does not explain how this is done in C++.


You need a custom game mode working you can write logic into its BeginPlay() method.

1. Import the Vive 3D controller into blender.


2. Export the Vive 3D controller as fbx

3. Import the Vive 3D controller and 2 related textures

C:\Program Files (x86)\Steam\steamapps\common\SteamVR\resources\rendermodels\vr_controller_vive_1_5

4. Build a material. I tweaked it to use a custom wood material

I assume you know how to make a material...

5. Set the material on the 3D controller

This is pretty straight forward...

6. Add HeadMountedDisplay to PublicDependencyModuleNames in your file
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "Foliage", "InputCore", "HeadMountedDisplay" });

7. Create a C++ Pawn using UE4

This is pretty straight forward...

8. Add 3 UPROPERTY Variables to the pawn class:

USceneComponent* OurVisibleComponent;

class UMotionControllerComponent* LeftMotionController;

class UMotionControllerComponent* RightMotionController;

9. Flesh out the Pawn constructor

// Set the player to be represented by this pawn
AutoPossessPlayer = EAutoReceiveInput::Player0;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));

LeftMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("LeftMotionController"));
LeftMotionController->Hand = EControllerHand::Left;
RightMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("RightMotionController"));
RightMotionController->Hand = EControllerHand::Right;

UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("PlayerCameraComponent"));

// TODO: Add SteamVRChaperone bounds
// TODO: Set Tracking Origin to floor for Vive

BaseEyeHeight = 0.0f;

10. Flesh out the Pawn BeginPlay

FTransform SpawnTransform = FTransform(FRotator(0.0f, 90.0f, 0.0f), FVector(0.f, 0.f, 0.f), FVector(0.120f, 0.120f, 0.120f));
// AGeneratedActor sets the mesh and material in its constructor
AGeneratedActor* LeftControllerActor = GetWorld()->SpawnActor<AGeneratedActor>(AGeneratedActor::StaticClass(), SpawnTransform);
LeftControllerActor->AttachToComponent(LeftMotionController, FAttachmentTransformRules::KeepRelativeTransform);

SpawnTransform = FTransform(FRotator(0.0f, 90.0f, 0.0f), FVector(0.f, 0.f, 0.f), FVector(0.120f, 0.120f, 0.120f));
AGeneratedActor* RightControllerActor = GetWorld()->SpawnActor<AGeneratedActor>(AGeneratedActor::StaticClass(), SpawnTransform);
RightControllerActor->AttachToComponent(RightMotionController, FAttachmentTransformRules::KeepRelativeTransform);

11. Spawn the Pawn in the GameMode BeginPlay()

FTransform SpawnTransform = FTransform(FRotator(0.0f, 0.0f, 0.0f), FVector(400.f, 550.f, 105.f), FVector(1.0f, 1.0f, 1.0f));
ASeanPawn* MyPawn = GetWorld()->SpawnActor<ASeanPawn>(ASeanStepPawn::StaticClass(), SpawnTransform);

12. Voila

I know I didn't cover the creation of an Actor with a Mesh. This is pretty straight forward thing. If you have constructed any meshes in C++, you should know how to do this.
I had to adjust rotation and scale of the model until it felt right. You will need to do the same.

No comments:

Post a Comment