Announcement

Collapse
No announcement yet.

Multiplayer question

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

    Multiplayer question

    Hi. I have watched the whole series of multiplayer videos which Epic made, and they are great. But if I create my own Pawn, instead of using a pawn provided in a template game, then if I do a "Set Actor Location" in blueprint when a key is pressed, the actor location changes on the client instance if I run it on a client, but then it does not change on the server. If I invoke a Multicast custom event, then the actor position changes on both the Server instance and the Client instance, but only if I press the key on the Server instance.

    How can I cause the position between the server and client to always be in sync?

    Click image for larger version

Name:	Ball.PNG
Views:	1
Size:	152.4 KB
ID:	1137578

    Thanks!
    Marius.

    #2
    Character movement is a bit of a special, more complicated case than normal replication. Most of the time you'll see examples using things like AddMovementInput instead of setting an actor location directly, because the engine and the character movement component do some things under the covers for character movement (predictive movement, etc.) to make it especially smooth in multiplayer. If you're trying to make a character repeatedly move around, you normally don't want to go the route of setting actor location directly or you'll get some snapping/stuttering when you play. However, if you just want to force a teleport or put an actor to a new location as a one-off, you could use a "Server" event instead of a multicast if it's in your pawn, character, or player controller blueprint. That event means tell the server to execute everything that is connected to this event. So you could use that to tell the server you pressed your button and respond however you want, like by setting the location or teleporting (I think there's a blueprint exposed function to Teleport also).
    Lead Programmer (Gameplay), Fortnite, Epic Games
    Twitter: @EpicIrascible

    Comment


      #3
      Thank you, that makes sense.

      Am I correct in assuming that AddMovementInput requires a MovementComponent component in my Pawn?

      Thanks! It is really awesome that the Epic developers are taking the time to help people.

      Cheers,
      Marius.

      Comment


        #4
        Hi Billy,

        I have made the simplest pawn I could think of - just a pawn with a ProjectileMovement component, a static mesh, and a camera. In the event graph, on Tick, I make a call to AddMovementInput, expecting this to cause my pawn to move. But the pawn is as still as a brick (that is not being pushed ). I am missing something elementary with regards to movement and how movement should be implemented.

        Click image for larger version

Name:	SimplePawn.PNG
Views:	1
Size:	539.8 KB
ID:	1053693

        Click image for larger version

