Search Unity

Trouble adding item pickups in multiplayer game - UNet

Discussion in 'UNet' started by ComputerFido, Sep 4, 2017.

  1. ComputerFido

    ComputerFido

    Joined:
    Jul 10, 2015
    Posts:
    2
    So this is what I am trying to implement in my multiplayer game using unet: Items spawn around the map and players press 'F' to pick them up, but I am getting many problems to do with the networking. First, I had an implementation but it only made changes to the current client and so if a object was picked up then the item would still be there for the other clients. I realized my problem so I tried using ServerManager.Spawn. As the object had to be in the spawnable prefabs in the network manager I created a new prefab which would contain the item and the rigidbody and the actual model of the item with the collider would be the child as the model is used elsewhere. But, for some reason on the client that is not the host the prefab that is registered under spawnable is getting spawned but no the model. I suspect this is to do with my use of Instantiate but I am not sure what to do as I am planning to add many more tiems and I don't want a long list of spawnable prefabs in my network manager. If it is the only way I am willing to do so though. My code:

    Item.GetItem(int) - gets the item at the specified id
    Item.gfx.model - contains the gameobject for the item model

    The code for the spawner:

    1. [SerializeField]
    2. int[] spawns;
    3. Item item;
    4. [SerializeField]
    5. GameObject droppedItem;
    6. GameObject drop;
    7. GameObject model;
    8. // Use this for initialization
    9. public override void OnStartServer () {
    10. item = Items.GetItem(spawns[Random.Range(0, spawns.Length)]);
    11. drop = Instantiate(droppedItem,transform.position, Quaternion.identity);
    12. drop.GetComponent<DroppedItem>().item = item;
    13. model = Instantiate(item.gfx.model, transform.position, item.gfx.model.transform.rotation, drop.transform);
    14. model.GetComponent<MeshCollider>().enabled = true;
    15. model.tag = "DroppedItem";
    16. drop.GetComponent<DroppedItem>().Init();
    17. NetworkServer.Spawn(drop);
    18. //NetworkServer.Spawn(model);
    19. }
    The small init code for the item:

    1. public Item item;
    2. bool initialized = false;
    3. public void Init () {
    4. if (initialized) return;
    5. item.InitForSpawn();
    6. initialized = true;
    7. }
     
  2. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    A common way to do it is the following:
    1. Client presses pickup button.
    2. Client checks if it hit a pickupitem with a raycast.
    3. If its true. it sends a blind pickup request to server.
    4. Server then also does a raycast to make sure the client is not lying about hitting it. Depending on how the game is designed. You might want to add some wiggle room on the server end to account for errors. But that's depending on how your movement is handled.
    5. If it hit on the server. It will pick the item up on the server and then tell all the clients that the requesting client picked the item up.
    6. To prevent latency on the client thats requesting the pickup. You might want to instantly simulate the pickup action and then if it failed on the server, just make the server tell Only the requesting client to revert the action (This should be a rare case by design, if the chance of it failing is high. This will create confusion for the player and you might want to just deal with the latency and wait for the server reply).


    This also makes the pickup "Authorative" (Cheat proof, atleast as long as your movement is authorative or atleast is being verified)
     
  3. ComputerFido

    ComputerFido

    Joined:
    Jul 10, 2015
    Posts:
    2
    Thanks, but pickup up the item is only part of the problem. I have a prefab which is the item model but this is used in two places - the item the player is holding and the item spawn. My problem is I need to spawn the model prefab and either
    1. Have a DroppedItem prefab and the model is the child - i tried this but the model didn't spawn as the child on the client
    2. Add the DroppedItem script to and instance of the item model, set the tag and spawn it (which is what I was trying to do) but, the DroppedItem script and the tag is only added on the server
     
  4. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    No, Things don't happend automatically. If you however make your spawn code spawn it as a child. It will. That's how programming works.