I am trying to create a spawnable actor that has a MotionControllerComponent. I took the example in the blueprint template VR level but it does not seem to work. The object that i make does not follow my movements.
This is my custom motion controller object class:
.h
public:
// Sets default values for this actor's properties
AHandController();
void Initialize(FName MotionSource);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
///COMPONENTS
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
class USceneComponent* Scene;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
class UMotionControllerComponent* MotionController;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
class UStaticMeshComponent* HandMesh;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
class USphereComponent* GrabCollision;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
class USteamVRChaperoneComponent* SteamVRChaperone;
///VARIABLES
UPROPERTY(BlueprintReadWrite, EditAnywhere)
FName Hand;
///FUNCTIONS
UFUNCTION(BlueprintCallable)
void Grab();
};
.cpp
// Sets default values
AHandController::AHandController()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
///Component Init
Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
RootComponent = Scene;
MotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("Motion Controller"));
MotionController->SetupAttachment(RootComponent);
HandMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Hand Mesh"));
HandMesh->SetupAttachment(MotionController);
GrabCollision = CreateDefaultSubobject<USphereComponent>(TEXT("Grab Sphere"));
GrabCollision->SetupAttachment(HandMesh);
SteamVRChaperone = CreateDefaultSubobject<USteamVRChaperoneComponent>(TEXT("VR Chaperone"));
}
//Constructor-like function for variables
//Called with Deffered Spawn
void AHandController::Initialize(FName MotionSource)
{
MotionController->MotionSource = MotionSource;
this->Hand = MotionSource;
}
// Called when the game starts or when spawned
void AHandController::BeginPlay()
{
Super::BeginPlay();
if (Hand == "Left") {
HandMesh->SetRelativeScale3D(FVector(HandMesh->GetComponentScale().X, HandMesh->GetComponentScale().Y, -HandMesh->GetComponentScale().Z));
}
}
// Called every frame
void AHandController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
And in my pawn class i have:
.h
public:
// Sets default values for this pawn's properties
AVR_Pawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
///Components
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class USceneComponent* RootSceneComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class USceneComponent* CameraSceneComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* CameraComponent;
///Variables
UPROPERTY(EditAnywhere)
TSubclassOf<class AHandController> HandSpawn;
UPROPERTY(BlueprintReadWrite)
class AHandController* MotionL;
UPROPERTY(BlueprintReadWrite)
class AHandController* MotionR;
///Functions
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
.cpp
AVR_Pawn::AVR_Pawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
///Component Init
RootSceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootSceneComponent"));
RootComponent = RootSceneComponent;
CameraSceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("VR Origin"));
CameraSceneComponent->SetupAttachment(RootComponent);
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("HeadCamera"));
CameraComponent->SetupAttachment(CameraSceneComponent);
///VariableInit
BaseEyeHeight = 0.0;
}
// Called when the game starts or when spawned
void AVR_Pawn::BeginPlay()
{
Super::BeginPlay();
//Spawn Motion Controllers With Deffer
MotionL = Cast<AHandController>(UGameplayStatics::BeginDeferredActorSpawnFromClass(this, HandSpawn, RootComponent->GetComponentTransform()));
if (MotionL) {
MotionL->Initialize("Left");
UGameplayStatics::FinishSpawningActor(MotionL, RootComponent->GetComponentTransform());
MotionL->AttachToComponent(CameraSceneComponent, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, false));
}
MotionR = Cast<AHandController>(UGameplayStatics::BeginDeferredActorSpawnFromClass(this, HandSpawn, RootComponent->GetComponentTransform()));
if (MotionR) {
MotionR->Initialize("Right");
UGameplayStatics::FinishSpawningActor(MotionR, RootComponent->GetComponentTransform());
MotionR->AttachToComponent(CameraSceneComponent, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, false));
}
}