Announcement

Collapse
No announcement yet.

Single/Multiplayer, Touch & Vive Proteus blueprint only Template

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

    #16
    Checking out the template, it works great! How would it be possible to make it compatible also with gear VR?

    Comment


      #17
      [MENTION=28694]Elleclouds[/MENTION] Di you make sure that's the VR_GameMode is selected in your map? Because this gamemode will cast the VR_PlayerController, which will spawn the MotionControllerPawn, which will itself spawn 2 BPMotionControllers
      [MENTION=5677]devel.bmad[/MENTION] It's not directly compatible. You should start with the Epic template, with the HMDController pawn. Then add Android functionnalities https://docs.unrealengine.com/latest...art/index.html but most functions of my template are centered around Motion Controllers which are absent from Gear VR. Best to start from scratch with Epic HMDController template.

      Comment


        #18
        Originally posted by Proteus View Post
        [MENTION=28694]
        [MENTION=5677]devel.bmad[/MENTION] It's not directly compatible. You should start with the Epic template, with the HMDController pawn. Then add Android functionnalities https://docs.unrealengine.com/latest...art/index.html but most functions of my template are centered around Motion Controllers which are absent from Gear VR. Best to start from scratch with Epic HMDController template.
        [MENTION=70903]Proteus[/MENTION]: I understand, this has been my approach so far. It would be in any case valuable to have a single template working for both mobile and desktop VR, and should not be too difficult to adapt your current template to this (basically most of the work should be in introducing a fallback for teleportation without controllers and to fix the height of the HMD from the floor when positional tracking is not available). I'll give it a try in the next few days, if I find some time.

        How are you progressing with the multiplayer version of the template? Have you been experimenting also with voice chat and spatialized audio so far?

        Comment


          #19
          [MENTION=5677]devel.bmad[/MENTION]

          So I've been working a lot on the multiplayer version. Testing via Steam, with 2 different computers/Steam logins/Rifts+Touch

          Basically the 2 players spawn in the level. They can see each other (for now some glitches like incorrect orientation of the Avatar head but should be solved easily).

          Each player can control its motion controllers (animation of hands follow).

          Problems encountered with each pawn:

          Player 1 (also Server): See Player 2 head, but bad rotation; see Player 2 hands but no movement; rest is OK (of course since its the client-server)
          Player 2 (Client 1): See 2x hands (his and Player 1); Hands animated but no movement; teleportation doesn't work yet; spawning poles at Guardian corners ok

          I did not address the teleportation and voice issue now.

          Also: When all will work, I know it will need optimizations on RPCs and replicated variables.

          So there's my plan: I will continue to work on it during the w-e and Monday I'll release it there to leverage the community to once and for all nail it.

          It can be done but, as most multiplayer projects, each functions and variables have to be rethinked for networking.

          As for the integrated platform mobile/desktop, my main concern for me is optimizations. I did once a project for Gear (started as a desktop project) and we had to rethink everything following machine specs.

          We are doing Vive/Rift projects and will tackle Windows Holographic soon, so I instead aim to adapt the template for the latter in a soon-to-follow iteration (as soon as multiplayer is tamed).

          Stay tuned on monday!

          Comment


            #20
            Can't wait to see multiplayer progress further. Thanks for all your hard work on the new template, I'll be keeping an eye on things!

            Comment


              #21
              [MENTION=3367]pixelvspixel[/MENTION] Thanks. Believe me I tried at least an hundred packaged versions of the multiplayer template to finally surrender. Even if I want it to be very simple, the multiplayer solution will ask for a 2-lines changes in the UE4 source code (MotionControllerComponent.cpp). Without that change, clients cannot own their respective motion controllers. This ownership fix cannot be done in blueprints (for now).

              Besides and with that fix, everything should work as expected. I'll finalize it this week and write proper docs for it.

              Comment


                #22
                Originally posted by Proteus View Post
                [MENTION=3367]pixelvspixel[/MENTION] Thanks. Believe me I tried at least an hundred packaged versions of the multiplayer template to finally surrender. Even if I want it to be very simple, the multiplayer solution will ask for a 2-lines changes in the UE4 source code (MotionControllerComponent.cpp). Without that change, clients cannot own their respective motion controllers. This ownership fix cannot be done in blueprints (for now).

                Besides and with that fix, everything should work as expected. I'll finalize it this week and write proper docs for it.
                [MENTION=219289]pro[/MENTION]meteus Great to hear that, thanks! It would be interesting to hear from [MENTION=5145]marksatt-pitbull[/MENTION] (or other Epic devel working on this part of the engine) about the issue you are having with the ownership of the motion controllers, having to rebuild the whole engine for this is kind of unfortunate.

                Comment


                  #23
                  [MENTION=5145]marksatt-pitbull[/MENTION] [MENTION=5677]devel.bmad[/MENTION] [MENTION=31494]muchcharles[/MENTION] [MENTION=3201]PenguinTD[/MENTION] OK here I call for the gods.

                  The problem is still ownership of the MotionController Component. Each player spawn and see the other. But the MotionController Component of the client refuses to be controlled by the client pawn.

                  As other as highlighted in https://forums.unrealengine.com/show...and-networking , by default the MotionController component will receive inputs from the actor who as authority over him, which in the case of my and Epic's template is BP_MotionController.
                  The corresponding and relevant C++ code in the MotionControllerComponent.cpp, is:

                  const AActor* MyOwner = GetOwner();
                  const APawn* MyPawn = Cast<APawn>(MyOwner);
                  bHasAuthority = MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner->Role == ENetRole::ROLE_Authority);

                  which I (and others) changed to

                  {
                  // Cache state from the game thread for use on the render thread
                  const AActor* MyOwner = GetOwner();
                  while (MyOwner && MyOwner->GetOwner() != nullptr)
                  {
                  MyOwner=MyOwner->GetOwner();
                  }
                  const APawn* MyPawn = Cast<APawn>(MyOwner);
                  bHasAuthority = MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner->Role == ENetRole::ROLE_Authority);
                  }

                  which, by design, should go to the owner of the 2 spawned BP_MotionControllers. Sadly, it still doesn't work

                  So I'm casting [MENTION=4285]mordentral[/MENTION] and [MENTION=548]getnamo[/MENTION] (which I had the pleasure to met again at OC3) to bring some light. Even with a PhD I'm stuck at it, which is lame.

                  So here's the build on github at https://github.com/ProteusVR/MultiplayerVR or onedrive at https://1drv.ms/f/s!AhConHxqM4Nix0x9ynoaaA4n4SVC

                  How it works:

                  You should download UE4.14 source version from GitHub, and change / improve these lines of code (what I did). Then convert the project to your UE4 build.

                  You need 2 computers each with rift or vive, each with a different Steam account. connected to Steam
                  Package project
                  Player 1 is the listen-server. In the Main Menu you're GREENPAWN. Launch Host. Now you're in the lobby. Select a character (it's all REDPAWN), and launch game (don't select map 2 it lead to sadness and death).

                  Now Player 2 launch the game, select find a match, internet, and there it is.

                  There's full of little things to arrange (like replication of animations etc) but I'll do that when our main problem is resolved.

                  I checked in Epîc trello and 4.15 preview, nothing changed. Maybe I could raise a flag for this.

                  PS. [MENTION=4285]mordentral[/MENTION] what you're doing for VR multiplayer is fantastic and optimized. The reason why we want to have a no-plugin integration is because we work with many UE4 versions, and also tackle Hololens and we had white nights adapting yours, Rama's and other plugins into different builts.

                  We Can make UE4 Great Again.

                  Comment


                    #24
                    Whats the problem? Is it just not moving or is it picking up the servers controller movements?

                    Because even with ownership it still has to be sent manually from the client to the server and then from the server to all non owning remote clients. Just getting proper ownership isn't enough as the server doesn't know the local clients VR tracking locations.


                    Consider supporting me on patreon

                    My Open source tools and plugins
                    Advanced Sessions Plugin
                    VR Expansion Plugin

                    Comment


                      #25
                      [MENTION=4285]mordentral[/MENTION]:

                      The way I set it:

                      2 instances of the pawn spawn, one is the listen-server and the other one client, via Steam. Player Index of MC Component is by default -1.
                      For each instance, inside the pawn:

                      1) Spawn on server BP_MotionController, reference at Left or Right Controller as Epic template:


                      2) Right/Left Controllers RepNotify, inside RepNotify set MotionController Component at 0:

                      3)On tick capture left/right/head transform and RepNotify:

                      4)Inside RepNotifyeverybody is getting location and rotation


                      So am I missing something?
                      Attached Files

                      Comment


                        #26
                        Yeah doing it in blueprint it still replicates back down to the original owner, you would have to manually set it on client again.

                        In c++ you set it to not replicate to the owner to avoid this issue, other than that though it should work, though I didn't look that closely at the ownership check.


                        Consider supporting me on patreon

                        My Open source tools and plugins
                        Advanced Sessions Plugin
                        VR Expansion Plugin

                        Comment


                          #27
                          Originally posted by mordentral View Post
                          Yeah doing it in blueprint it still replicates back down to the original owner, you would have to manually set it on client again.

                          In c++ you set it to not replicate to the owner to avoid this issue, other than that though it should work, though I didn't look that closely at the ownership check.
                          Correct, in 4) looks like you should avoid to use the position / rotation replicated by the server when the pawn is controlled locally and use directly the local values.

                          Comment


                            #28
                            Looks like I wasn't needed. It's a tricky one for sure for multiplayer especially if you want to grab things without suffering latency.(Actually I don't think it should be replicated at all when you grab anything on the client side.)

                            Basically a simple case like this(server/client A and B), anything owned/grabbed by client A immediately lose replication status on client A(or seems to be), and then update server side object by running multicast call every frame). A cheap way to do this is by using the duplicated object method where you spawn identical thing(shape) for you to grab, and you just don't see the replicated object(owner no see flag maybe, which lags behind anyway). Server will update things controlled by client A and then replicated to client B, client B can see since B is not owner, so B saw the replicated shape. B won't notice anything differently, but upon release, you have to lose owner ship and then server takes over, you then see the replicated shape and hide/destroy whatever shape you are grabbing. C++ should be easier like above post mentioned. But it would be pretty hard to do anti-cheat this way if and object update is from client side. ie. a melee sword that can just fly/stab client B by sending out wrong location from client A if you didn't put in any checks.
                            Unreal Engine 4 Game Framework diagram for relation of all major base object types
                            Unreal Engine 4 Input Event diagram, scroll down to section Input Processing Procedural
                            Resident Evil Classic Camera
                            RPCs official document, Must Read
                            Everything you should know about replication

                            Comment


                              #29
                              [MENTION=3201]PenguinTD[/MENTION] [MENTION=5677]devel.bmad[/MENTION] [MENTION=4285]mordentral[/MENTION]

                              Thanks all for the tips. I adjusted some parameters but nada. The problem is still the MotionController Component does not receive input from the client side.
                              Here's is more detail the flow:
                              1)Pawn #1 (listen-server via Steam) spawns BP_MotionController. Pawn #2 (client) will follow later.

                              So at this point the pawn owns BP_MotionController_0 and _1, which in return own their MotionController Component
                              Server set a reference variable with RepNotify for BP_MotionController exist for everybody. There, client should have a replicate of BP_MotionController and control the MotionControllerComponent inside.

                              Within RepNotify, Player Index of the MotionController Component is set to 0, ultimately owned by the locally controlled pawn. The, the server attach the BP_MotionController to the root (VRORigin).


                              Then at every tick, on the server and the client, the worldtransform of the controllers are captured then RepNotified from the Server to everybody.


                              On RepNotify, transforms are replicated to everybody and local pawns get local variables

                              Finally some fine-tuning stuff


                              The result the same: Pawns see each other, their face and controllers. But motioncontrollers are not associated with client (Pawn #2) hands. They are still at VROrigin location, but animation works.

                              I tried with/without C++ changes, the same.

                              Original code:
                              bool UMotionControllerComponent::PollControllerState(FVector& Position, FRotator& Orientation)
                              {
                              if (IsInGameThread())
                              {
                              // Cache state from the game thread for use on the render thread
                              const AActor* MyOwner = GetOwner();
                              while (MyOwner && MyOwner->GetOwner() != nullptr)
                              {
                              MyOwner = MyOwner->GetOwner();
                              }
                              const APawn* MyPawn = Cast<APawn>(MyOwner);
                              bHasAuthority = MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner->Role == ENetRole::ROLE_Authority);
                              }


                              if ((PlayerIndex != INDEX_NONE) && bHasAuthority)
                              {
                              TArray<IMotionController*> MotionControllers = IModularFeatures::Get().GetModularFeatureImplementations<IMotionController>( IMotionController::GetModularFeatureName() );
                              for( auto MotionController : MotionControllers )
                              {
                              if ((MotionController != nullptr) && MotionController->GetControllerOrientationAndPosition(PlayerIndex, Hand, Orientation, Position))
                              {
                              CurrentTrackingStatus = MotionController->GetControllerTrackingStatus(PlayerIndex, Hand);
                              return true;
                              }
                              }
                              }
                              return false;
                              }

                              Modified code:
                              bool UMotionControllerComponent::PollControllerState(FVector& Position, FRotator& Orientation)
                              {
                              if (IsInGameThread())
                              {
                              // Cache state from the game thread for use on the render thread
                              const AActor* MyOwner = GetOwner();
                              while ( MyOwner && MyOwner->GetOwner() != nullptr)
                              {
                              MyOwner = MyOwner->GetOwner();
                              }
                              const APawn* MyPawn = Cast<APawn>(MyOwner);
                              bHasAuthority = MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner->Role == ENetRole::ROLE_Authority);
                              }


                              if ((PlayerIndex != INDEX_NONE) && bHasAuthority)
                              {
                              TArray<IMotionController*> MotionControllers = IModularFeatures::Get().GetModularFeatureImplementations<IMotionController>( IMotionController::GetModularFeatureName() );
                              for( auto MotionController : MotionControllers )
                              {
                              if ((MotionController != nullptr) && MotionController->GetControllerOrientationAndPosition(PlayerIndex, Hand, Orientation, Position))
                              {
                              CurrentTrackingStatus = MotionController->GetControllerTrackingStatus(PlayerIndex, Hand);
                              return true;
                              }
                              }
                              }
                              return false;
                              }

                              I'm stuck as an old gum under a park bench on a summer day.
                              Attached Files

                              Comment


                                #30
                                Hi [MENTION=70903]Proteus[/MENTION], I can't see the first 2 screenshots. RepNotify, isn't the locally controlled branch redundant?
                                It basically applies to the controller mesh the transformation it already has. Does't it?
                                Click image for larger version

Name:	Screen Shot 2017-02-03 at 11.56.58.png
Views:	1
Size:	143.4 KB
ID:	1122488

                                And doesn't the fine tuning part conflict with the repnotify above?
                                Sorry, cannot directly test the code right now, I will give it a run as soon as possible.
                                Last edited by devel.bmad; 02-03-2017, 02:17 PM.

                                Comment

                                Working...
                                X