फोटॉन नेटवर्क (क्लासिक) शुरुआती गाइड

फोटॉन नेटवर्कUnity के लिए एक सेवा है जो डेवलपर्स को रीयल-टाइम मल्टीप्लेयर गेम बनाने की अनुमति देती है।

यह एक शक्तिशाली और उपयोग में आसान API प्रदान करता है जो इसे नौसिखिए डेवलपर्स के लिए भी सही बनाता है।

इस पोस्ट में, हम आवश्यक फ़ाइलों को डाउनलोड करना, फोटॉन ऐपआईडी सेट करना और एक सरल मल्टीप्लेयर उदाहरण प्रोग्रामिंग करना सीखेंगे।

भाग 1: फोटॉन नेटवर्क की स्थापना

पहला कदम Asset Store से फोटॉन नेटवर्क पैकेज डाउनलोड करना है। इसमें मल्टीप्लेयर एकीकरण के लिए सभी आवश्यक स्क्रिप्ट और फ़ाइलें शामिल हैं।

  • अपना Unity प्रोजेक्ट खोलें फिर Asset Store पर जाएं: (विंडो -> सामान्य -> ​​AssetStore) या Ctrl+9 दबाएं
  • "फ़ोटॉन Unity नेटवर्किंग क्लासिक - मुफ़्त" खोजें, फिर पहले परिणाम पर क्लिक करें या यहां क्लिक करें
  • डाउनलोड समाप्त होने के बाद फोटॉन पैकेज आयात करें

  • पैकेज आयात होने के बाद आपको एक फोटॉन ऐप आईडी बनानी होगी, यह उनकी वेबसाइट पर किया जाता है: https://www.photonengine.com/
  • एक नया खाता बनाएं (या अपने मौजूदा खाते में लॉगिन करें)
  • प्रोफ़ाइल आइकन पर क्लिक करके एप्लिकेशन पृष्ठ पर जाएं और फिर "Your Applications" या इस लिंक का अनुसरण करें: https://dashboard.photonengine.com/en-US/PublicCloud
  • एप्लिकेशन पृष्ठ पर क्लिक करें "Create new app"

  • निर्माण पृष्ठ पर, फोटॉन प्रकार के लिए "Photon Realtime" चुनें और नाम के लिए, कोई भी नाम टाइप करें और फिर क्लिक करें "Create"

जैसा कि आप देख सकते हैं, एप्लिकेशन निःशुल्क योजना पर डिफ़ॉल्ट है। आप मूल्य निर्धारण योजनाओं के बारे में अधिक जानकारी यहां पढ़ सकते हैं

  • एक बार एप्लिकेशन बन जाने के बाद, ऐप नाम के नीचे स्थित ऐप आईडी को कॉपी करें

  • अपने Unity प्रोजेक्ट पर वापस जाएँ फिर विंडो -> फोटॉन Unity नेटवर्किंग -> PUN विज़ार्ड पर जाएँ
  • PUN विज़ार्ड में "Setup Project" पर क्लिक करें, अपनी ऐप आईडी पेस्ट करें और फिर क्लिक करें "Setup Project"
  • फोटॉन नेटवर्क अब तैयार है

भाग 2: एक मल्टीप्लेयर गेम बनाना

अब आइए उस हिस्से पर चलते हैं जहां हम वास्तव में एक मल्टीप्लेयर गेम बनाते हैं।

फोटॉन में मल्टीप्लेयर को जिस तरह से संभाला जाता है वह है:

  • सबसे पहले, हम फोटॉन क्षेत्र (उदा. यूएसए पूर्व, यूरोप, एशिया, आदि) से जुड़ते हैं जिसे लॉबी के नाम से भी जाना जाता है।
  • एक बार लॉबी में, हम क्षेत्र में बनाए गए सभी कमरों का अनुरोध करते हैं, फिर हम या तो किसी एक कमरे में शामिल हो सकते हैं या अपना खुद का कमरा बना सकते हैं।
  • कमरे में शामिल होने के बाद हम कमरे से जुड़े खिलाड़ियों की एक सूची का अनुरोध करते हैं और उनके प्लेयर इंस्टेंस को इंस्टेंट करते हैं, जिसे बाद में फोटोनव्यू के माध्यम से उनके स्थानीय इंस्टेंस के साथ सिंक किया जाता है।
  • जब कोई कक्ष छोड़ता है, तो उसका उदाहरण नष्ट हो जाता है और उसे खिलाड़ी सूची से हटा दिया जाता है।

