PUN 2'yi Kullanarak Sert Cisimleri Ağ Üzerinden Senkronize Etme

PUN 2'te Nesneleri senkronize etmek basittir, peki ya Sert Cisimleri senkronize etmeye ne dersiniz?

Normal GameObject'lerin aksine, Rigidbody aynı zamanda Yerçekiminden (Kinematik değilse) ve diğer nesnelerden de etkilenir. Dolayısıyla, yalnızca nesnenin Dönüşümünü senkronize etmek yerine, velocity ve angularVelocity gibi birkaç ek parametreyi de senkronize etmemiz gerekir.

Bu yazıda, Odadaki her Oyuncu tarafından etkilenebilen ve Ağ üzerinden senkronize edilebilen etkileşimli Sert Cisimlerin nasıl yapılacağını göstereceğim.

Unity Bu eğitimde kullanılan sürüm: Unity 2018.3.0f2 (64-bit)

Bölüm 1: PUN 2'yi ve Çok Oyunculu Örneği Kurma

PUN 2'yi kullanarak çok oyunculu bir örneğin nasıl kurulacağına dair zaten bir eğitimimiz var, aşağıdaki bağlantıyı kontrol edin:

Unity 3D'te PUN 2'yi kullanarak çok oyunculu bir oyun yapın

Çok oyunculu bir proje oluşturmayı bitirdiğinizde devam edebilmemiz için tekrar gelin.

Alternatif olarak, kaynak projeyi buradan adresinden alarak zamandan tasarruf edebilirsiniz.

Bölüm 2: Etkileşimli Sert Cisimler Ekleme

Yukarıdaki eğitimi izlediyseniz artık 2 Sahneye sahip olursunuz "GameLobby" ve "GameLevel"

  • "GameLevel" Sahnesini açın ve birkaç Küp oluşturun (GameObject -> 3D Object -> Cube)

  • Her Küp'e bir Sert Cisim bileşeni ekleyin
  • Her Küp'e bir PhotonView bileşeni ekleyin

Şimdi Rigidbody'leri ağ üzerinden senkronize edecek yeni bir Script oluşturmamız gerekiyor.

  • Yeni bir Komut Dosyası oluşturun ve onu PUN2_RigidbodySync olarak adlandırın

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'i her iki Küp'e ekleyin ve ayrıca Photon View "Observed Components":'e atayın.

Ayrıca Multiplayer eğitimindeki PUN2_PlayerSync betiğinde de bazı değişiklikler yapmamız gerekiyor:

  • PUN2_PlayerSync.cs'yi açın
  • void Start()'ta, if(photonView.IsMine) içine şu kodu ekleyin:
            //Player is local
            gameObject.tag = "Player";
            //Add Rigidbody to make the player interact with rigidbody
            Rigidbody r = gameObject.AddComponent<Rigidbody>();
            r.isKinematic = true;

Şimdi void Start() şöyle görünmeli:

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

Bir Rigidbody bileşeni ekleyerek oynatıcı örneğinin diğer Rigidbody'lerle etkileşime girebilmesini sağlıyoruz ve etiketi "Player" olarak değiştirerek bunun bir Rigidbody ile çarpışan yerel bir örnek olup olmadığını tespit edebiliyoruz.

  • Her şey tamamlandıktan sonra GameLevel Sahnesini kaydedin.

Şimdi bir yapı oluşturalım ve test edelim!

Sharp Coder Video oynatıcı

Her şey beklendiği gibi çalışıyor, artık Rigidbody'ler hâlâ etkileşimliyken Ağ üzerinden senkronize edilebiliyor.

Önerilen Makaleler
PUN 2'yi kullanarak Unity'de Çok Oyunculu Bir Oyun Yapın
PUN 2 ile Çok Oyunculu Araba Oyunu Yapın
Photon Network (Klasik) Başlangıç ​​Kılavuzu
Unity'de Çok Oyunculu Ağ Bağlantılı Oyunlar Oluşturma
PUN 2 Gecikme Telafisi
Unity, PUN 2 Odalarına Çok Oyunculu Sohbet Ekliyor
Çok Oyunculu Veri Sıkıştırma ve Bit İşleme