Photon Network (klassiek) beginnershandleiding

Photon Network is een service voor Unity waarmee ontwikkelaars realtime multiplayer-games kunnen maken.

Het biedt een krachtige en gebruiksvriendelijke API, waardoor het zelfs perfect is voor beginnende ontwikkelaars.

In dit bericht bespreken we het downloaden van de benodigde bestanden, het instellen van Photon AppID en het programmeren van een eenvoudig multiplayer-voorbeeld.

Deel 1: Fotonnetwerk opzetten

De eerste stap is het downloaden van het Photon Network-pakket van de Asset Store. Het bevat alle benodigde scripts en bestanden voor multiplayer-integratie.

  • Open uw Unity project en ga vervolgens naar Asset Store: (Venster -> Algemeen -> AssetStore) of druk op Ctrl+9
  • Zoek naar "Photon Unity Networking Classic - Gratis" en klik vervolgens op het eerste resultaat of klik hier
  • Importeer het Photon-pakket nadat het downloaden is voltooid

  • Nadat het pakket is geïmporteerd, moet u een Photon App ID aanmaken. Dit doet u op hun website: https://www.photonengine.com/
  • Maak een nieuw account aan (of log in op uw bestaande account)
  • Ga naar de pagina Applicaties door op het profielpictogram te klikken en vervolgens op "Your Applications" of volg deze link: https://dashboard.photonengine.com/en-US/PublicCloud
  • Klik op de pagina Toepassingen "Create new app"

  • Op de aanmaakpagina selecteert u bij Fotontype "Photon Realtime" en bij Naam typt u een willekeurige naam en klikt u vervolgens op "Create"

Zoals u kunt zien, is de applicatie standaard ingesteld op het gratis abonnement. U kunt hier meer lezen over prijsplannen

  • Zodra de applicatie is gemaakt, kopieert u de app-ID onder de app-naam

  • Ga terug naar je Unity-project en ga vervolgens naar Venster -> Foton Unity Netwerken -> PUN-wizard
  • Klik in de PUN-wizard op "Setup Project", plak uw app-ID en klik vervolgens "Setup Project"
  • Het fotonnetwerk is nu klaar

Deel 2: Een multiplayerspel maken

Laten we nu naar het gedeelte gaan waar we daadwerkelijk een multiplayer-game maken.

De manier waarop multiplayer in Photon wordt afgehandeld is:

  • Ten eerste maken we verbinding met de fotonregio (bijvoorbeeld VS-Oost, Europa, Azië, enz.), ook wel bekend als Lobby.
  • Eenmaal in de lobby vragen we alle kamers op die in de regio zijn gemaakt. Vervolgens kunnen we lid worden van een van de kamers of onze eigen kamer creëren.
  • Nadat we ons bij de kamer hebben aangesloten, vragen we een lijst op van de spelers die met de kamer zijn verbonden en instantiëren we hun Player-instanties, die vervolgens via PhotonView worden gesynchroniseerd met hun lokale instanties.
  • Wanneer iemand de kamer verlaat, wordt zijn exemplaar vernietigd en wordt hij van de spelerslijst verwijderd.

1. Een lobby opzetten

Laten we beginnen met het maken van een Hoofdmenu dat een Lobby-logica zal bevatten (door bestaande kamers bladeren, nieuwe kamers maken, enz.).

  • Maak een nieuwe scène en roep deze aan "MainMenu"
  • Maak een nieuw C#-script en noem het GameLobby
  • Maak in de hoofdmenuscène een nieuw GameObject. Noem het "_GameLobby" en voeg het GameLobby-script eraan toe

Open nu het GameLobby-script.

Laten we eerst alle benodigde variabelen maken:

    //Our player name
    string playerName = "Player 1";
    //This client's version number. Users are separated from each other by gameversion (which allows you to make breaking changes).
    string gameVersion = "0.9";
    //The list of created rooms
    RoomInfo[] createdRooms = new RoomInfo[0];
    //Use this name when creating a Room
    string roomName = "Room 1";
    Vector2 roomListScroll = Vector2.zero;
    bool joiningRoom = false;