1. लॉबी की स्थापना

आइए एक मेनमेनू बनाकर शुरुआत करें जिसमें एक लॉबी लॉजिक होगा (मौजूदा कमरों को ब्राउज़ करना, नए कमरे बनाना आदि)।

  • एक नया दृश्य बनाएं और उसे कॉल करें "MainMenu"
  • एक नई C# स्क्रिप्ट बनाएं और इसे GameLobby नाम दें
  • मेनमेनू दृश्य में एक नया गेमऑब्जेक्ट बनाएं। इसे "_GameLobby" पर कॉल करें और इसमें गेमलॉबी स्क्रिप्ट संलग्न करें

अब गेमलॉबी स्क्रिप्ट खोलें।

सबसे पहले, आइए सभी आवश्यक वेरिएबल बनाएं:

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

अगली चीज़ जो हमें करने की ज़रूरत है वह है ऑटो-जॉइन लॉबी और लॉबी स्टैट्स को सक्षम करना, इससे हमें कमरे की सूची प्राप्त करने की अनुमति मिल जाएगी। यह शून्य प्रारंभ() में किया जाता है।

इसके अलावा, हम स्वचालित रूप से सिंक सीन को सक्षम करते हैं ताकि रूम में शामिल होने पर दृश्य स्वचालित रूप से सिंक हो जाए।

और अंत में, हम कनेक्ट करने के लिए PhotonNetwork.ConnectUsingSettings को कॉल करते हैं।

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

यह जानने के लिए कि फोटॉन क्लाउड से कनेक्शन सफल था या नहीं, हमें इन 2 कॉलबैक को लागू करना होगा: OnReceivedRoomListUpdate() और OnFairedToConnectToPhoton(ऑब्जेक्ट पैरामीटर)

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

अगला यूआई भाग है, जहां रूम ब्राउज़िंग और रूम निर्माण किया जाता है:

फोटॉन नेटवर्क लॉबी

और अंत में हम अन्य 4 कॉलबैक लागू करते हैं: OnPhotonCreateRoomFaired(), OnPhotonJoinRoomFaired(ऑब्जेक्ट[] कारण), OnCreatedRoom() और OnJoinedRoom().

इन कॉलबैक का उपयोग यह निर्धारित करने के लिए किया जाता है कि क्या हम रूम में शामिल हुए/बनाए गए या कनेक्शन के दौरान कोई समस्या थी या नहीं।

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

और यहाँ अंतिम GameLobby.cs स्क्रिप्ट है:

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. प्लेयर प्रीफ़ैब बनाना

मल्टीप्लेयर गेम में, प्लेयर इंस्टेंस के 2 पक्ष होते हैं: स्थानीय और रिमोट।

एक स्थानीय उदाहरण को स्थानीय रूप से (हमारे द्वारा) नियंत्रित किया जाता है।

दूसरी ओर, दूरस्थ उदाहरण, अन्य खिलाड़ी क्या कर रहा है इसका स्थानीय प्रतिनिधित्व है। यह हमारे इनपुट से अप्रभावित रहना चाहिए।

यह निर्धारित करने के लिए कि उदाहरण स्थानीय है या रिमोट, हम PhotonView घटक का उपयोग करते हैं।

फोटोनव्यू एक संदेशवाहक के रूप में कार्य करता है जो उन मानों को प्राप्त और भेजता है जिन्हें सिंक करने की आवश्यकता होती है, उदाहरण के लिए, स्थिति और रोटेशन।

तो आइए प्लेयर इंस्टेंस बनाकर शुरुआत करें (यदि आपके पास पहले से ही प्लेयर इंस्टेंस तैयार है, तो आप इस चरण को छोड़ सकते हैं)।

