Panduan Pemula Jaringan Foton (Klasik).

Photon Network adalah layanan untuk Unity yang memungkinkan pengembang membuat game multipemain waktu nyata.

Ini menyediakan API yang kuat dan mudah digunakan sehingga membuatnya sempurna bahkan untuk pengembang pemula.

Dalam posting ini, kita akan mulai mengunduh file yang diperlukan, mengatur Photon AppID, dan memprogram contoh multipemain sederhana.

Bagian 1: Menyiapkan Jaringan Foton

Langkah pertama adalah mengunduh paket Photon Network dari Asset Store. Ini berisi semua skrip dan file yang diperlukan untuk integrasi multipemain.

  • Buka proyek Unity Anda lalu buka Asset Store: (Window -> General -> AssetStore) atau tekan Ctrl+9
  • Cari "Photon Unity Networking Classic - Gratis" lalu klik hasil pertama atau klik di sini
  • Impor paket Photon setelah Pengunduhan selesai

  • Pada halaman pembuatan, untuk Photon Type pilih "Photon Realtime" dan untuk Name, ketikkan nama apa saja lalu klik "Create"

Seperti yang Anda lihat, Aplikasi defaultnya adalah paket Gratis. Anda dapat membaca lebih lanjut tentang Paket Harga di sini

  • Setelah Aplikasi dibuat, salin ID Aplikasi yang terletak di bawah nama Aplikasi

  • Kembali ke proyek Unity Anda lalu buka Window -> Photon Unity Networking -> PUN Wizard
  • Di PUN Wizard klik "Setup Project", paste App ID Anda lalu klik "Setup Project"
  • Jaringan Foton sekarang siap

Bagian 2: Membuat game multipemain

Sekarang mari beralih ke bagian di mana kita sebenarnya membuat game multipemain.

Cara penanganan multipemain di Photon adalah:

  • Pertama, kita terhubung ke Wilayah Foton (mis. AS Timur, Eropa, Asia, dll.) yang juga dikenal sebagai Lobi.
  • Setelah berada di Lobi, kita meminta semua Ruangan yang dibuat di wilayah tersebut, lalu kita dapat bergabung dengan salah satu Ruangan atau membuat Ruangan kita sendiri.
  • Setelah kami bergabung dengan ruangan, kami meminta daftar pemain yang terhubung ke ruangan dan membuat instance Player mereka, yang kemudian disinkronkan dengan instance lokal mereka melalui PhotonView.
  • Ketika seseorang meninggalkan Ruangan, instance mereka dihancurkan dan mereka dihapus dari Daftar Pemain.

1. Menyiapkan Lobi

Mari kita mulai dengan membuat MainMenu yang berisi logika Lobi (Menelusuri ruangan yang ada, membuat ruangan baru, dll.).

  • Buat Adegan baru dan beri nama "MainMenu"
  • Buat skrip C# baru dan beri nama GameLobby
  • Dalam adegan MainMenu buat GameObject baru. Sebut saja "_GameLobby" dan lampirkan skrip GameLobby ke dalamnya

Sekarang buka skrip GameLobby.

Pertama, mari buat semua variabel yang diperlukan:

    //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;

Hal berikutnya yang perlu kita lakukan adalah mengaktifkan Auto-Join Lobby dan Lobby Stats, ini akan memungkinkan kita menerima daftar kamar. Hal ini dilakukan dalam kekosongan Start().

Selain itu, kami mengaktifkan automaticSyncScene sehingga Scene disinkronkan secara otomatis setelah kami bergabung ke dalam Room.

Dan terakhir, kami memanggil PhotonNetwork.ConnectUsingSettings untuk terhubung.

    // 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);
        }
    }

Untuk mengetahui apakah koneksi ke Photon Cloud berhasil, kita harus mengimplementasikan 2 callback berikut: OnReceivedRoomListUpdate() dan OnFailedToConnectToPhoton(parameter objek).

    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();
    }

