Photon Network (Klasik) Başlangıç ​​Kılavuzu

Photon Network, geliştiricilerin gerçek zamanlı çok oyunculu oyunlar oluşturmasına olanak tanıyan bir Unity hizmetidir.

Güçlü ve kullanımı kolay bir API sağlar, bu da onu acemi geliştiriciler için bile mükemmel kılar.

Bu yazıda gerekli dosyaları indirmeyi, Photon AppID'yi ayarlamayı ve basit bir çok oyunculu örnek programlamayı ele alacağız.

Bölüm 1: Foton Ağının Kurulumu

İlk adım Photon Network paketini Asset Store'den indirmektir. Çok oyunculu entegrasyon için gerekli tüm komut dosyalarını ve dosyaları içerir.

  • Unity projenizi açın, ardından Asset Store:'ye gidin (Pencere -> Genel -> AssetStore) veya Ctrl+9 tuşlarına basın
  • "Photon Unity Networking Classic - Free" ifadesini arayın ve ardından ilk sonuca tıklayın veya burayı tıklayın
  • İndirme tamamlandıktan sonra Photon paketini içe aktarın

  • Paket içe aktarıldıktan sonra bir Photon Uygulama Kimliği oluşturmanız gerekir; bu, web sitesinde yapılır: https://www.photonengine.com/
  • Yeni bir hesap oluşturun (veya mevcut hesabınıza giriş yapın)
  • Profil simgesine ve ardından "Your Applications"'e tıklayarak Uygulamalar sayfasına gidin veya şu bağlantıyı izleyin: https://dashboard.photonengine.com/en-US/PublicCloud
  • Uygulamalar sayfasında tıklayın "Create new app"

  • Oluşturma sayfasında, Foton Türü için "Photon Realtime"'ü seçin ve Ad için herhangi bir adı yazın ve ardından simgesine tıklayın. "Create"

Gördüğünüz gibi Uygulama varsayılan olarak Ücretsiz planı kullanıyor. Fiyatlandırma Planları hakkında daha fazla bilgiyi burada bulabilirsiniz

  • Uygulama oluşturulduktan sonra Uygulama adının altında bulunan Uygulama Kimliğini kopyalayın

  • Unity projenize geri dönün ve ardından Pencere -> Photon Unity Ağ İletişimi -> PUN Sihirbazı'na gidin
  • PUN Sihirbazı'nda "Setup Project"'a tıklayın, Uygulama Kimliğinizi yapıştırın ve ardından tıklayın "Setup Project"
  • Foton Ağı artık hazır

Bölüm 2: Çok oyunculu bir oyun oluşturma

Şimdi aslında çok oyunculu bir oyun yaratacağımız kısma geçelim.

Photon'da çok oyunculu modun işlenme şekli şöyledir:

  • Öncelikle Lobby olarak da bilinen Foton Bölgesine (örn. ABD Doğu, Avrupa, Asya vb.) bağlanıyoruz.
  • Lobiye girdikten sonra bölgede oluşturulan tüm Odaları talep ediyoruz, ardından Odalardan birine katılabilir veya kendi Odamızı oluşturabiliriz.
  • Odaya katıldıktan sonra, odaya bağlı oyuncuların bir listesini talep ediyoruz ve Player örneklerini başlatıyoruz; bunlar daha sonra PhotonView aracılığıyla yerel örnekleriyle senkronize ediliyor.
  • Birisi Odadan ayrıldığında örneği yok edilir ve Oyuncu Listesinden kaldırılır.

1. Lobi Kurmak

Lobi mantığını içerecek bir MainMenu oluşturarak başlayalım (Mevcut odalara göz atmak, yeni odalar oluşturmak vb.).

  • Yeni bir Sahne oluşturun ve onu çağırın "MainMenu"
  • yeni bir C# betiği oluşturun ve buna GameLobby adını verin
  • MainMenu sahnesinde yeni bir GameObject oluşturun. Bunu "_GameLobby" olarak adlandırın ve GameLobby komut dosyasını buna ekleyin

Şimdi GameLobby betiğini açın.

Öncelikle gerekli tüm değişkenleri oluşturalım:

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

Yapmamız gereken bir sonraki şey, Lobi ve Lobi İstatistiklerini Otomatik Katılmayı etkinleştirmek, bu oda listesini almamızı sağlayacaktır. Bu, void Start()'ta yapılır.