मेरे मामले में, प्लेयर इंस्टेंस एक साधारण क्यूब होगा जिसे W, और S कुंजियों के साथ घुमाया जाएगा और A और D कुंजियों के साथ घुमाया जाएगा।

फोटॉन नेटवर्क प्लेयर इंस्टेंस

और यहाँ एक सरल नियंत्रक स्क्रिप्ट है:

प्लेयरकंट्रोलर.सीएस

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

अगला चरण एक PhotonView घटक जोड़ना है।

  • प्लेयर इंस्टेंस में एक PhotonView घटक जोड़ें
  • एक नई C# स्क्रिप्ट बनाएं, इसे प्लेयरनेटवर्कसिंक कहें और इसे खोलें (इस स्क्रिप्ट का उपयोग फोटोनव्यू के माध्यम से संचार करने के लिए किया जाएगा)

पहली चीज़ जो हमें करने की ज़रूरत है वह है MonoBehaviour को Photon.MonoBehaviour से बदलना। GetComponent<PhotonView>() का उपयोग करने के बजाय कैश्ड फोटॉनव्यू वेरिएबल का उपयोग करने में सक्षम होने के लिए यह चरण आवश्यक है।

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[] localObjects;
    //Values that will be synced over network
    Vector3 latestPos;
    Quaternion latestRot;

फिर void Start() में हम फोटोनव्यू.आईएसमाइन का उपयोग करके जांचते हैं कि प्लेयर लोकल है या रिमोट:

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

वास्तविक सिंक्रनाइज़ेशन PhotonView के कॉलबैक के माध्यम से किया जाता है: OnPhotonSerializeView(PhotonStream स्ट्रीम, 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();
        }
    }

इस मामले में, हम केवल प्लेयर की स्थिति और रोटेशन भेजते हैं, लेकिन आप उच्च आवृत्ति पर नेटवर्क पर सिंक करने के लिए आवश्यक किसी भी मान को भेजने के लिए उपरोक्त उदाहरण का उपयोग कर सकते हैं।

प्राप्त मानों को फिर शून्य अद्यतन() में लागू किया जाता है:

    // 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 स्क्रिप्ट है:

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

  • प्लेयरइंस्टेंस को प्रीफैब में सहेजें और इसे रिसोर्सेज नामक फ़ोल्डर में ले जाएं (यदि ऐसा कोई फ़ोल्डर नहीं है, तो एक बनाएं)। नेटवर्क पर मल्टीप्लेयर ऑब्जेक्ट्स को उत्पन्न करने में सक्षम होने के लिए यह कदम आवश्यक है।

3. गेम लेवल बनाना

गेमलेवल एक दृश्य है जिसे रूम में शामिल होने के बाद लोड किया जाता है और यहीं पर सारी कार्रवाई होती है।

  • एक नया दृश्य बनाएं और इसे "GameLevel" कहें (या यदि आप एक अलग नाम रखना चाहते हैं, तो GameLobby.cs पर इस पंक्ति PhotonNetwork.LoadLevel('GameLevel'); में नाम बदलना सुनिश्चित करें।

मेरे मामले में, मैं एक विमान के साथ एक साधारण दृश्य का उपयोग करूंगा:

  • अब एक नई स्क्रिप्ट बनाएं और इसे रूमकंट्रोलर नाम दें। यह स्क्रिप्ट कमरे के अंदर तर्क को संभालेगी (जैसे खिलाड़ियों को तैयार करना, खिलाड़ियों की सूची दिखाना आदि)।

आइए आवश्यक चरों को परिभाषित करके प्रारंभ करें:

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

प्लेयर प्रीफ़ैब को इंस्टेंट करने के लिए हम 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);
    }

और "Leave Room" बटन के साथ एक सरल यूआई और कुछ अतिरिक्त तत्व जैसे कमरे का नाम और जुड़े हुए खिलाड़ियों की सूची:

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

और अंत में, हम OnLeftRoom() नामक एक और PhotonNetwork कॉलबैक कार्यान्वित करते हैं जिसे कक्ष छोड़ने पर कहा जाता है:

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