Het volgende dat we moeten doen is het inschakelen van Auto-Join Lobby en Lobbystatistieken, hierdoor kunnen we de kamerlijst ontvangen. Dit wordt gedaan in de lege Start().

We schakelen ook automatischSyncScene in, zodat de scène automatisch wordt gesynchroniseerd zodra we ons bij de ruimte voegen.

En ten slotte noemen we PhotonNetwork.ConnectUsingSettings om verbinding te maken.

    // Use this for initialization
    void Start()
    {
        //Automatically join Lobby after we connect to Photon Region
        PhotonNetwork.PhotonServerSettings.JoinLobby = true;
        //Enable Lobby Stats to receive the list of Created rooms
        PhotonNetwork.PhotonServerSettings.EnableLobbyStatistics = true;
        //This makes sure we can use PhotonNetwork.LoadLevel() on the master client and all clients in the same room sync their level automatically
        PhotonNetwork.automaticallySyncScene = true;

        if (!PhotonNetwork.connected)
        {
            // Connect to the photon master-server. We use the settings saved in PhotonServerSettings (a .asset file in this project)
            PhotonNetwork.ConnectUsingSettings(gameVersion);
        }
    }

Om te weten of een verbinding met Photon Cloud succesvol was, moeten we deze 2 callbacks implementeren: OnReceivedRoomListUpdate() en OnFailedToConnectToPhoton(object parameters).

    void OnFailedToConnectToPhoton(object parameters)
    {
        Debug.Log("OnFailedToConnectToPhoton. StatusCode: " + parameters + " ServerAddress: " + PhotonNetwork.ServerAddress);
        //Try to connect again
        PhotonNetwork.ConnectUsingSettings(gameVersion);
    }

    void OnReceivedRoomListUpdate()
    {
        Debug.Log("We have received the Room list");
        //After this callback, PhotonNetwork.GetRoomList() becomes available
        createdRooms = PhotonNetwork.GetRoomList();
    }

Het volgende is het UI-gedeelte, waar het bladeren door kamers en het maken van kamers worden gedaan:

Fotonnetwerklobby

En als laatste implementeren we nog eens 4 callbacks: OnPhotonCreateRoomFailed(), OnPhotonJoinRoomFailed(object[] oorzaak), OnCreatedRoom() en OnJoinedRoom().

Deze terugbelverzoeken worden gebruikt om te bepalen of we lid zijn geworden van de ruimte of dat er problemen zijn opgetreden tijdens de verbinding.

    void OnPhotonCreateRoomFailed()
    {
        Debug.Log("OnPhotonCreateRoomFailed got called. This can happen if the room exists (even if not visible). Try another room name.");
        joiningRoom = false;
    }

    void OnPhotonJoinRoomFailed(object[] cause)
    {
        Debug.Log("OnPhotonJoinRoomFailed got called. This can happen if the room is not existing or full or closed.");
        joiningRoom = false;
    }

    void OnCreatedRoom()
    {
        Debug.Log("OnCreatedRoom");
        //Set our player name
        PhotonNetwork.playerName = playerName;
        //Load the Scene called GameLevel (Make sure it's added to build settings)
        PhotonNetwork.LoadLevel("GameLevel");
    }

    void OnJoinedRoom()
    {
        Debug.Log("OnJoinedRoom");
    }

