Announcement

Collapse
No announcement yet.

Training Stream - Sam and Wes' VR Stream: Cameras, Multiplayer, Tips and Tricks! - Live from Epic HQ

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    #16
    Hi Wes,

    were you able to find out how to fix the Multiplayer Motion Controller thing?
    I am also in dire need of that solution...

    Cheers
    Fred

    Comment


      #17
      Hi Fredrum,

      I haven't had a chance to investigate this further yet on the Blueprint side. I will try to get an answer on this, this week if possible. A lot of the team is gearing up for GDC among other things here at the office so they are a little preoccupied at the moment. I'll see what I can find out though.

      -W

      Comment


        #18
        Wes if I redo my character BP into c++ will let this issue be fixed on a 4.11 build?

        Comment


          #19
          I built the VR teleport demo and for the most part is working good except half the directions I point my gun in the bullet will stick in the air without moving while the other 180 degrees the gun shoots normally. I can still teleport to the sphere in both cases. At first I thought it might be something in the character that it was hitting but by moving the gun to different locations and rotating it the bullet will stick in areas I can also shoot through just based on which way the gun is pointed. The 180 that sticks is the xy quadrants 3, 4. Pointing the gun in the -x.
          Thanks,
          Matt

          Comment


            #20
            Originally posted by Wes Bunn View Post
            Hey Lasyavez,

            You have run into the same hurdle we have regarding multiplayer with motion controllers. Our team has indicated that a code side fix for this is in the 4.11 preview build however after testing, I'm still unable to get this to work properly myself. I've reached out to the developers working on this and I'm still in the process of identifying the best approach (this may not be ready for next weeks stream). We are going to do a quick setup for a teleport mechanic with motion controllers (similar to what is used in Bullet Train) if we do not have the multiplayer motion controller issue sorted out before then.

            -W

            Edit: Here is the fix and the relevant code:

            Code:
            bool UMotionControllerComponent::PollControllerState(FVector& Position, FRotator& Orientation)
            {
            	if (IsInGameThread())
            	{
            		// Cache state from the game thread for use on the render thread
            		const APlayerController* Actor = Cast<APlayerController>(GetOwner());
            		bHasAuthority = !Actor || Actor->IsLocalPlayerController();
            	}
            bHasAuthority must be true for one motion controller and false for the remote, however I haven't found the best way to define this yet since I'm doing it in Blueprint.


            Hey
            So where do i insert this Code ?
            The Farm - Visit us here !

            https://twitter.com/playthefarm
            https://www.instagram.com/playthefarm/

            Comment


              #21
              Hi guys. I got the same issue and I managed to fix it in quite simple way.
              First I did some research and I found many threads about the same problem. I post them at the end of the post so you can make some additional reading if you want to.

              So in UMotionControllerComponent inside the PollControllerState method there is an authority check...
              Code:
                 
              if (IsInGameThread())
              {
                   // Cache state from the game thread for use on the render thread
                   const AActor* MyOwner = GetOwner();
                   const APawn* MyPawn = Cast<APawn>(MyOwner);
                   bHasAuthority = MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner->Role == ENetRole::ROLE_Authority);
              }
              
              if (bHasAuthority)
                  {
                      TArray<IMotionController*> MotionControllers = IModularFeatures::Get().GetModularFeatureImplementations<IMotionController>(IMotionController::GetModularFeatureName());
                      for (auto MotionController : MotionControllers)
                      {.....
              Authority check in here is not enough because what we do later is telling the engine to get all motion controllers out there and process them. So if one of them got authority you still update them all.
              PollControllerState is a private method so you cannot edit definition of that method. So instead I wrote this piece of code inside the TickComponent in my UMotionControllerComponent derived class


              Code:
              void UNetworkMotionControllerComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
              {
                  Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
                  const AActor* MyOwner = GetOwner();
                  const APawn* MyPawn = Cast<APawn>(MyOwner);
                  bHasAuthority = MyPawn ? MyPawn->IsLocallyControlled() : throw;
                  if (bHasAuthority == false)
                  {
                      SetAssociatedPlayerIndex(-1);
              // this line is where we tell the engine to not to use this controller. PlayerIndex variable is used differently in platform specific places. eg. SteamVR uses some 2 dimensional array to store the controllers and then only checks if they are smaller than the max value so it can be a better solution to set it to maximum value of int instead. You have to check it up with your platform. (-1 works well with oculus rift and htc vive)
                  }
              
                  if (bIsActive&&PlayerIndex == 0)
                  {
                      FVector Position;
                      FRotator Orientation;
                      float WorldToMeters = GetWorld() ? GetWorld()->GetWorldSettings()->WorldToMeters : 100.0f;
                      const bool bNewTrackedState = PollControllerState(Position, Orientation, WorldToMeters);
                      if (bNewTrackedState)
                      {
                          Server_SetRelativeLocationAndRotation(Position, Orientation);
                          //SetRelativeLocationAndRotation(Position, Orientation);
                      }
              //rest of the default motioncontrollercomponent's code
              So basically you have to do those things:
              set PlayerIndex != 0 on the controllers that should't get the data from you motion controller.
              implement the function that will set the position and rotation. It have to be done on server so the other clients can see it. I copied the code from USceneComponent::SetRelativeLocationAndRotation() and it woks like a charm.

              Please keep in mind that this is the working solution but its like alpha alpha version. I'm sure I'll try to optimize this so I don't have to do all those casting inside of a tick function and get rid of the throwing exceptions when there is no Pawn. Do not use this as ready to go solution in your projects. I posted this only as a reference so you can get on going with your projects if you stucked.


              Links to read if you want to get more information:

              https://forums.unrealengine.com/deve...and-networking
              https://forums.unrealengine.com/deve...r-multi-player
              https://answers.unrealengine.com/que...s-them-al.html
              https://forums.unrealengine.com/deve...nd-networking=
              https://www.youtube.com/watch?v=jVdFpuicptQ at 14:35
              and the thread about this livestream
              https://forums.unrealengine.com/unre...epic-hq?99586=

              Comment

              Working...
              X