Search Unity

MLAPI - Camera & Movement with IsLocalPlayer

Discussion in 'Netcode for GameObjects' started by si_wattsy, Aug 27, 2021.

  1. si_wattsy

    si_wattsy

    Joined:
    Jan 29, 2013
    Posts:
    2
    Hey All,

    Sorry quite new to unity and am just playing about with MLAPI have successfully coded something single player that resembles a procedurally generated world. I've been through the tutorial and several posts by other lost developers and I have also reviewed the MLAPI docs (which I find generally quite poor). Hoping that someone here can spot something or at least point me in the right direction

    So I am currently using the StarterAssets and the first person player capsule and FirstPersonController. I have made the following changes to the prefabs & FirstPersonController script;

    1. Camera disabled in the prefab
    2. Audio Listener disabled in the prefab
    3. FirstPersonController script now extends NetworkBehaviour
    4. Add
    Code (CSharp):
    1. _mainCamera.GetComponent<Camera>().enabled = IsLocalPlayer;
    to the Update method of FirstPersonController (I tried this in awake and start and basically the value of IsLocalPlayer was always false regardless).
    5. Add
    Code (CSharp):
    1.  
    2. _mainCamera.GetComponent<AudioListener>().enabled = IsLocalPlayer;
    3.  
    to the Update method of FirstPersonController (I tried this in awake and start and basically the value of IsLocalPlayer was always false regardless).
    6. Wrapped all movement and camera control in
    Code (CSharp):
    1. if (IsLocalPlayer)
    I have added a network manager and set the default player prefab to the player capsule.

    If I then hit player in editor and host a new game - great the player spawns in and everything is controllable as if I were just on a single player.

    If I then build a version of the game (and I wont go into how annoying this is to test multiplayer) my first player (host) works fine as above but second player (client) has the camera from the first player capsule enabled even though the actual player capsule for the 2nd player (client) has spawned in correctly.

    So here is what I have observed so far on debugging;

    IsLocalPlayer is always false in the awake method
    IsLocalPlayer is always true (regardless of if I am a host or a client) on the first spawned player
    IsLocalPlayer is always false (regardless of if I am a host or a client) on additionally spawned player

    I have no idea why this would be as it seems like a simple use of the parameter.

    I am currently using unity version 2021.2.0b6

    I understand that I will need to do RPC calls to ultimately update and sync servers and clients but this is predominantly about the initial setup of the player and IsLocalPlayer behaving weirdly.

    I tried removing the Default Player Prefab from network manager and using my own spawn with SpawnWithOwnership (and then using IsOwner to determine camera and movement) but unity just falls over when you have no default player prefab.

    Any ideas on where to go from here for debugging would be most appreciated as everything I read seems to point back to using IsLocalPlayer in a similar way that I am currently doing it.

    Thanks
     
  2. si_wattsy

    si_wattsy

    Joined:
    Jan 29, 2013
    Posts:
    2
    So I think I have got to the bottom of this in case anyone else happens on the same issue. The first person controller comes with the following code to "fetch" the camera;

    Code (CSharp):
    1. _mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
    It clicked that this was just looking at all GameObjects and always finding the first object with the tag "MainCamera" - this is obviously OK for a single player game where there is one FPS camera.

    This was therefore only ever running for the first camera and producing the behaviour that I saw

    Instead I needed to traverse the child game objects to find the camera. Right now this is "working" but does not look optimal;

    Code (CSharp):
    1. if (_mainCamera == null)
    2. {
    3.                 foreach(Transform child in gameObject.transform)
    4.                 {
    5.  
    6.                     if(child.name == "PlayerCameraRoot")
    7.                     {
    8.                         foreach(Transform granchild in child.transform)
    9.                         {
    10.                             if(granchild.tag == "MainCamera")
    11.                                 _mainCamera = granchild.gameObject;
    12.                         }
    13.                     }
    14.                 }
    15. }
    Not quite sure if there is an easier way to get child games objects using default unity but I will look for that separately
     
  3. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    Regarding the issue of `IsLocalPlayer` being always false in Awake and Start, that's unfortunately the case. You should use NetworkStart for this.

    Code (CSharp):
    1. public class Example : NetworkBehaviour
    2. {
    3.     public override NetworkStart()
    4.     {
    5.         // This object is now spawned across the network and fully initialized.
    6.     }
    7. }
     
  4. ireakhavok

    ireakhavok

    Joined:
    Feb 9, 2023
    Posts:
    19
    So when I tried this... isLocalPlayer is still false, even though it's a host session.
     
  5. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    @ireakhavok Have you already had a look at the examples in the official ClientDriven sample?

    If not, you can download it here.

    Its examples show how to use the third person controller asset in a multiplayer environment for movement and picking objects up
     
  6. ireakhavok

    ireakhavok

    Joined:
    Feb 9, 2023
    Posts:
    19
    I fixed my issue by creating the camera first, then player, and on start if not spawned then just return.

    It will eventually be spawned, then it will go into an RPC call to get the camera and send back to the client so that they can link in the movementcode. I used a networkobjectreference in the clientRPC call and then did a tryout using that reference to grab the reference of the network camera.


    I want to use fully authoritative, because in future I plan on making the players appear / not appear when raycasted serverside, so that cheaters can never wallhack, etc. I also want it to be server authoritative for several other reasons being that we do plan on making it a fully implemented game. Currently right now I am about to take a look at the spectre1989 example from github that also has the client side prediction. but I have fears in rearchitecting some of this code due to it's complexity. however, it's inevitable. Trying to find sources of examples online that still work is hard. The boss room example didn't work for me when I tried to open it, even after installing the version of unity that it asked for. I've seen your post several times, and have been tempted, but after speaking with my other devs, we feel it is definitely not the way we want to go. however there may be instances where we could do it for "instanced" areas if we decide to go that route in some areas of the game.
     
    Last edited: Mar 1, 2023
  7. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    That's ok, and I was not suggesting to go client-authoritative. I was suggesting to check how the sample handles player initialization / setup.

    The point is, if your camera is being networked your'e doing something wrong.

    UI, VFXs, SFXs and cameras should never be networked.

    The proper way to do this is to instantiate a camera for the LocalPlayer when it spawns.
     
  8. ireakhavok

    ireakhavok

    Joined:
    Feb 9, 2023
    Posts:
    19
    but doesn't this mean that the player can move his own camera? or inject their own code to move the camera? I want the server to handle what the player can see and it's location, and thus must have authority over where it is positioned. I already have this working and linked to the player after they spawn. I'm having issues with collisions currently and am chatting in another netcode thread. Maybe your input would be nice as a counter to what I'm doing.
     
  9. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    @ireakhavok Got it. Yes, the player will be able to move its camera.

    I have a feeling that what you're really looking for is Object Visibility, but if that's not it, feel free to go with whatever approach works for your case!
     
  10. ireakhavok

    ireakhavok

    Joined:
    Feb 9, 2023
    Posts:
    19
    yes @RikuTheFuffs-U, Object visibility based on the server tracing from camera location to other player points. basically to combat all forms of wall hacking and "radar". I just don't want the chance of players to position their own camera to get an advantage in that kind of situation.

    But IDK my other issues I'm having are going to be more of a roadblock than that kind of server management. Non-deterministic collisions are, I assume, to be a cause of issue on multiple fronts of my progress, so far. I don't know how to combat this. The physics/networking solution of netcode in conjunction with my code is causing some issues that I don't know how to alleviate.

    https://forum.unity.com/threads/ful...ller-client-is-having-trouble-moving.1406158/