En hier is het laatste GameLobby.cs-script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameLobby : MonoBehaviour
{
    //Our player name
    string playerName = "Player 1";
    //This client's version number. Users are separated from each other by gameversion (which allows you to make breaking changes).
    string gameVersion = "0.9";
    //The list of created rooms
    RoomInfo[] createdRooms = new RoomInfo[0];
    //Use this name when creating a Room
    string roomName = "Room 1";
    Vector2 roomListScroll = Vector2.zero;
    bool joiningRoom = false;

    // Use this for initialization
    void Start()
    {
        //Automatically join Lobby after we connect to Photon Region
        PhotonNetwork.PhotonServerSettings.JoinLobby = true;
        //Enable Lobby Stats to receive the list of Created rooms
        PhotonNetwork.PhotonServerSettings.EnableLobbyStatistics = true;
        //This makes sure we can use PhotonNetwork.LoadLevel() on the master client and all clients in the same room sync their level automatically
        PhotonNetwork.automaticallySyncScene = true;

        if (!PhotonNetwork.connected)
        {
            // Connect to the photon master-server. We use the settings saved in PhotonServerSettings (a .asset file in this project)
            PhotonNetwork.ConnectUsingSettings(gameVersion);
        }
    }

    void OnFailedToConnectToPhoton(object parameters)
    {
        Debug.Log("OnFailedToConnectToPhoton. StatusCode: " + parameters + " ServerAddress: " + PhotonNetwork.ServerAddress);
        //Try to connect again
        PhotonNetwork.ConnectUsingSettings(gameVersion);
    }

    void OnReceivedRoomListUpdate()
    {
        Debug.Log("We have received the Room list");
        //After this callback, PhotonNetwork.GetRoomList() becomes available
        createdRooms = PhotonNetwork.GetRoomList();
    }

    void OnGUI()
    {
        GUI.Window(0, new Rect(Screen.width/2 - 450, Screen.height/2 - 200, 900, 400), LobbyWindow, "Lobby");
    }

    void LobbyWindow(int index)
    {
        //Connection Status and Room creation Button
        GUILayout.BeginHorizontal();

            GUILayout.Label("Status: " + PhotonNetwork.connectionStateDetailed);

            if(joiningRoom || !PhotonNetwork.connected)
            {
                GUI.enabled = false;
            }

            GUILayout.FlexibleSpace();

            //Room name text field
            roomName = GUILayout.TextField(roomName, GUILayout.Width(250));

            if (GUILayout.Button("Create Room", GUILayout.Width(125)))
            {
                if (roomName != "")
                {
                    joiningRoom = true;

                    RoomOptions roomOptions = new RoomOptions();
                    roomOptions.IsOpen = true;
                    roomOptions.IsVisible = true;
                    roomOptions.MaxPlayers = (byte)10; //Set any number

                    PhotonNetwork.JoinOrCreateRoom(roomName, roomOptions, TypedLobby.Default);
                }
            }

        GUILayout.EndHorizontal();

        //Scroll through available rooms
        roomListScroll = GUILayout.BeginScrollView(roomListScroll, true, true);

            if(createdRooms.Length == 0)
            {
                GUILayout.Label("No Rooms were created yet...");
            }
            else
            {
                for(int i = 0; i < createdRooms.Length; i++)
                {
                    GUILayout.BeginHorizontal("box");
                    GUILayout.Label(createdRooms[i].Name, GUILayout.Width(400));
                    GUILayout.Label(createdRooms[i].PlayerCount + "/" + createdRooms[i].MaxPlayers);

                    GUILayout.FlexibleSpace();
                
                    if (GUILayout.Button("Join Room"))
                    {
                        joiningRoom = true;

                        //Set our Player name
                        PhotonNetwork.playerName = playerName;

                        //Join the Room
                        PhotonNetwork.JoinRoom(createdRooms[i].Name);
                    }
                    GUILayout.EndHorizontal();
                }
            }

        GUILayout.EndScrollView();

        //Set player name and Refresh Room button
        GUILayout.BeginHorizontal();

            GUILayout.Label("Player Name: ", GUILayout.Width(85));
            //Player name text field
            playerName = GUILayout.TextField(playerName, GUILayout.Width(250));

            GUILayout.FlexibleSpace();

            GUI.enabled = PhotonNetwork.connectionState != ConnectionState.Connecting && !joiningRoom;
            if (GUILayout.Button("Refresh", GUILayout.Width(100)))
            {
                if (PhotonNetwork.connected)
                {
                    //We are already connected, simply update the Room list
                    createdRooms = PhotonNetwork.GetRoomList();
                }
                else
                {
                    //We are not connected, estabilish a new connection
                    PhotonNetwork.ConnectUsingSettings(gameVersion);
                }
            }

        GUILayout.EndHorizontal();

        if (joiningRoom)
        {
            GUI.enabled = true;
            GUI.Label(new Rect(900/2 - 50, 400/2 - 10, 100, 20), "Connecting...");
        }
    }

    void OnPhotonCreateRoomFailed()
    {
        Debug.Log("OnPhotonCreateRoomFailed got called. This can happen if the room exists (even if not visible). Try another room name.");
        joiningRoom = false;
    }

    void OnPhotonJoinRoomFailed(object[] cause)
    {
        Debug.Log("OnPhotonJoinRoomFailed got called. This can happen if the room is not existing or full or closed.");
        joiningRoom = false;
    }

    void OnCreatedRoom()
    {
        Debug.Log("OnCreatedRoom");
        //Set our player name
        PhotonNetwork.playerName = playerName;
        //Load the Scene called GameLevel (Make sure it's added to build settings)
        PhotonNetwork.LoadLevel("GameLevel");
    }

    void OnJoinedRoom()
    {
        Debug.Log("OnJoinedRoom");
    }
}