Berikutnya adalah bagian UI, tempat penjelajahan Ruangan dan pembuatan Ruangan dilakukan:

Lobi Jaringan Foton

Dan terakhir kami menerapkan 4 callback lainnya: OnPhotonCreateRoomFailed(), OnPhotonJoinRoomFailed(object[] cause), OnCreatedRoom() dan OnJoinedRoom().

Callback ini digunakan untuk menentukan apakah kita Bergabung/Membuat ruangan atau apakah ada masalah selama koneksi.

    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");
    }

Dan berikut skrip GameLobby.cs terakhir:

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. Membuat cetakan Player

Dalam game Multipemain, instance Player memiliki 2 sisi: Lokal dan Jarak Jauh.

Sebuah instance lokal dikontrol secara lokal (oleh kami).

Sebaliknya, instance jarak jauh adalah representasi lokal dari apa yang dilakukan pemain lain. Seharusnya tidak terpengaruh oleh masukan kita.

Untuk menentukan apakah instance tersebut Lokal atau Jarak Jauh, kami menggunakan komponen PhotonView.

PhotonView bertindak sebagai pembawa pesan yang menerima dan mengirimkan nilai yang perlu disinkronkan, misalnya posisi dan rotasi.

Jadi mari kita mulai dengan membuat instance pemain (Jika instance pemain Anda sudah siap, Anda dapat melewati langkah ini).

Dalam kasus saya, instance Player akan berupa Kubus sederhana yang dipindahkan dengan tombol W, dan S dan diputar dengan tombol A dan D.

Contoh Pemutar Jaringan Foton

Dan berikut ini skrip pengontrol sederhana:

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);
        }
    }
}

Langkah selanjutnya adalah menambahkan komponen PhotonView.

  • Tambahkan komponen PhotonView ke Instans Pemain
  • Buat skrip C# baru, beri nama PlayerNetworkSync, dan buka (skrip ini akan digunakan untuk berkomunikasi melalui PhotonView)

Hal pertama yang perlu kita lakukan adalah mengganti MonoBehaviour dengan Photon.MonoBehaviour. Langkah ini diperlukan agar dapat menggunakan variabel photonView yang di-cache alih-alih menggunakan GetComponent<PhotonView>().

public class PlayerNetworkSync : Photon.MonoBehaviour

Setelah itu, kita dapat melanjutkan untuk membuat semua variabel yang diperlukan:

    //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;

Kemudian di bagian kosong Start() kita periksa apakah pemutarnya Lokal atau Jarak Jauh dengan menggunakan 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);
            }
        }
    }

Sinkronisasi sebenarnya dilakukan melalui panggilan balik PhotonView: OnPhotonSerializeView(aliran PhotonStream, info PhotonMessageInfo):

    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();
        }
    }

Dalam hal ini, kami hanya mengirimkan Posisi dan Rotasi pemain, tetapi Anda dapat menggunakan contoh di atas untuk mengirimkan nilai apa pun yang perlu disinkronkan melalui jaringan, pada frekuensi tinggi.

Nilai yang diterima kemudian diterapkan dalam kekosongan 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);
        }
    }

Berikut skrip PlayerNetworkSync.cs terakhir:

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);
        }
    }
}
  • Tambahkan skrip PlayerNetworkSync.cs ke PlayerInstance dan tetapkan ke Komponen Pengamatan PhotonView.
  • Tetapkan PlayerCntroller.cs ke "Local Scripts" dan tetapkan GameObjects (yang ingin Anda nonaktifkan untuk pemain jarak jauh) ke "Local Objects"

  • Simpan PlayerInstance ke Prefab dan pindahkan ke folder bernama Resources (Jika tidak ada folder seperti itu, buatlah folder tersebut). Langkah ini diperlukan untuk dapat menelurkan Objek multipemain melalui Jaringan.

3. Membuat Level Game

