0
\$\begingroup\$

I am very new to networking, and have ran into an issue, read below.

I have multiplayer system setup, where players can spawn, they can pick up weapons and drop them, there is an object representing a pickup with network identity component attached and local player authority enable, the player can come up to it and press "E", which will destroy the pickup object, then the player can press I to to "drop" that weapon, which instantiates it infront of the player, now this is what should happen, and it works on single player, but when there's 2 players, for second player(client only) it doesn't work as it should.

I have 1 script weapon manager and another small, Pickup (on pickup object child with trigger).

Below is the code and according description of my attempt so far:

Below is PickUp script (on 1st child of pickup object with trigger enabled)

private void OnTriggerStay(Collider other)
{
    if (other.CompareTag("Player"))
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            //Call pickup function on player, passing the weapon id and parent gameobject
            other.GetComponent<WeaponManager>().PickUpWeapon(weaponID, transform.parent.gameObject);
        }
    }
}

Below is WeaponManager script (on player)

public void PickUpWeapon(int id, GameObject go)
{
    CmdDestroyObj(go);

    //... (other code, not relevent)
}

[Command]
void CmdDestroyObj(GameObject obj)
{
    RpcDestroyObj(obj);
}

[ClientRpc]
void RpcDestroyObj(GameObject obj)
{
    // HERE obj is NULL   (!!ERROR!!)
    Destroy(obj);
}

Above in RpcDestroyObj() obj is null

void Update(){
  if(isLocalPlayer)
  {
    if (Input.GetKeyDown(KeyCode.I))
    {
       if (slots[currentActiveSlot] != null)
       {
          CmdDropWeapon();
       }
    }
  }
}

Then here's CmdDropWeapon() function:

[Command]
void CmdDropWeapon()
{
    RpcDropWeapon();
}

Here's RpcDropWeapon() function:

[ClientRpc]
void RpcDropWeapon()
{
    GameObject _drop = (GameObject)Instantiate(drops[currentGun.GetComponent<WeaponStats>().id], transform.position + transform.forward, Quaternion.identity);
    _drop.GetComponent<Rigidbody>().AddForce(transform.forward * 25000f * Time.deltaTime);

    CmdDestroyWeaponHeld() //Destroy currently held weapon (don't pay attention, not relevent to current problem

    currentGun = null;

    if (isLocalPlayer)
    {
        GetComponent<PlayerSetup>().playerUIInstance.GetComponent<PlayerUI>().SetInventorySlotFill(currentActiveSlot, -1);
        emptyHanded = true;
    }
}

On single player (so host & client), everything works besides destroying the pickup prefab that is Instantiated.

On multiplayer, second player (client only), can pick up and drop weapons as well as the originally spawned weapon is destroyed, but destroying the newly instantiated (so after player drops it) pickup object doesn't work.

(In the console there are no errors when UnityEditor is the Lan host/server, when 2 players are playing and I try picking up and dropping weapons several times from client side)

Why is this not working? I would appreciate any help/assistance in getting this right and sync over network for all players.

My guess is that, rpc function Instantiates the drop prefab but it's kind of different on all clients, so the server or another client doesn't have exactly the same object in the scene which means it will not find it and return null.

Let me know if you need any additional information.

Thanks a lot in advance!

\$\endgroup\$
1
\$\begingroup\$

On UNET, when you Instantiate and Destroy Objects (or deactivate, if such the case), you must make use of Spawn and Unspawn respectively, so those objects appear / dissapear on the other clients.

You still need to make use of Instantiate and Destroy, but you must add hat extra step. The given examples are from a tiny UNET test I've made:

[Command]
private void CmdShoot()
{
    shoot.Cast();
    shoot.currentBullet.GetComponent<Bullet>().scoreRetrieved = OnScoreMade;
    NetworkServer.Spawn(shoot.currentBullet);
}

public void OnDie()
{
    playerGUI.gameObject.SetActive(false);
    NetworkServer.UnSpawn(playerGUI.gameObject);
}

Hope it helps.

\$\endgroup\$
  • \$\begingroup\$ I am aware of NetworkServer.Spawn() and have tried using it, but it can only be used in [Command] function, when I tried that it didn't seem to sync it over to all clients so I have put everything back to [ClientRpc] \$\endgroup\$ – Vadim Tatarnikov May 13 '18 at 1:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.