2. Een Player-prefab maken

In multiplayer-spellen heeft de Player-instantie twee kanten: lokaal en extern.

Een lokale instantie wordt lokaal (door ons) beheerd.

Een externe instantie is daarentegen een lokale weergave van wat de andere speler doet. Het mag niet worden beïnvloed door onze inbreng.

Om te bepalen of de instantie lokaal of extern is, gebruiken we een component PhotonView.

PhotonView fungeert als een messenger die de waarden ontvangt en verzendt die moeten worden gesynchroniseerd, bijvoorbeeld positie en rotatie.

Laten we dus beginnen met het maken van de spelerinstantie (als u uw spelerinstantie al gereed heeft, kunt u deze stap overslaan).

In mijn geval zal de Player-instantie een eenvoudige kubus zijn die wordt verplaatst met de W- en S-toetsen en wordt geroteerd met de A- en D-toetsen.

Photon Network Player-instantie

En hier is een eenvoudig controllerscript:

PlayerController.cs

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        //Move Front/Back
        if (Input.GetKey(KeyCode.W))
        {
            transform.Translate(transform.forward * Time.deltaTime * 2.45f, Space.World);
        }
        else if (Input.GetKey(KeyCode.S))
        {
            transform.Translate(-transform.forward * Time.deltaTime * 2.45f, Space.World);
        }

        //Rotate Left/Right
        if (Input.GetKey(KeyCode.A))
        {
            transform.Rotate(new Vector3(0, -14, 0) * Time.deltaTime * 4.5f, Space.Self);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            transform.Rotate(new Vector3(0, 14, 0) * Time.deltaTime * 4.5f, Space.Self);
        }
    }
}

De volgende stap is het toevoegen van een PhotonView-component.

  • Voeg een PhotonView-component toe aan Player Instance
  • Maak een nieuw C#-script, noem het PlayerNetworkSync en open het (dit script wordt gebruikt om te communiceren via PhotonView)

Het eerste dat we moeten doen is MonoBehaviour vervangen door Photon.MonoBehaviour. Deze stap is nodig om de in de cache opgeslagen photonView-variabele te kunnen gebruiken in plaats van GetComponent<PhotonView>().

public class PlayerNetworkSync : Photon.MonoBehaviour

Daarna kunnen we doorgaan met het maken van alle benodigde variabelen:

    //List of the scripts that should only be active for the local player (ex. PlayerController, MouseLook etc.)
    public MonoBehaviour[] localScripts;
    //List of the GameObjects that should only be active for the local player (ex. Camera, AudioListener etc.)
    public GameObject[] localObjects;
    //Values that will be synced over network
    Vector3 latestPos;
    Quaternion latestRot;