GameLevel adalah Adegan yang dimuat setelah bergabung dengan Ruangan dan di situlah semua aksi terjadi.

  • Buat Scene baru dan beri nama "GameLevel" (Atau jika Anda ingin tetap menggunakan nama lain, pastikan untuk mengganti nama di baris ini PhotonNetwork.LoadLevel("GameLevel"); di GameLobby.cs).

Dalam kasus saya, saya akan menggunakan Adegan sederhana dengan Pesawat:

  • Sekarang buat skrip baru dan beri nama RoomController. Skrip ini akan menangani logika di dalam Ruangan (Seperti memunculkan pemain, menampilkan daftar pemain, dll.).

Mari kita mulai dengan mendefinisikan variabel yang diperlukan:

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

Untuk membuat instance prefab Player kami menggunakan 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);
    }

Dan UI sederhana dengan tombol "Leave Room" dan beberapa elemen tambahan seperti nama Ruangan dan daftar Pemain yang terhubung:

    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);
        }
    }

Dan terakhir, kita mengimplementasikan callback PhotonNetwork lain yang disebut OnLeftRoom() yang dipanggil ketika kita meninggalkan Ruangan:

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

Dan inilah skrip RoomController.cs terakhir:

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");
    }
}
  • Terakhir, buat GameObject baru di adegan GameLevel dan beri nama "_RoomController"
  • Lampirkan skrip RoomController ke Objek _RoomController
  • Tetapkan prefab PlayerInstance dan SpawnPoint Transform ke dalamnya lalu simpan Scene
  • Tambahkan MainMenu dan GameLevel ke Pengaturan Build.

4. Membuat tes Membangun

Sekarang saatnya membuat build dan mengujinya:

Sharp Coder Pemutar video

Semuanya berfungsi seperti yang diharapkan!

Bonusnya

RPC

Di Jaringan Foton, RPC adalah singkatan dari Remote Procedure Call, digunakan untuk memanggil fungsi pada klien Jarak Jauh yang berada di ruangan yang sama (Anda dapat membaca selengkapnya di sini).

RPC memiliki banyak kegunaan, misalnya Anda perlu mengirim pesan chat ke semua pemain di Room. Dengan RPC, hal ini mudah dilakukan.

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

Perhatikan [PunRPC] sebelum fungsinya. Atribut ini diperlukan jika Anda berencana memanggil fungsi melalui RPC.

Untuk memanggil fungsi yang ditandai sebagai RPC, Anda memerlukan PhotonView. Contoh panggilan:

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

Kiat pro: Jika skrip Anda adalah Photon.MonoBehaviour atau Photon.PunBehaviour Anda dapat menggunakan: this.photonView.RPC().

Properti Kustom

Di Jaringan Foton, Properti Kustom adalah Hashtable yang dapat ditetapkan ke Pemain atau Ruangan.

Ini berguna ketika Anda perlu mengatur data persisten yang tidak perlu sering diubah (mis. Nama Tim Pemain, Mode Permainan Kamar, dll.).

Pertama, Anda harus mendefinisikan Hashtable, yang dilakukan dengan menambahkan baris di bawah ini di awal skrip:

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

Contoh di bawah ini menyetel properti Room yang disebut "GameMode" dan "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"]);

Properti pemain diatur dengan cara yang sama:

        //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"]);

Untuk Menghapus properti tertentu cukup setel nilainya menjadi nol.

        //Remove property called "PlayerHP" from Player properties
        Hashtable setPlayerProperties = new Hashtable();
        setPlayerProperties.Add("PlayerHP", null);
        PhotonNetwork.player.SetCustomProperties(setPlayerProperties);
Artikel yang Disarankan
Membangun Game Jaringan Multipemain dalam Unity
Sinkronkan Rigidbodies Melalui Jaringan Menggunakan PUN 2
Buat Game Multiplayer di Unity menggunakan PUN 2
Kompresi Data Multi Pemain dan Manipulasi Bit
Tutorial Papan Peringkat Online Unity
Buat Game Mobil Multi Pemain dengan PUN 2
Kompensasi Lag PUN 2