Despawn projectiles on all clients depending on master



  • Yes, you can basically turn around the current OnTriggerEnter method:

    • copy + remove all the visual parts happening on the client (before the IsMasterClient check)
    • add a call to your new RpcBulletDespawn method at the end
    • in that separate Rpc method, paste the visual parts again

    This way only the master controls visual and despawn. As I said, this heavily increases the amount of RPCs in the room (by the amount of bullets * player count).



  • Hi,

    I'm thinking about migrating only the on hit despawns to the master client, other despawns that happen due to bullet lifetime expiring will still happen on each client side. And the game is 1v1, so the amount of successful hits happening at a given time won't be too big I think.

    Do you think there's a flaw in my thinking?



  • In a 1v1 room this doesn't have any big impact indeed.



  • Got stuck.

    Where do I have to define the RpcBulletDespawn method in order to make it work? Did try it on the bullet.cs, but it didn't work. Probably because there's no photonview on the bullets.

    Any suggestions?



  • There is a PhotonView on the Bullet prefab.

    @sahinyalabik said in Despawn projectiles on all clients depending on master:

    Did try it on the bullet.cs, but it didn't work.

    Error message please.



  • OK, here's what I achieved so far:

    I created this method in the bullet.cs

    [PunRPC]
           protected virtual void RpcDespawnBullet()
           {
               PoolManager.Despawn(gameObject);
               if (hitFX) PoolManager.Spawn(hitFX, transform.position, Quaternion.identity);
               if (hitClip) AudioManager.Play3D(hitClip, transform.position);
               Debug.Log("HIT");
           }
    

    I'm calling it within the TriggerEnter in the bullet.cs after the IsMasterClient check with the following line:

    this.photonView.RPC("RpcDespawnBullet", RpcTarget.AllViaServer);

    It works except for 1 fatal error: Every time there's a hit, all the bullets are despawned instead of just the hitting one, and I get the following error:

    Had to lookup view that wasn't in photonViewList: View 0 on Bullet(Clone)002 (scene)
    UnityEngine.Debug:LogWarning(Object)
    Photon.Pun.PhotonNetwork:GetPhotonView(Int32) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:822)
    Photon.Pun.PhotonNetwork:ExecuteRpc(Hashtable, Player) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:335)
    Photon.Pun.PhotonNetwork:RPC(PhotonView, String, RpcTarget, Player, Boolean, Object[]) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:1118)
    Photon.Pun.PhotonNetwork:RPC(PhotonView, String, RpcTarget, Boolean, Object[]) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetwork.cs:2779)
    Photon.Pun.PhotonView:RPC(String, RpcTarget, Object[]) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonView.cs:411)
    


  • Ah. If you play a round and have a look at the Bullet instances in the scene, you can see that all of them are assigned to the scene with an Photon ViewID of 0.

    That's because although they have a PhotonView component, they are still instantiated locally, not over the network. Open Pool.cs which instantiates the bullets in the PreLoad() method, line 81. Instead of the local format

                    //instantiate new instance of the prefab
                    GameObject obj = (GameObject)Object.Instantiate(prefab, Vector3.zero, Quaternion.identity);
    

    it should use PhotonNetwork.Instantiate when the prefab starts with "Bullet" (check your prefab names or modify that):

                    //instantiate new instance of the prefab
                    GameObject obj = null;
                    if(prefab.name.StartsWith("Bullet"))
                        obj = Photon.Pun.PhotonNetwork.Instantiate(prefab.name, Vector3.zero, Quaternion.identity);
                    else
                        obj = (GameObject)Object.Instantiate(prefab, Vector3.zero, Quaternion.identity);
    

    Additionally move all Bullet prefabs into the Resources folder as otherwise Photon is not able to instantiate them. Play the scene again and you should notice that all Bullet instances have a unique ViewID.

    Report back if there are more issues.



  • Worked like a charm!

    Thanks again for the effort & keep up the amazing work!



  • Actually, when I tested with 2 clients, I noticed that 10 bullets are instantiated in the middle of the screen (visible), and they exist not within the scripts/poolmanager/projectiles, but in the root of the scene.
    Mechanically, it's also not working. Although the master scores the hit correctly. slaves can't.
    https://imgur.com/a/EeQ1ypE



  • The Pool instantiation code is called on all clients - have you tried letting only the master instantiate bullets (IsMasterClient)? It is likely that the bullets under the Pool are local ones, and the ones floating around in the scene are the networked bullets.

    If you get to keep only the networked bullets, probably the master needs to despawn them instantly in the next step.

    It's a bit more complicated than I thought, because the PoolManager and Pool instances are not synchronized over the network. And when shooting, the Player "spawns" a bullet instance from the Pool instead of getting one from the master client. Simply telling the master that a player wants to shoot, and the master using PhotonNetwork.Instantiate a bullet at that position would be easy, but it has an additional layer of complexity when using Pools.


Log in to reply