Photon PUN 2 instantiating objects more than I want

57 Views Asked by At

I'm fairly new to making multiplayer games and using PUN 2. I am trying to make a tool system where the current tool you are using is synced across all players so everyone can see what you are using.

This script is working for the most part, but for some reason, the tools get instantiated twice. The extra objects are also not parented to anything, even though the script parents the instantiated object to the toolSlot transform.

public class ToolManager : MonoBehaviour, IPunObservable
{
    public SA_Tool[] Tools;
    public Transform toolSlot;
    private GameObject currentToolInstance;

    private PhotonView photonView;

    private void Start()
    {
        photonView = GetComponent<PhotonView>();
    }

    private void Update()
    {
        if (photonView.IsMine && Input.GetMouseButtonDown(0))
        {
            SwitchTool(0);
        }
    }

    private void SwitchTool(int newIndex)
    {
        DestroyCurrentTool();
        currentToolInstance = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs/Tool Models", Tools[newIndex].model.name), transform.position, transform.rotation);
        SetToolTransform(currentToolInstance);
        photonView.RPC("RPCSyncToolChange", RpcTarget.Others, newIndex);
    }

    private void SetToolTransform(GameObject tool)
    {
        tool.transform.SetParent(toolSlot, false);
        tool.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
    }

    private void DestroyCurrentTool()
    {
        if (currentToolInstance != null)
        {
            Debug.Log("Destroying current tool instance...");
            PhotonNetwork.Destroy(currentToolInstance);
        }
    }

    [PunRPC]
    private void RPCSyncToolChange(int newIndex)
    {
        DestroyCurrentTool();
        currentToolInstance = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs/Tool Models", Tools[newIndex].model.name), transform.position, transform.rotation);
        SetToolTransform(currentToolInstance);
    }
}

I've put in some Debug.Logs to check if it's destroying extra objects in the DestroyCurrentTool() method, but that never showed up in the console. I've also tried calling SetTool() in different methods, and it does the same thing, so I don't think it's because it's in the update method.

Again, I am very new to this, so if more information is needed, please let me know.

1

There are 1 best solutions below

1
derHugo On BEST ANSWER

You are calling

PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs/Tool Models", Tools[newIndex].model.name), transform.position, transform.rotation);

twice, once in SwitchTool and then again in the RPC.

Each of these calls will instantiate the object network wide for all clients!

So let's say you have e.g. 3 players then

  • you call this local => spawns the object on all 3 clients
  • you send RPC to both other players
  • both spawn another two instances for all clients
  • you end up with 3 instances on all players

In your case you shouldn't use a networked spawn at all since your RPC anyway is build in the way that the destroy and instantiate is also done on the remote clients.

=> It should probably simply be

currentToolInstance = Instantiate(Tools[newIndex].model), transform.position, transform.rotation);
SetToolTransform(currentToolInstance);

and accordingly also use a normal

Destroy(currentToolInstance);