Disabling a Remote Player's Body

Options
Hello, I have two different types of multiplayer players. I have a remote version and a local version. When the local version presses E, I want one of it's child gameobjects to be disabled on the remote version (for player model changing purposes). However, I cannot get it to work. I tried launching and RPC when the local version presses E that gets sent to everyone else and the function finds all gameobjects that are tagged with player, and if the gameobject's viewID is equal to the id of the person who press E, it's child gameobject is destroyed. However, everyone's gets destroyed. Does anyone know what I might be doing wrong? Is there a better approach?

Comments

  • Hi @DKMHorse,

    are the 'local' and the 'remote' version two different prefabs? How do you instantiate them? If it is just one prefab and you have used PhotonNetwork.Instantiate, then it should be relatively easy to gets things working by using RPCs. In any other case you might want to take a look at the PhotonNetwork.RaiseEvent function, to send custom events matching your needs.
  • DKMHorse
    DKMHorse
    edited September 2017
    Options
    Yes, they are two different prefabs. The problem is I want the model disabled on the remote version of it, but the only way I can think to link them is the photon view id. Also, the raise event you suggested is "without relation to some networked object," wouldn't I need the opposite of that?
    void Update () {
    		if(Input.GetKeyDown(KeyCode.E))
            {
                photonView.RPC("ChangeCharacter", PhotonTargets.OthersBuffered, GetComponent<PhotonView>().viewID);
            }
    	}
    
        [PunRPC]
        void ChangeCharacter(int id)
        {
            GameObject[] people = GameObject.FindGameObjectsWithTag("Player");
    
            for (int i = 0; i < people.Length; i++)
            {
                if (people[i].GetComponent<PhotonView>().viewID == id)
                {
                    Debug.Log(people[i].name + (people[i].GetComponent<PhotonView>().viewID.ToString() + id.ToString()));
                    people[i].transform.Find("RemoteFlash").gameObject.SetActive(false);
                }
            }
        }
  • You can use RaiseEvent to instantiate certain prefabs for certain players, 'owner' instantiates object A, all other clients instantiate object B. This might look like this:
    public void OnJoinedRoom()
    {
        int viewId = PhotonNetwork.AllocateViewID();
    
        PhotonNetwork.RaiseEvent(1, new int[] {viewId}, true, new RaiseEventOptions() { Receivers = ReceiverGroup.All, CachingOption = EventCaching.AddToRoomCache });
    }
    RaiseEvent call is added to OnJoinedRoom callback in this example. The actual event handler is in the same script and might look like this:
    private void OnEvent(byte eventcode, object content, int senderid)
    {
        if (eventcode == 1)
        {
            int[] data = (int[]) content;
    
            GameObject go;
    
            if (senderid == PhotonNetwork.player.ID)
            {
                go = Instantiate(Cube, Vector3.zero, Quaternion.identity);
            }
            else
            {
                go = Instantiate(Sphere, Vector3.zero, Quaternion.identity);
            }
    
            go.GetComponent<PhotonView>().viewID = data[0];
        }
    }
    Since this event is sent to all players, the caller actually receives it as well. Therefore the senderId is checked to decide which prefab gets instantiated. You can also change this behaviour by sending this event only to other clients and instantiate the game object directly before or after calling the RaiseEvent function on the local client.

    Both prefabs have a PhotonView component and a script attached handling what you want to achieve. In my example I simply disable the renderer of the object itself, you can relatively simple adjust that to fit your needs. This might look like the following:
    public void Update()
    {
        if (!pView.isMine)
        {
            return;
        }
    
        if (Input.GetKeyDown(KeyCode.E))
        {
            pView.RPC("ChangeCharacter", PhotonTargets.Others);
        }
    }
    
    [PunRPC]
    public void ChangeCharacter()
    {
        Renderer r = GetComponent<Renderer>();
    
        r.enabled = !r.enabled;
    }
    Hope that helps. If you still have questions please feel free to ask.