Announcement

Collapse
No announcement yet.

In a networked environment, when does the player's pawn actually get created?

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

    In a networked environment, when does the player's pawn actually get created?

    I've set up a HUD that is supposed to be added to the viewport as soon as the game starts which right now is immediately after the project is run. For the server, everything works great. This is my player controller event graph

    Click image for larger version

Name:	7h5aLBX.png
Views:	1
Size:	76.5 KB
ID:	1186031

    The elements in the HUD look to display variables that exist on the pawn. But when a client connects, it seems to take a while for the pawn to actually be spawned. By "a while", I simply mean the pawn does not yet exist when this is executed which is why I have the "switch has authority" in there, because if I try to run it for the client too I get flooded with errors.

    Unfortunately, I don't see a good way to handle this. A few months ago I was researching a similar issue and someone referenced a function available in the gamemode called "OnPostLogin" which I thought helped somehow but now I don't recall what it was supposed to do. I thought it might mean "The client has finished its initialization and has a pawn", so I tried the following:

    This is in my gamemode event graph

    Click image for larger version

Name:	okLa3Pc.png
Views:	1
Size:	48.8 KB
ID:	1186032

    And changed this in my controller blueprint

    Click image for larger version

Name:	GziAB4n.png
Views:	1
Size:	68.8 KB
ID:	1186033

    But this doesn't change anything. Is there a good way to determine when a pawn is spawned and ready to be referenced?

    #2
    Even on possess on the player controller?

    Comment


      #3
      OnPossess? That .. doesn't seem to be an option although it sounds promising if it exists..

      (From my player controller BP)
      Click image for larger version

Name:	iNS8CsP.png
Views:	1
Size:	12.6 KB
ID:	1108235

      Comment


        #4
        OnPostLogin is called when the Client has a valid PlayerController.

        This is not about the PlayerPawn.

        Your SwitchHasAuthority completely blocks off the Client, since you only call this on the Server.

        What you need to do, is calling it as Remote AND Authority, but as Authority, you need to make sure it's the Server's PlayerController.
        Clients only have one PlayerController anyway. You can do that by simply using the function IsLocalPlayerController + a branch.

        Another way would be using the OnPostLogin Event and using a "RunOnOwningClient" RPC on the PlayerController.

        You should read my network compendium: http://cedric.bnslv.de/unreal-engine...dium-released/
        Open for contracted work | C++/BP (incl. Multiplayer) | Tutoring | VR

        My UE4 Blog/Page with Tutorials and more: Hit me for ALL the things!
        (Including 100+ Pages Multiplayer Network Compendium to get you started.)

        Comment


          #5
          Oh, they are in the pawn, not in the controller.
          Luckily you can easily forward from your pawns to your controller using some interface or casting approach.

          Comment


            #6
            Originally posted by eXi View Post

            Your SwitchHasAuthority completely blocks off the Client, since you only call this on the Server.
            Yeah, I had mentioned that in the first post.

            Originally posted by Chumble View Post
            the pawn does not yet exist when this is executed which is why I have the "switch has authority" in there, because if I try to run it for the client too I get flooded with errors.
            Originally posted by eXi View Post

            What you need to do, is calling it as Remote AND Authority, but as Authority, you need to make sure it's the Server's PlayerController.
            Clients only have one PlayerController anyway. You can do that by simply using the function IsLocalPlayerController + a branch.

            Another way would be using the OnPostLogin Event and using a "RunOnOwningClient" RPC on the PlayerController.

            You should read my network compendium: http://cedric.bnslv.de/unreal-engine...dium-released/
            Soo something like this?

            Click image for larger version

Name:	T7nD6xL.png
Views:	1
Size:	98.0 KB
ID:	1108238

            This doesn't solve anything from the remote client perspective though. The pawn is still not valid at the time that this runs so every HUD element that initializes by trying to get the player pawn causes errors. I could potentially rectify this by doing a EventBeginPlay on the player pawn to initialize the HUD elements but that's a bit of a backwards way to go about it I think. Overall, it might be the only choice if there's no way to detect a valid pawn.

            Comment


              #7
              If you need the Pawn Reference inside of the HUD Widget to be valid, yoi either spawn the HUD in the Pawn, like you said, or, which is better, simply use 'IsValid' on the Pawn Reference and only use the reference if it's Valid.
              Open for contracted work | C++/BP (incl. Multiplayer) | Tutoring | VR

              My UE4 Blog/Page with Tutorials and more: Hit me for ALL the things!
              (Including 100+ Pages Multiplayer Network Compendium to get you started.)

              Comment


                #8
                But that leads me back to the same problem of needing to essentially running a loop on Pawn-->IsValid and every time I do that it tells me it's an infinite loop.

                So this is pretty much what shows up in each of my HUD elements

                Click image for larger version

Name:	LBekW2x.png
Views:	1
Size:	103.8 KB
ID:	1108241

                When this is called for clients, it's invalid so the "Cast to MyCharacter" returns false and .. that's where it ends.

                And if I do something like this

                Click image for larger version