Ayrıca, Odaya katıldığımızda Sahnenin otomatik olarak senkronize edilmesi için otomatik olarak SyncScene'i etkinleştiriyoruz.

Ve son olarak bağlanmak için PhotonNetwork.ConnectUsingSettings'i çağırıyoruz.

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

Photon Cloud bağlantısının başarılı olup olmadığını bilmek için şu 2 geri aramayı uygulamamız gerekir: OnReceivedRoomListUpdate() ve OnFailedToConnectToPhoton(object parametreleri).

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

Sonraki, Odaya göz atma ve Oda oluşturma işlemlerinin yapıldığı kullanıcı arayüzü kısmıdır:

Foton Ağı lobisi

Ve son olarak 4 geri çağırma daha uyguluyoruz: OnPhotonCreateRoomFailed(), OnPhotonJoinRoomFailed(object[] Cause), OnCreatedRoom() ve OnJoinedRoom().

Bu geri aramalar, odaya katılıp katılmadığımızı/odayı oluşturup oluşturmadığımızı veya bağlantı sırasında herhangi bir sorun olup olmadığını belirlemek için kullanılır.

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

Ve işte son GameLobby.cs komut dosyası:

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. Oyuncu prefabrik oluşturma

Çok Oyunculu oyunlarda Oyuncu örneğinin 2 tarafı vardır: Yerel ve Uzak.

Yerel bir örnek yerel olarak (bizim tarafımızdan) kontrol edilir.

Uzak örnek ise diğer oyuncunun ne yaptığının yerel bir temsilidir. Bizim girdimizden etkilenmemelidir.

Örneğin Yerel mi Uzak mı olduğunu belirlemek için PhotonView bileşenini kullanırız.

PhotonView, konum ve dönüş gibi senkronize edilmesi gereken değerleri alan ve gönderen bir haberci görevi görür.

O halde oynatıcı örneğini oluşturarak başlayalım (Player örneğiniz zaten hazırsa bu adımı atlayabilirsiniz).

Benim durumumda Player örneği, W ve S tuşlarıyla hareket ettirilen ve A ve D tuşlarıyla döndürülen basit bir Küp olacaktır.

Photon Ağ Oynatıcı Örneği

Ve işte basit bir denetleyici betiği:

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

Bir sonraki adım bir PhotonView bileşeni eklemektir.

Yapmamız gereken ilk şey MonoBehaviour'u Photon.MonoBehaviour ile değiştirmek. Bu adım, GetComponent<PhotonView>() kullanmak yerine önbelleğe alınmış photonView değişkenini kullanabilmek için gereklidir.

public class PlayerNetworkSync : Photon.MonoBehaviour

Bundan sonra gerekli tüm değişkenleri oluşturmaya geçebiliriz:

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

Daha sonra void Start() alanında, photonView.isMine kullanarak oynatıcının Yerel mi yoksa Uzak mı olduğunu kontrol ederiz:

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

Gerçek senkronizasyon, PhotonView'ın geri araması yoluyla yapılır: 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();
        }
    }

Bu durumda, oynatıcıya yalnızca Konum ve Rotasyon göndeririz, ancak ağ üzerinden senkronize edilmesi gereken herhangi bir değeri yüksek frekansta göndermek için yukarıdaki örneği kullanabilirsiniz.

Alınan değerler daha sonra void Update() işlevine uygulanır:

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

İşte son PlayerNetworkSync.cs komut dosyası:

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);
        }
    }
}
  • PlayerNetworkSync.cs betiğini PlayerInstance'a ekleyin ve onu PhotonView Observed Components'a atayın.
  • PlayerCntroller.cs'yi "Local Scripts"'a atayın ve GameObjects'i (Uzak oynatıcılar için devre dışı bırakılmasını istediğiniz) "Local Objects"

  • PlayerInstance'ı Prefab'a kaydedin ve Kaynaklar adlı klasöre taşıyın (Böyle bir klasör yoksa bir tane oluşturun). Bu adım, Ağ üzerinden çok oyunculu Nesneler oluşturabilmek için gereklidir.

3. Oyun Seviyesi Oluşturma

