مزامنة الأجسام الصلبة عبر الشبكة باستخدام PUN 2
تعد مزامنة الكائنات في PUN 2 أمرًا بسيطًا، ولكن ماذا عن مزامنة الأجسام الصلبة؟
على عكس كائنات GameObjects العادية، يتأثر Rigidbody أيضًا بالجاذبية (إن لم يكن بالحركية) والكائنات الأخرى أيضًا. لذلك بدلاً من مزامنة تحويل الكائن فقط، نحتاج أيضًا إلى مزامنة بعض المعلمات الإضافية، مثل velocity و angularVelocity.
في هذا المنشور، سأوضح كيفية إنشاء أجسام صلبة تفاعلية يمكن أن تتأثر بكل لاعب في الغرفة وتتم مزامنتها عبر الشبكة.
Unity الإصدار المستخدم في هذا البرنامج التعليمي: Unity 2018.3.0f2 (64 بت)
الجزء 1: إعداد PUN 2 ومثال متعدد اللاعبين
لدينا بالفعل برنامج تعليمي حول كيفية إعداد مثال متعدد اللاعبين باستخدام PUN 2، تحقق من الرابط أدناه:
أنشئ لعبة متعددة اللاعبين في Unity 3D باستخدام PUN 2
عد بمجرد الانتهاء من إعداد مشروع متعدد اللاعبين حتى نتمكن من المتابعة.
وبدلاً من ذلك، يمكنك توفير الوقت عن طريق الحصول على المشروع المصدر من هنا.
الجزء 2: إضافة الأجسام الصلبة التفاعلية
إذا اتبعت البرنامج التعليمي أعلاه، فسيكون لديك الآن مشهدان "GameLobby" و "GameLevel"
- افتح المشهد "GameLevel" وقم بإنشاء مكعبين (GameObject -> 3D Object -> Cube)
- أضف مكون الجسم الصلب إلى كل مكعب
- أضف مكون PhotonView إلى كل مكعب
نحن الآن بحاجة إلى إنشاء برنامج نصي جديد يقوم بمزامنة Rigidbodies عبر الشبكة.
- قم بإنشاء برنامج نصي جديد وأطلق عليه اسم 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 بكلا المكعبين وقم أيضًا بتعيينه إلى Photon View "Observed Components":
نحتاج أيضًا إلى إجراء بعض التغييرات على البرنامج النصي PUN2_PlayerSync من البرنامج التعليمي المتعدد اللاعبين:
- افتح PUN2_PlayerSync.cs
- في الفراغ 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;
لذا الآن يجب أن يبدو الفراغ Start() كما يلي:
// 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، نتأكد من أن مثيل اللاعب يمكن أن يتفاعل مع Rigidbodys الأخرى وعن طريق تغيير العلامة إلى "Player" يمكننا اكتشاف ما إذا كان مثيلًا محليًا اصطدم بجسم Rigidbody.
- احفظ مشهد GameLevel بعد الانتهاء من كل شيء.
الآن دعونا نبني ونختبره!
كل شيء يعمل كما هو متوقع، الآن يمكن مزامنة Rigidbodies عبر الشبكة مع الاستمرار في التفاعل.