Replications of Motion Controller

Hi Community!

I’m now already a long time googling and tried a lot of things. As I’m newer to C++ it might also just be a lack of understanding codeing. Any way…my problem is, that when I try to replicate the controller, the client sees the movement from the server’s controller but the server doesn’t see the movement of the client’s controller (just sees the spawned weapon from the client). Every client and also server sees his own moving controller.

I made a weapon class which I wanted to attach to the MotionController. But as I don’t found the mesh of it, I created a meshcomp “inbetween” which I can add a socket, to which I can attach my weapon class.

As the weapon is spawning of the opponend but stays only on the ground, I thing the only problem is the RPC from the clients movement of the motion controller to the server.

I would be so thankfull if somebody could help me with this.



// Fill out your copyright notice in the Description page of Project Settings.


#include "SCharacter.h"
#include "Camera\CameraComponent.h"
#include "MotionControllerComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "GameFramework/PawnMovementComponent.h"
#include "VR_Project_D.h"
#include "SHealthComponent.h"
#include "SWeapon.h"
#include "SProjectileWeapon.h"
#include "Net/UnrealNetwork.h"




// Sets default values
ASCharacter::ASCharacter()
{
     // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    HealthComp = CreateDefaultSubobject<USHealthComponent>(TEXT("HealthComp"));

    GetCapsuleComponent()->SetCollisionResponseToChannel(COLLISION_WEAPON, ECR_Ignore);

    VRRoot = CreateDefaultSubobject<USceneComponent>(TEXT("VRRoot"));
    VRRoot->SetupAttachment(GetRootComponent());

    CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));
    CameraComp->SetupAttachment(VRRoot);


    LeftController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("LeftController"));
    LeftController->SetupAttachment(VRRoot);
    LeftController->SetTrackingSource(EControllerHand::Left);

//    if (LeftController)
//    {
//        LeftController->SetIsReplicated(true);
//    }

    LeftBox = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("LeftBox"));
    LeftBox->SetupAttachment(LeftController);


    RightController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("RightController"));
    RightController->SetupAttachment(VRRoot);
    RightController->SetTrackingSource(EControllerHand::Right);


    //Makes the controller's movement only visible from server to client
    if (RightController)
    {
        RightController->SetIsReplicated(true);
    }

    RightBox = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("RightBox"));
    RightBox->SetupAttachment(RightController);


    WeaponAttachSocketName = "WeaponSocket";
}

// Called when the game starts or when spawned
void ASCharacter::BeginPlay()
{
    Super::BeginPlay();

    HealthComp->OnHealthChanged.AddDynamic(this, &ASCharacter::OnHealthChanged);

    //I set at ASWeapon::ASWeapon(){... SetReplicates(true); ...}
    if (Role == ROLE_Authority)
    {
        //Spawn a default weapon
        FActorSpawnParameters SpawnParams;
        SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

        CurrentWeapon = GetWorld()->SpawnActor<ASWeapon>(StarterWeaponClass, FVector::ZeroVector, FRotator::ZeroRotator, SpawnParams);

        if (CurrentWeapon)
        {
            CurrentWeapon->SetOwner(this);
            CurrentWeapon->AttachToComponent(RightBox, FAttachmentTransformRules::SnapToTargetNotIncludingScale, WeaponAttachSocketName);
        }
    }
}

//---------------------------------------------
//___________CUT OUT IRRELEVANT CODE___________
//---------------------------------------------


void ASCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    DOREPLIFETIME(ASCharacter, bDied);
    DOREPLIFETIME(ASCharacter, CurrentWeapon);

    //Tried to replicate it as a variable but obviously doesn't work...is there another method?
//    DOREPLIFETIME(ASCharacter, RightController);
}


Am I doing something wrong that nobody responds? :frowning:

UMotionControllerComponent doesn’t replicate its position, so you need to do it manually.

In Tick(…) for locally controlled pawn set RightController->PlayerIndex = 0 and save current location and rotation to replicated variables (use server event). For remotely controlled pawn set RightController->PlayerIndex = -1 and update its location/rotation from those replicated variables.

Thanks a lot for your answering. I’ll try that and will let you know if it worked!

Hello,

I’ll bump this thread since I have the same problem.

Did you manage to make this work?
Can you share a screenshot of the blueprints setup?

Regards!

For anyone stumbeling over this thread: My solution was to add the VR plugin from . It’s extremely versatile and just awesome!