GameLevel, Odaya katıldıktan sonra yüklenen bir Sahnedir ve tüm aksiyonun gerçekleştiği yerdir.

  • Yeni bir Sahne oluşturun ve onu "GameLevel" olarak adlandırın (Veya farklı bir ad tutmak istiyorsanız, adı GameLobby.cs'de PhotonNetwork.LoadLevel("GameLevel"); satırında değiştirdiğinizden emin olun).

Benim durumumda basit bir Düzlemli Sahne kullanacağım:

  • Şimdi yeni bir komut dosyası oluşturun ve buna RoomController adını verin. Bu script Odanın içindeki mantığı yönetecektir (Oyuncuları canlandırmak, oyuncu listesini göstermek vb. gibi).

Gerekli değişkenleri tanımlayarak başlayalım:

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

Player prefabrik örneğini oluşturmak için PhotonNetwork.Instantiate kullanıyoruz:

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

Ve "Leave Room" düğmesinin yanı sıra Oda adı ve bağlı Oyuncuların listesi gibi bazı ek öğeleri içeren basit bir kullanıcı arayüzü:

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

Ve son olarak, Odadan çıktığımızda çağrılan OnLeftRoom() adında başka bir PhotonNetwork geri çağrısı uyguluyoruz:

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

Ve işte son RoomController.cs betiği:

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");
    }
}
  • Son olarak GameLevel sahnesinde yeni bir GameObject oluşturun ve onu çağırın. "_RoomController"
  • RoomController komut dosyasını _RoomController Nesnesine ekleyin
  • PlayerInstance prefab'ını ve ona bir SpawnPoint Dönüşümü atayın ve Sahneyi kaydedin
  • Yapı Ayarlarına hem MainMenu hem de GameLevel'i ekleyin.

4. Test oluşturma

Şimdi bir yapı oluşturup test etme zamanı:

Sharp Coder Video oynatıcı

Her şey beklendiği gibi çalışıyor!

Bonus

RPC

Photon Ağında, RPC Uzaktan Yordam Çağrısı anlamına gelir, aynı odadaki Uzak istemcilerde bir işlevi çağırmak için kullanılır (Bu konuda daha fazla bilgi edinebilirsiniz burada).

RPC'lerin birçok kullanım alanı vardır; örneğin, Odadaki tüm oyunculara bir sohbet mesajı göndermeniz gerektiğini varsayalım. RPC'lerle bunu yapmak kolaydır.

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

İşlevden önce [PunRPC]'a dikkat edin. İşlevi RPC'ler aracılığıyla çağırmayı planlıyorsanız bu öznitelik gereklidir.

RPC olarak işaretlenen işlevleri çağırmak için bir PhotonView'a ihtiyacınız vardır. Örnek çağrı:

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

Profesyonel ipucu: Komut dosyanız Photon.MonoBehaviour veya Photon.PunBehaviour ise şunu kullanabilirsiniz: this.photonView.RPC().

Özel Özellikler

Photon Ağında Özel Özellikler, Oyuncuya veya Odaya atanabilen bir Hashtable'dır.

Bu, sık sık değiştirilmesi gerekmeyen kalıcı verileri (örn. Oyuncu Takımı adı, Oda Oyunu Modu vb.) ayarlamanız gerektiğinde kullanışlıdır.

Öncelikle, betiğin başına aşağıdaki satırı ekleyerek yapılan bir Hashtable tanımlamanız gerekir:

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

Aşağıdaki örnek, "GameMode" ve "AnotherProperty": olarak adlandırılan Oda özelliklerini ayarlar.

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

Oynatıcı özellikleri benzer şekilde ayarlanır:

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

Belirli bir özelliği kaldırmak için değerini null olarak ayarlamanız yeterlidir.

        //Remove property called "PlayerHP" from Player properties
        Hashtable setPlayerProperties = new Hashtable();
        setPlayerProperties.Add("PlayerHP", null);
        PhotonNetwork.player.SetCustomProperties(setPlayerProperties);
Önerilen Makaleler
PUN 2 ile Çok Oyunculu Araba Oyunu Yapın
Unity, PUN 2 Odalarına Çok Oyunculu Sohbet Ekliyor
PUN 2'yi Kullanarak Sert Cisimleri Ağ Üzerinden Senkronize Etme
PUN 2'yi kullanarak Unity'de Çok Oyunculu Bir Oyun Yapın
Unity'de Çok Oyunculu Ağ Bağlantılı Oyunlar Oluşturma
Çok Oyunculu Veri Sıkıştırma ve Bit İşleme
Unity Çevrimiçi Skor Tablosu Eğitimi