PUN 2 का उपयोग करके नेटवर्क पर रिगिडबॉडीज़ को सिंक करें

PUN 2 में ऑब्जेक्ट को सिंक करना सरल है, लेकिन रिगिडबॉडी को सिंक करने के बारे में क्या?

नियमित गेमऑब्जेक्ट्स के विपरीत, Rigidbody ग्रेविटी (यदि किनेमेटिक नहीं) और अन्य वस्तुओं से भी प्रभावित होता है। इसलिए केवल ऑब्जेक्ट के ट्रांसफॉर्म को सिंक करने के बजाय, हमें कुछ अतिरिक्त पैरामीटर्स को भी सिंक करने की आवश्यकता है, जैसे velocity और angularVelocity

इस पोस्ट में, मैं दिखाऊंगा कि इंटरैक्टिव रिगिडबॉडी कैसे बनाई जाती है जो कमरे में प्रत्येक खिलाड़ी से प्रभावित हो सकती है और नेटवर्क पर सिंक हो सकती है।

Unity इस ट्यूटोरियल में प्रयुक्त संस्करण: Unity 2018.3.0f2 (64-बिट)

भाग 1: PUN 2 और मल्टीप्लेयर उदाहरण स्थापित करना

PUN 2 का उपयोग करके मल्टीप्लेयर उदाहरण कैसे सेट करें, इस पर हमारे पास पहले से ही एक ट्यूटोरियल है, नीचे दिए गए लिंक को देखें:

PUN 2 का उपयोग करके Unity 3D में एक मल्टीप्लेयर गेम बनाएं

मल्टीप्लेयर प्रोजेक्ट सेट अप करने के बाद वापस आएँ ताकि हम जारी रख सकें।

वैकल्पिक रूप से, आप यहां से स्रोत प्रोजेक्ट प्राप्त करके समय बचा सकते हैं।

भाग 2: इंटरएक्टिव रिगिडबॉडीज़ जोड़ना

यदि आपने उपरोक्त ट्यूटोरियल का अनुसरण किया है तो अब आपके पास 2 दृश्य "GameLobby" और होंगे "GameLevel"

  • "GameLevel" दृश्य खोलें और कुछ क्यूब बनाएं (गेमऑब्जेक्ट -> 3डी ऑब्जेक्ट -> क्यूब)

अब हमें एक नई स्क्रिप्ट बनाने की ज़रूरत है जो नेटवर्क पर रिगिडबॉडीज़ को सिंक करेगी।

  • एक नई स्क्रिप्ट बनाएं और इसे PUN2_RigidbodySync नाम दें

PUN2_RigidbodySync.cs

using UnityEngine;
using Photon.Pun;

public class PUN2_RigidbodySync : MonoBehaviourPun, IPunObservable
{

    Rigidbody r;

    Vector3 latestPos;
    Quaternion latestRot;
    Vector3 velocity;
    Vector3 angularVelocity;

    bool valuesReceived = false;

    // Start is called before the first frame update
    void Start()
    {
        r = GetComponent<Rigidbody>();
    }

    public 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);
            stream.SendNext(r.velocity);
            stream.SendNext(r.angularVelocity);
        }
        else
        {
            //Network player, receive data
            latestPos = (Vector3)stream.ReceiveNext();
            latestRot = (Quaternion)stream.ReceiveNext();
            velocity = (Vector3)stream.ReceiveNext();
            angularVelocity = (Vector3)stream.ReceiveNext();

            valuesReceived = true;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (!photonView.IsMine && valuesReceived)
        {
            //Update Object position and Rigidbody parameters
            transform.position = Vector3.Lerp(transform.position, latestPos, Time.deltaTime * 5);
            transform.rotation = Quaternion.Lerp(transform.rotation, latestRot, Time.deltaTime * 5);
            r.velocity = velocity;
            r.angularVelocity = angularVelocity;
        }
    }

    void OnCollisionEnter(Collision contact)
    {
        if (!photonView.IsMine)
        {
            Transform collisionObjectRoot = contact.transform.root;
            if (collisionObjectRoot.CompareTag("Player"))
            {
                //Transfer PhotonView of Rigidbody to our local player
                photonView.TransferOwnership(PhotonNetwork.LocalPlayer);
            }
        }
    }
}
  • दोनों क्यूब्स में PUN2_RigidbodySync संलग्न करें और इसे फोटॉन व्यू "Observed Components" पर भी असाइन करें:

हमें मल्टीप्लेयर ट्यूटोरियल से PUN2_PlayerSync स्क्रिप्ट में कुछ बदलाव करने की भी आवश्यकता है:

  • PUN2_PlayerSync.cs खोलें
  • शून्य प्रारंभ() में, if(photonView.IsMine) के अंदर यह कोड जोड़ें:
            //Player is local
            gameObject.tag = "Player";
            //Add Rigidbody to make the player interact with rigidbody
            Rigidbody r = gameObject.AddComponent<Rigidbody>();
            r.isKinematic = true;

तो अब void प्रारंभ() इस तरह दिखना चाहिए:

    // Use this for initialization
    void Start()
    {
        if (photonView.IsMine)
        {
            //Player is local
            gameObject.tag = "Player";
            //Add Rigidbody to make the player interact with rigidbody
            Rigidbody r = gameObject.AddComponent<Rigidbody>();
            r.isKinematic = true;
        }
        else
        {
            //Player is Remote, deactivate the scripts and object that should only be enabled for the local player
            for (int i = 0; i < localScripts.Length; i++)
            {
                localScripts[i].enabled = false;
            }
            for (int i = 0; i < localObjects.Length; i++)
            {
                localObjects[i].SetActive(false);
            }
        }
    }

Rigidbody घटक जोड़कर हम यह सुनिश्चित करते हैं कि प्लेयर इंस्टेंस अन्य Rigidbody के साथ इंटरैक्ट कर सकता है और टैग को "Player" में बदलकर हम यह पता लगा सकते हैं कि क्या यह एक स्थानीय इंस्टेंस था जो Rigidbody से टकराया था।

  • सब कुछ हो जाने के बाद गेमलेवल सीन को सेव करें।

आइए अब एक निर्माण करें और उसका परीक्षण करें!

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

सब कुछ अपेक्षा के अनुरूप काम करता है, अब रिगिडबॉडीज को इंटरैक्टेबल रहते हुए भी नेटवर्क पर सिंक किया जा सकता है।

लिंक
Unity 6