और यहाँ अंतिम RoomController.cs स्क्रिप्ट है:

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");
    }
}
  • अंत में, गेमलेवल दृश्य में एक नया गेमऑब्जेक्ट बनाएं और उसे कॉल करें "_RoomController"
  • _RoomController ऑब्जेक्ट में रूमकंट्रोलर स्क्रिप्ट संलग्न करें
  • इसमें प्लेयरइंस्टेंस प्रीफैब और स्पॉनप्वाइंट ट्रांसफॉर्म असाइन करें और फिर सीन को सेव करें
  • बिल्ड सेटिंग्स में मेनमेनू और गेमलेवल दोनों जोड़ें।

4. एक परीक्षण बिल्ड बनाना

अब इसका निर्माण करने और उसका परीक्षण करने का समय आ गया है:

Sharp Coder वीडियो प्लेयर

सब कुछ उम्मीद के मुताबिक काम करता है!

बक्शीश

आरपीसी

फोटॉन नेटवर्क में, RPC का अर्थ है रिमोट प्रोसीजर कॉल, इसका उपयोग रिमोट क्लाइंट पर एक फ़ंक्शन को कॉल करने के लिए किया जाता है जो एक ही कमरे में हैं (आप इसके बारे में अधिक पढ़ सकते हैं यहां)।

आरपीसी के कई उपयोग हैं, उदाहरण के लिए, मान लें कि आपको रूम के सभी खिलाड़ियों को एक चैट संदेश भेजने की आवश्यकता है। आरपीसी के साथ, यह करना आसान है।

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

फ़ंक्शन से पहले [PunRPC] पर ध्यान दें। यदि आप RPCs के माध्यम से फ़ंक्शन को कॉल करने की योजना बना रहे हैं तो यह विशेषता आवश्यक है।

RPC के रूप में चिह्नित फ़ंक्शन को कॉल करने के लिए, आपको एक PhotonView की आवश्यकता है। उदाहरण कॉल:

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

प्रो टिप: यदि आपकी स्क्रिप्ट Photon.MonoBehaviour या Photon.PunBehaviour है तो आप इसका उपयोग कर सकते हैं: this.photonView.RPC()।

कस्टम गुण

फोटॉन नेटवर्क में, कस्टम प्रॉपर्टीज़ एक हैशटेबल है जिसे प्लेयर या रूम को सौंपा जा सकता है।

यह तब उपयोगी होता है जब आपको लगातार डेटा सेट करने की आवश्यकता होती है जिसे बार-बार बदलने की आवश्यकता नहीं होती है (उदा. प्लेयर टीम का नाम, रूम गेम मोड, आदि)।

सबसे पहले, आपको एक हैशटेबल को परिभाषित करना होगा, जो स्क्रिप्ट की शुरुआत में नीचे दी गई पंक्ति जोड़कर किया जाता है:

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

नीचे दिया गया उदाहरण "GameMode" और "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"]);

प्लेयर गुण समान रूप से सेट किए गए हैं:

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

विशिष्ट संपत्ति को हटाने के लिए बस उसका मान शून्य पर सेट करें।

        //Remove property called "PlayerHP" from Player properties
        Hashtable setPlayerProperties = new Hashtable();
        setPlayerProperties.Add("PlayerHP", null);
        PhotonNetwork.player.SetCustomProperties(setPlayerProperties);
सुझाए गए लेख
PUN 2 का उपयोग करके नेटवर्क पर रिगिडबॉडीज़ को सिंक करें
यूनिटी में मल्टीप्लेयर नेटवर्क गेम्स का निर्माण
PUN 2 का उपयोग करके यूनिटी में एक मल्टीप्लेयर गेम बनाएं
PUN 2 के साथ एक मल्टीप्लेयर कार गेम बनाएं
PUN 2 लैग मुआवजा
मल्टीप्लेयर डेटा संपीड़न और बिट हेरफेर
एकता ऑनलाइन लीडरबोर्ड ट्यूटोरियल