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डी ऑब्जेक्ट -> क्यूब)
- प्रत्येक क्यूब में एक रिगिडबॉडी घटक जोड़ें
- प्रत्येक क्यूब में एक PhotonView घटक जोड़ें
अब हमें एक नई स्क्रिप्ट बनाने की ज़रूरत है जो नेटवर्क पर रिगिडबॉडीज़ को सिंक करेगी।
- एक नई स्क्रिप्ट बनाएं और इसे 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 से टकराया था।
- सब कुछ हो जाने के बाद गेमलेवल सीन को सेव करें।
आइए अब एक निर्माण करें और उसका परीक्षण करें!
सब कुछ अपेक्षा के अनुरूप काम करता है, अब रिगिडबॉडीज को इंटरैक्टेबल रहते हुए भी नेटवर्क पर सिंक किया जा सकता है।