Vervolgens controleren we in de leegte Start() of de speler lokaal of extern is met behulp van photonView.isMine:

    // Use this for initialization
    void Start()
    {
        if (photonView.isMine)
        {
            //Player is local
        }
        else
        {
            //Player is Remote
            for(int i = 0; i < localScripts.Length; i++)
            {
                localScripts[i].enabled = false;
            }
            for (int i = 0; i < localObjects.Length; i++)
            {
                localObjects[i].SetActive(false);
            }
        }
    }

De daadwerkelijke synchronisatie wordt uitgevoerd via de callback van PhotonView: OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info):

    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.isWriting)
        {
            //We own this player: send the others our data
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
        }
        else
        {
            //Network player, receive data
            latestPos = (Vector3)stream.ReceiveNext();
            latestRot = (Quaternion)stream.ReceiveNext();
        }
    }

In dit geval sturen we alleen de positie en rotatie van de speler, maar u kunt het bovenstaande voorbeeld gebruiken om elke waarde die nodig is om te worden gesynchroniseerd via het netwerk, met een hoge frequentie te verzenden.

Ontvangen waarden worden vervolgens toegepast in de void Update():

    // Update is called once per frame
    void Update()
    {
        if (!photonView.isMine)
        {
            //Update remote player (smooth this, this looks good, at the cost of some accuracy)
            transform.position = Vector3.Lerp(transform.position, latestPos, Time.deltaTime * 5);
            transform.rotation = Quaternion.Lerp(transform.rotation, latestRot, Time.deltaTime * 5);
        }
    }