Name:	SimplePawnGraph.PNG
Views:	1
Size:	234.4 KB
ID:	1053694

        More help would be appreciated!

        Thanks,
        Marius.

        Comment


          #5
          Hi Marius,

          First I would suggest considering using Character instead of Pawn if that is a possibility, since it has the networking you're talking about built-in to CharacterMovementComponent. Most of the templates derive from Character rather than Pawn.

          Alternatively DefaultPawn might be a good starting point, it has a sphere for collision and has simple flying movement. You can force it to use 2D movement by editing the "Plane Constraint" on the FloatingPawnMovement if you like.

          Second, projectile movement doesn't respond to AddMovementInput, that is specific to PawnMovementComponent (in version 4.3). In 4.4 we made AddMovementInput work for Pawns without a movement component, in the sense that it can be used to accumulate input and then read it back (with the ConsumeMovementInputVector function), however you still need to apply that input somewhere to cause movement. PawnMovementComponents applies that input automatically, and if you use DefaultPawn or Character then that happens for your. Otherwise, you need to read the input in your own Tick event and add to position/velocity/etc to cause movement.

          As for networking... if you're not using Character then you can decide on a couple movement schemes, the most simple is to move on the client and send the movement to the server also, where you match the client's movement. This is called client-authoritative movement. I think the multicast setup you used doesn't run the movement on the client in addition to the server, and that may be why the client isn't moving when they push the button.

          A more complex scheme is to move on the client and the server (as before), and detect when the client is too far out of sync with the server's (authoritative) location, and send a correction to the client when this happens. Character does something similar to this, with the added ability to play back all input that occurred after the correction, to account for the delay in the message from the client->server->client that resulted in the correction.

          -Zak
          Zak Middleton
          Sr. Engine Programmer, Epic Games

          Comment


            #6
            Originally posted by Zak Middleton View Post
            Hi Marius,

            First I would suggest considering using Character instead of Pawn if that is a possibility, since it has the networking you're talking about built-in to CharacterMovementComponent. Most of the templates derive from Character rather than Pawn.

            Alternatively DefaultPawn might be a good starting point, it has a sphere for collision and has simple flying movement. You can force it to use 2D movement by editing the "Plane Constraint" on the FloatingPawnMovement if you like.

            Second, projectile movement doesn't respond to AddMovementInput, that is specific to PawnMovementComponent (in version 4.3). In 4.4 we made AddMovementInput work for Pawns without a movement component, in the sense that it can be used to accumulate input and then read it back (with the ConsumeMovementInputVector function), however you still need to apply that input somewhere to cause movement. PawnMovementComponents applies that input automatically, and if you use DefaultPawn or Character then that happens for your. Otherwise, you need to read the input in your own Tick event and add to position/velocity/etc to cause movement.

            As for networking... if you're not using Character then you can decide on a couple movement schemes, the most simple is to move on the client and send the movement to the server also, where you match the client's movement. This is called client-authoritative movement. I think the multicast setup you used doesn't run the movement on the client in addition to the server, and that may be why the client isn't moving when they push the button.

            A more complex scheme is to move on the client and the server (as before), and detect when the client is too far out of sync with the server's (authoritative) location, and send a correction to the client when this happens. Character does something similar to this, with the added ability to play back all input that occurred after the correction, to account for the delay in the message from the client->server->client that resulted in the correction.

            -Zak
            Thank you very much for the detailed explanation Zak. I should be able to implement a solution now, thanks.

            Comment


              #7
              OK, thanks to all of the help, I have solved all of my problems. That is the good news. The bad news is, two new issues have come up.

              I decided to base my blueprint on DefaultPawn instead of Character, because I am making an aircraft, and Character seems to be too specific to, well, characters, to use it as a base for an aircraft.

              In the Tick event, I send my pawn's position to the server, and voila, it works beautifully, I have a working multiplayer scenario with multiple players, each seeing the other players.

              So my networking problem is solved now, thank you! But this lead to the following issues. 1) DefaultPawn has a Collision component, which is a sphere. A sphere is too simple for the collision responses that I need for my aircraft models. But I can not seem to remove this component (I guess it is a NativeComponent), and I can also not give it zero size and use the collision on the mesh, the mesh collision seems to just be ignored. 2) And the second problem, I now find that my control scheme does not work correctly. I added roll to my pawn (using AddRollInput)), and it does roll, but then if I then pitch (which automatically comes from the DefaultPawn because I do not explicitly pitch, moving the mouse up and down pitches for me), the pitch takes place on a fixed vertical axis, ignoring my roll.

              I hope that explanation is clear enough.

              I suspect that I will have to move to C++ now to be able to modify a DefaultPawn-derived class to not behave in this way?

              Thanks,
              Marius.

              Comment


                #8
                Hi,

                OK I have only one problem left, which so far I have not been able to solve. Perhaps someone knows why this is happening?

                I derive from DefaultPawn, and I disable registering of the input scheme used by DefaultPawn.

                In the Blueprint of the pawn, if I add pitch input, my pawn pitches. If I add roll input, my pawn rolls. But if I roll and then pitch, pitching happens on the original pitch axis, not taking the roll into account at all.

                Apart from this peculiar movement, networking works fine, and if open a server and client window, I can see both pawns, and their movement updates on both server and client.

                Thanks,
                Marius.

                Comment


                  #9
                  Originally posted by Marius View Post
                  Hi,

                  OK I have only one problem left, which so far I have not been able to solve. Perhaps someone knows why this is happening?

                  I derive from DefaultPawn, and I disable registering of the input scheme used by DefaultPawn.

                  In the Blueprint of the pawn, if I add pitch input, my pawn pitches. If I add roll input, my pawn rolls. But if I roll and then pitch, pitching happens on the original pitch axis, not taking the roll into account at all.

                  Apart from this peculiar movement, networking works fine, and if open a server and client window, I can see both pawns, and their movement updates on both server and client.

                  Thanks,
                  Marius.
                  Are you trying to add these rotations serially, or creating a rotator and adding the rotation that way? You'll probably need to do it the latter way so both rotations are taken into account, I'm guessing. Could be wrong :P
                  Storyteller - An immersive VR audiobook player

                  Dungeon Survival - WIP First person dungeon crawler with a focus on survival and environmental gameplay ala roguelikes

                  Comment


                    #10
                    Thanks for the suggestion, I will try your suggestion tonight. If it is the case, then it would be weird that one input would negate the other. But it is possible

                    Cheers,
                    Marius.

                    Comment

                    Working...
                    X