Name:	uHX9YQW.png
Views:	1
Size:	128.8 KB
ID:	1108242

                The editor ends telling me it's an infinite loop which is incorrect but I guess it runs through enough iterations that it triggers it.

                I was able to hack together some awful script that used the Event Tick to check over and over if the GUI had been initialized and if it didn't keep trying. This got around the infinite loop error but it's SO MESSY. Plus I like to avoid Event Tick if I can.

                This is why I was looking for some kind of event that would tell me exactly when a pawn exists.

                Comment


                  #9
                  Originally posted by Chumble View Post
                  This is why I was looking for some kind of event that would tell me exactly when a pawn exists.
                  Yeah well, that's the BeginPlay of the Pawn

                  Well, if you need the Pawn on Construct, then you need the Pawn to initialize the HUD creation.

                  So use the Pawns BeginPlay. But that doesn't solve the death of a Pawn. If you happen to destroy him, the reference will be NULL again.

                  So you need to fill that variable when the Player gets created.

                  You could create a reference Variable in the HUD and create the HUD when the PlayerController is ready.
                  Then, when the Pawn gets created/possessed, you use its BeginPlay to tell the PlayerController to fill the Variable in the HUD.
                  Or you just get the HUD reference and fill it yourself from inside of the Pawns BeginPlay. Doesn't matter.

                  In the HUD you just use an IsValid on the Reference for your bindings. So you don't get Accessed None errors until the Player gets spawned.
                  Open for contracted work | C++/BP (incl. Multiplayer) | Tutoring | VR

                  My UE4 Blog/Page with Tutorials and more: Hit me for ALL the things!
                  (Including 100+ Pages Multiplayer Network Compendium to get you started.)

                  Comment


                    #10
                    It's strange because I feel like this should be a fairly common thing every person who creates a networked game with UMG needs to deal with and it just feels so .. messy!


                    Ok, so the Player Controller spawns the GUI, but I'll need to remove the "Event Construct" nodes since the references wont be available then.

                    In the Pawn, I should use a "Get Controller" to get a reference to my Player Controller (that works, right?) and inform it that the Pawn is ready.

                    From there, I get each HUD element and call an initialize function to set up the references for the Pawn.

                    And in the meantime, the HUD elements will check for the Pawn's validity before attempting to access it.

                    I'll give this a try tonight. Thanks for your responses.

                    Comment


                      #11
                      So I tried this out. So far .. not good. Then I read through your document - a few good things in there I didn't know! Will be referencing it in the future. Unfortunately, right now it doesn't seem to help me.

                      I currently have this on my Pawn



                      Just as a test. I would have expected this to be called 4 times, twice for the server and twice for the client and for each pair there should be a "I am locally controlled" and a "I am NOT locally controlled". Instead..



                      So the client is always returning false for "Is Locally Controlled". I did some research and some people suggested that when "Event BeginPlay" is called on the pawn, this is not yet set up internally. To test this, I added a 2 second delay immediately after the Event BeginPlay. The result...



                      So it would seem that even in "Event BeginPlay", the pawn isn't yet fully set up. So where can I actually call this stuff when I can be sure that things are actually done loading? Because I'm not going to just put a 2 second delay in and call it a "solution". I feel like this is something everyone has had to deal with so why does it seem like I'm the only one struggling with it?

                      Comment


                        #12
                        I would simply think your Pawn isn't possessed when the BeginPlay gets called. So the "IsLocallyControlled" will return false, because there is no Controller yet.
                        Open for contracted work | C++/BP (incl. Multiplayer) | Tutoring | VR

                        My UE4 Blog/Page with Tutorials and more: Hit me for ALL the things!
                        (Including 100+ Pages Multiplayer Network Compendium to get you started.)

                        Comment


                          #13
                          So what's the right way to do this? The pawn doesnt exist when the controller is created, the pawn isn't possessed when it is created .. how can I ensure this is ready? This is so frustrating.



                          This is the source of an absolutely massive amount of frustration. And it's not even like I'm doing something crazy - this is something literally every single person who uses UMG with networking needs to deal with. Why does it seem like no one knows what's going on?
                          Last edited by Chumble; 06-14-2016, 10:16 PM.

                          Comment


                            #14
                            If it needs to always be on screen, how about making it your HUD as part of your GameMode?

                            Comment


                              #15
                              The creation of the HUD isn't the issue. Right now I'm creating it on the controller. The problem is the HUD relies on variables from the Pawn and trying to get the controller and pawn in sync is apparently a MASSIVE headache. I'm losing sleep over this. Seriously. I just want to continue with this project and I'm hung up on such a stupid part.

                              Edit: Sorry if I'm kinda coming off as snippy. I'm very upset



                              OK. I think I found another way to go about this. I didn't think I'd have to do this but now that I've done it this way.. it makes more sense.

                              I focused primarily on the GameMode. I set the default pawn to be null.

                              In the GameMode I used the Event OnPostLogin to spawn an actor of my character pawn. I then cast the "new player" pin to my player controller and assigned to it the spawned pawn.

                              Then I used the pin from the spawned pawn to assign my reference to the player controller.

                              Then I told the controller to possess the pawn and initialize the HUD. Seems to be working so far.
                              Last edited by Chumble; 06-14-2016, 11:32 PM.

                              Comment

                              Working...
                              X