Search Unity

Create and Keep Track of Client List in Server...

Discussion in 'Multiplayer' started by Caps, May 6, 2011.

  1. Caps

    Caps

    Joined:
    Jul 23, 2010
    Posts:
    21
    Hi guys,


    Ok, for a few days now I´ve been trying to create a client list on a server. Now, I know this is probably not too difficult but since I´m no experienced programmer it´s just being kind of difficult! II´ve read some tutorials (Leepos and the Networking) but since most of the code is in js and part of their own project it´s being very complicated for me to grasp the functionality and stick it to my code... I kind of understand the concept of how it works though.

    The reason I´m trying manage client list is because of all the issues using network.instantiate and destroy.

    So, basically the design I´m using is clients control themselves (movement, firing etc.).

    Each client instantiates itself (game character) and sends an RPC to all (buffered) wich instantiates a clone of that game character with respective ID locally on each other client.

    What I want is to be able to create on server, a list o players, with their names and ID and have the server manage the instantiation and destroying the clients that arrive or leave (instead of using buffered RPCs).

    I just don´t know where to start. Here´s what I have untill now:


    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class Client_Start_Script : MonoBehaviour {
    7. public Transform playerPrefab;
    8. public Transform start_camera_Prefab;  
    9. public Camera client_camera;
    10. private Vector3 player_spawn_position;
    11. private Vector3 server_spawn_position; 
    12.  
    13.  
    14. public string player_name = null;  
    15.  
    16.  
    17. //Server-only playerlist
    18. public ArrayList playerList = new ArrayList();
    19.    
    20. public class PlayerNode
    21. {
    22.     public string player_name;
    23.     public NetworkPlayer networkPlayer;
    24. }
    25.    
    26. void Start ()
    27.    
    28. {
    29.         server_spawn_position = new Vector3(-3, 3,-20);
    30.         player_spawn_position = new Vector3(-3,20,-20);
    31.         Instantiate(start_camera_Prefab, server_spawn_position, transform.rotation);
    32.    
    33. }
    34.      
    35.  
    36.     //Server function
    37. void OnServerInitialized()
    38. {
    39.     PlayerNode newEntry  = new PlayerNode();
    40.     newEntry.player_name=player_name;
    41.     newEntry.networkPlayer=Network.player;
    42.     playerList.Add(newEntry);  
    43.  
    44. }
    45.  
    46.  
    47.  
    48.     void OnGUI()
    49.     {
    50.        
    51.             if (Network.isClient)
    52.             {
    53.                 if (GUILayout.Button("SpawnPlayer"))
    54.            
    55.                 {
    56.                    
    57.                 //Network.Instantiate(playerPrefab, player_spawn_position, transform.rotation, 0);
    58.                 NetworkViewID viewID = Network.AllocateViewID();
    59.                 networkView.RPC("SpawnPlayer", RPCMode.AllBuffered, viewID, transform.position);
    60.                 }
    61.             }
    62.     }
    63.    
    64.  
    65.  
    66.     [RPC]
    67.     void SpawnPlayer(NetworkViewID viewID, Vector3 location)
    68.    
    69.     {
    70.         Transform clone;
    71.         clone = Instantiate(playerPrefab, location, Quaternion.identity) as Transform;
    72.         NetworkView nView;
    73.         nView = clone.GetComponent<NetworkView>();
    74.         nView.viewID = viewID;
    75.        
    76.     }
    77.    
    78.    
    79. }
    80.  
    81.  
    82.  
    83.  
     
  2. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    If they all exist on all clients (and server), why not just do a: FindObjectsOfType or (or is that ByType? Whatever) on the server?

    Check the GameObject class in the docs for your choices. Each time a player is spawned just do a GetObjects call and you will have all of them in 1 line of code... :p

    Of course, there ARE other options also like having an Array on the server and each time a player is spawned, just do a playerList.add(player.gameObject);

    I would think the latter option would probably be a better option for adding players to your list, but once you start destroying players you could either do:
    "loop through the entire array comparing each entry to the one you want to destroy, update a counter for each iteration, keep a reference to it if found, break out of the loop if found, remove entry from the array using RemoveAt(), destroy it using the stored reference" or you could do "destroy object, call GetObjects to create the new list"

    These two methods i reckon are the easiest to do... Hope it helps

    Keep in mind the difference between the two types of Arrays, though. Using Array() you can use Add() to add stuff to it, you can use RemoveAt() and you can store either GameObjects, Transforms or components or basically any part of the character.

    Using the GetObjects version, you will end up with Unity's built in [] arrays which does NOT allow dynamic adding and removing of items in the array and you will be limited to the returned types of the function but apparently it offers a speed increase to use them over standard Array()'s so it might be worthwhile to use them. Although, if you are going to store GameObjects and each time you want to do something with the item you first have to do a GetComponent on the item in the array then it might be a better idea to create a new [] array that is the same length as the returned array, make it the class of the component you will use most often and store a reference to THAT instead.

    Remember, when you store a reference to a component, you automatically store a reference to the object also. Just like when you instantiate it. If your object has a component called "myclass" and another one called "myotherclass" you could do this:

    Code (csharp):
    1.  
    2. var playerPrefab:    myclass;
    3. var allPlayers    :    Array;
    4.  
    5. function Start()
    6. {
    7. allPlayers = new Array();
    8. }
    9.  
    10. function SpawnPlayer()
    11. {
    12. newplayer = Instantitate(playerPrefab);
    13. newplayer.someFuntionInMyclass();
    14.  
    15. otherClass = newplayer.GetComponent(myotherclass);
    16. allPlayers.Add(otherClass);
    17. }
    18.  
    19. function Shoot(playerIndex: int)
    20. {
    21. allPlayers[playerIndex].shootFunctionInMyOtherClass();
    22. }
    23.  
    24. function Teleport(playerIndex: int, location : Vector3)
    25. {
    26. allPlayers[playerIndex].transform.position = location;
    27. }
    28.  
    Not an example of good coding practices, but this should give you an idea of how you can store and access objects via their inherent components. Unity allows for a lot of freedom in this regard.
     
    Last edited: May 6, 2011
  3. Caps

    Caps

    Joined:
    Jul 23, 2010
    Posts:
    21
    Hello Mr. Dude,


    Thank you for your answers. Yes, I would like to try and create a list and manage things by this list. Meaning, as a client joins in, it will receive RPCs for creating each of those characters or objects in that list, and each character/object will have their specific ID from network view for syncronization.

    thanks again,


    Best regards,