Please I need Help with my setFloor system

Hi I'm green in unity and too in PUN :) I'm trying that when a client change of floor in the map, this change only affect this client and not at all clients.

I'm using a script in a Trigger2D to send a value(CambiaPiso.cs) to setFloor(int i)(MapManager.cs), when setFLoor receive a value, this set activeself of floors in the map.
I'm tried with RPC but I could not achieve it :/
here Here is a demonstration of how works.... but when 1 player change of floor.... all change with him.
https://youtube.com/watch?v=K-uZyPJMjl4&feature=youtu.be

I need this to be done only on the client that walks through the trigger and not at all . Someone can help me to make this? :) (The comments are some pieces of my lasts tries)

Inspesctor of player prefab:
[img]https://preview.ibb.co/cN7Ntn/1.png [/img]

CambiaPiso.cs (the trigger2D(CambiaPisos) in the floor have this script)
https://preview.ibb.co/eJ4tYn/2.png

using System.Collections; using System.Collections.Generic; using UnityEngine; public class CambiaPiso : MonoBehaviour { // Use this for initialization [SerializeField] MapManager mapManager; public int numeroPiso; //PhotonView photonView; /*PhotonView id = gameObject.GetComponent<PhotonView> ().viewID; PhotonView a =PhotonView.RPC("setFloor", RPCMode.Server, id);*/ void Start () { } // Update is called once per frame void Update () { } void OnTriggerEnter2D(Collider2D col) { //photonView = col.gameObject.GetComponent<PhotonView> (); if (col.gameObject.tag == "Player") { if (mapManager.currentFloor == numeroPiso) { //photonView.RPC ("setFloor", PhotonTargets.MasterClient, numeroPiso-1); mapManager.setFloor (numeroPiso - 1); } else { //photonView.RPC ("setFloor", PhotonTargets.MasterClient, numeroPiso); mapManager.setFloor (numeroPiso); } } } }

CambiaPisos Inspector (the trigger2D in floor)
https://preview.ibb.co/grXmm7/4.png

MapManager.cs
https://preview.ibb.co/nrY967/3.png

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class MapManager : MonoBehaviour { public int currentFloor; [SerializeField] private GameObject currentMap; public Text txt; public static MapManager MP; //PhotonView view; void Awake() { MP = this; } void Start () { currentFloor = 0; setFloor (currentFloor); //view = this.GetComponent<PhotonView> (); } // Update is called once per frame void Update () { txt.text = currentFloor.ToString (); } [PunRPC] public void setFloor(int i) { currentFloor = i; switch (i) { case 0: currentMap.transform.GetChild (0).gameObject.SetActive (true); currentMap.transform.GetChild (1).gameObject.SetActive (true); currentMap.transform.GetChild (2).gameObject.SetActive (false); currentMap.transform.GetChild (3).gameObject.SetActive (false); break; case 1: currentMap.transform.GetChild (0).gameObject.SetActive (true); currentMap.transform.GetChild (1).gameObject.SetActive (true); currentMap.transform.GetChild (2).gameObject.SetActive (true); currentMap.transform.GetChild (3).gameObject.SetActive (false); break; case 2: currentMap.transform.GetChild (0).gameObject.SetActive (true); currentMap.transform.GetChild (1).gameObject.SetActive (true); currentMap.transform.GetChild (2).gameObject.SetActive (true); currentMap.transform.GetChild (3).gameObject.SetActive (true); break; case 3: currentMap.transform.GetChild (0).gameObject.SetActive (true); currentMap.transform.GetChild (1).gameObject.SetActive (true); currentMap.transform.GetChild (2).gameObject.SetActive (true); currentMap.transform.GetChild (3).gameObject.SetActive (true); break; default: break; } } }
GameManager Inspector
https://preview.ibb.co/hK7rKS/5.png

Thanks in advance.

Comments

  • Hi @Riukensay,

    if you have the possibility to set each tile individually from the MapManager, you can either use a RPC or the RaiseEvent function for this. In this case I would prefer the RaiseEvent function because it does not require an attached PhotonView component. Whenever a client enters a certain trigger, he can use PhotonNetwork.RaiseEvent(...) with an unique event code, the unique tile ID of the certain tile and the floor that you should be active afterwards. This might look like this:
    int[] eventContent = new int[] { tileId, newFloor };
    PhotonNetwork.RaiseEvent(uniqueEventCode, eventContent, true, new RaiseEventOptions { Receivers = ReceiverGroup.All });
    The MapManager requires an OnEvent function, which handles this custom event, like this:
    void OnEvent(byte eventcode, object content, int senderid)
    {
        if (eventcode == uniqueEventCode)
        {
            int[] eventContent = (int[])content;
    
            int tileId = eventContent[0];
            int newFloor = eventContent[1];
    
            // Do something with this data
        }
    }
    Do not forget to register this function. To set how this works, you can take a look at the RPCs and RaiseEvent documentation page.

    Hint: there a different ways to handle such a scenario. In my opinion the above one is the best solution therefore. Another way would be to use the Custom Room Properties, to store some information about changed tiles there. It is also possible, to network instantiate each tile (requires a PhotonView component) and to use either RPCs or the OnPhotonSerializeView function, to synchronize their state. However having a lot of PhotonView in your game is not the best solution.
Sign In or Register to comment.