Hier is het laatste PlayerNetworkSync.cs-script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerNetworkSync : Photon.MonoBehaviour
{
    //List of the scripts that should only be active for the local player (ex. PlayerController, MouseLook etc.)
    public MonoBehaviour[] localScripts;
    //List of the GameObjects that should only be active for the local player (ex. Camera, AudioListener etc.)
    public GameObject[] localObject;
    //Values that will be synced over network
    Vector3 latestPos;
    Quaternion latestRot;

    // Use this for initialization
    void Start()
    {
        if (photonView.isMine)
        {
            //Player is local
        }
        else
        {
            //Player is Remote
            for(int i = 0; i < localScripts.Length; i++)
            {
                localScripts[i].enabled = false;
            }
            for (int i = 0; i < localObject.Length; i++)
            {
                localObject[i].SetActive(false);
            }
        }
    }

    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.isWriting)
        {
            //We own this player: send the others our data
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
        }
        else
        {
            //Network player, receive data
            latestPos = (Vector3)stream.ReceiveNext();
            latestRot = (Quaternion)stream.ReceiveNext();
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (!photonView.isMine)
        {
            //Update remote player (smooth this, this looks good, at the cost of some accuracy)
            transform.position = Vector3.Lerp(transform.position, latestPos, Time.deltaTime * 5);
            transform.rotation = Quaternion.Lerp(transform.rotation, latestRot, Time.deltaTime * 5);
        }
    }
}
  • Voeg het PlayerNetworkSync.cs-script toe aan de PlayerInstance en wijs het toe aan de PhotonView Observed Components.
  • Wijs PlayerCntroller.cs toe aan de "Local Scripts" en wijs de GameObjects (die u wilt deactiveren voor externe spelers) toe aan de "Local Objects"

  • Sla de PlayerInstance op in Prefab en verplaats deze naar de map met de naam Resources (als zo'n map niet bestaat, maak er dan een). Deze stap is nodig om multiplayer-objecten via het netwerk te kunnen spawnen.

3. Een spelniveau creëren

GameLevel is een scène die wordt geladen nadat je de kamer hebt betreden en hier vindt alle actie plaats.

  • Maak een nieuwe scène en noem deze "GameLevel" (of als je een andere naam wilt behouden, zorg er dan voor dat je de naam in deze regel verandert: PhotonNetwork.LoadLevel("GameLevel"); in GameLobby.cs).

In mijn geval zal ik een eenvoudige scène met een vliegtuig gebruiken:

  • Maak nu een nieuw script en noem het RoomController. Dit script zorgt voor de logica in de kamer (zoals het spawnen van de spelers, het tonen van de spelerslijst, enz.).

Laten we beginnen met het definiëren van de noodzakelijke variabelen:

    //Player instance prefab, must be located in the Resources folder
    public GameObject playerPrefab;
    //Player spawn point
    public Transform spawnPoint;

Om de Player prefab te instantiëren gebruiken we PhotonNetwork.Instantiate:

    // Use this for initialization
    void Start()
    {
        //In case we started this demo with the wrong scene being active, simply load the menu scene
        if (!PhotonNetwork.connected)
        {
            UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
            return;
        }

        //We're in a room. spawn a character for the local player. it gets synced by using PhotonNetwork.Instantiate
        PhotonNetwork.Instantiate(playerPrefab.name, spawnPoint.position, Quaternion.identity, 0);
    }

En een eenvoudige gebruikersinterface met een knop "Leave Room" en enkele extra elementen, zoals de naam van de kamer en de lijst met verbonden spelers:

    void OnGUI()
    {
        if (PhotonNetwork.room == null)
            return;

        //Leave this Room
        if (GUI.Button(new Rect(5, 5, 125, 25), "Leave Room"))
        {
            PhotonNetwork.LeaveRoom();
        }

        //Show the Room name
        GUI.Label(new Rect(135, 5, 200, 25), PhotonNetwork.room.Name);

        //Show the list of the players connected to this Room
        for (int i = 0; i < PhotonNetwork.playerList.Length; i++)
        {
            //Show if this player is a Master Client. There can only be one Master Client per Room so use this to define the authoritative logic etc.)
            string isMasterClient = (PhotonNetwork.playerList[i].IsMasterClient ? ": MasterClient" : "");
            GUI.Label(new Rect(5, 35 + 30 * i, 200, 25), PhotonNetwork.playerList[i].NickName + isMasterClient);
        }
    }

En ten slotte implementeren we nog een PhotonNetwork-callback genaamd OnLeftRoom() die wordt aangeroepen wanneer we de kamer verlaten:

    void OnLeftRoom()
    {
        //We have left the Room, return to the MainMenu
        UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
    }

En hier is het laatste RoomController.cs-script:

using UnityEngine;

public class RoomController : MonoBehaviour
{
    //Player instance prefab, must be located in the Resources folder
    public GameObject playerPrefab;
    //Player spawn point
    public Transform spawnPoint;

    // Use this for initialization
    void Start()
    {
        //In case we started this demo with the wrong scene being active, simply load the menu scene
        if (!PhotonNetwork.connected)
        {
            UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
            return;
        }

        //We're in a room. spawn a character for the local player. it gets synced by using PhotonNetwork.Instantiate
        PhotonNetwork.Instantiate(playerPrefab.name, spawnPoint.position, Quaternion.identity, 0);
    }

    void OnGUI()
    {
        if (PhotonNetwork.room == null)
            return;

        //Leave this Room
        if (GUI.Button(new Rect(5, 5, 125, 25), "Leave Room"))
        {
            PhotonNetwork.LeaveRoom();
        }

        //Show the Room name
        GUI.Label(new Rect(135, 5, 200, 25), PhotonNetwork.room.Name);

        //Show the list of the players connected to this Room
        for (int i = 0; i < PhotonNetwork.playerList.Length; i++)
        {
            //Show if this player is a Master Client. There can only be one Master Client per Room so use this to define the authoritative logic etc.)
            string isMasterClient = (PhotonNetwork.playerList[i].IsMasterClient ? ": MasterClient" : "");
            GUI.Label(new Rect(5, 35 + 30 * i, 200, 25), PhotonNetwork.playerList[i].NickName + isMasterClient);
        }
    }

    void OnLeftRoom()
    {
        //We have left the Room, return to the MainMenu
        UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
    }
}
  • Maak ten slotte een nieuw GameObject in de GameLevel-scène en roep het aan "_RoomController"
  • Voeg het RoomController-script toe aan het _RoomController-object
  • Wijs de PlayerInstance-prefab en een SpawnPoint-transformatie eraan toe en sla vervolgens de scène op
  • Voeg zowel MainMenu als GameLevel toe aan de Build-instellingen.

4. Een proefbuild maken

Nu is het tijd om een ​​build te maken en deze te testen:

Sharp Coder Video speler

Alles werkt zoals verwacht!

Bonus

RPC

In Photon Network staat RPC voor Remote Procedure Call, het wordt gebruikt om een ​​functie aan te roepen op externe clients die zich in dezelfde kamer bevinden (je kunt er hier meer over lezen ).

RPC's hebben veel toepassingen. Laten we bijvoorbeeld zeggen dat je een chatbericht naar alle spelers in de kamer moet sturen. Met RPC's is het eenvoudig te doen.

[PunRPC]
void ChatMessage(string senderName, string messageText)
{
    Debug.Log(string.Format("{0}: {1}", senderName, messageText));
}

Let op de [PunRPC] vóór de functie. Dit kenmerk is nodig als u van plan bent de functie via RPC's aan te roepen.

Om de functies gemarkeerd als RPC op te roepen, hebt u een PhotonView nodig. Voorbeeld oproep:

PhotonView photonView = PhotonView.Get(this);
photonView.RPC("ChatMessage", PhotonTargets.All, PhotonNetwork.playerName, "Some message");

Pro-tip: als uw script een Photon.MonoBehaviour of Photon.PunBehaviour is, kunt u het volgende gebruiken: this.photonView.RPC().

Aangepaste eigenschappen

In Photon Network zijn Aangepaste eigenschappen een hashtabel die kan worden toegewezen aan de speler of de kamer.

Dit is handig als u permanente gegevens moet instellen die niet vaak hoeven te worden gewijzigd (bijvoorbeeld de teamnaam van de speler, de kamerspelmodus, enz.).

Eerst moet je een hashtabel definiëren, wat je doet door de onderstaande regel aan het begin van het script toe te voegen:

//Replace default Hashtables with Photon hashtables
using Hashtable = ExitGames.Client.Photon.Hashtable; 

In het onderstaande voorbeeld worden de kamereigenschappen ingesteld, genaamd "GameMode" en "AnotherProperty":

        //Set Room properties (Only Master Client is allowed to set Room properties)
        if (PhotonNetwork.isMasterClient)
        {
            Hashtable setRoomProperties = new Hashtable();
            setRoomProperties.Add("GameMode", "FFA");
            setRoomProperties.Add("AnotherProperty", "Test");
            PhotonNetwork.room.SetCustomProperties(setRoomProperties);
        }

        //Will print "FFA"
        print((string)PhotonNetwork.room.CustomProperties["GameMode"]);
        //Will print "Test"
        print((string)PhotonNetwork.room.CustomProperties["AnotherProperty"]);

Spelereigenschappen worden op dezelfde manier ingesteld:

        //Set our Player's property
        Hashtable setPlayerProperties = new Hashtable();
        setPlayerProperties.Add("PlayerHP", (float)100);
        PhotonNetwork.player.SetCustomProperties(setPlayerProperties);

        //Will print "100"
        print((float)PhotonNetwork.player.CustomProperties["PlayerHP"]);

Om een ​​specifieke eigenschap te verwijderen, stelt u de waarde in op null.

        //Remove property called "PlayerHP" from Player properties
        Hashtable setPlayerProperties = new Hashtable();
        setPlayerProperties.Add("PlayerHP", null);
        PhotonNetwork.player.SetCustomProperties(setPlayerProperties);
Voorgestelde artikelen
Maak een multiplayer-autospel met PUN 2
Unity voegt multiplayer-chat toe aan de PUN 2-kamers
Synchroniseer starre lichamen via netwerk met PUN 2
Maak een multiplayergame in Unity met PUN 2
Samen multiplayer-netwerkgames bouwen
Multiplayer-datacompressie en bitmanipulatie
Unity Online Leaderboard-tutorial