Sinkronkan Rigidbodies Melalui Jaringan Menggunakan PUN 2
Menyinkronkan Objek di PUN 2 itu sederhana, tetapi bagaimana dengan menyinkronkan Rigidbodies?
Tidak seperti GameObject biasa, Rigidbody juga dipengaruhi oleh Gravitasi (jika bukan Kinematik) dan objek lainnya. Jadi, daripada menyinkronkan Transform objek saja, kita juga perlu menyinkronkan beberapa parameter tambahan, seperti velocity dan angularVelocity.
Dalam postingan kali ini, saya akan menunjukkan cara membuat Rigidbodies interaktif yang dapat dipengaruhi oleh setiap Pemain di Ruangan dan disinkronkan melalui Jaringan.
Unity versi yang digunakan dalam tutorial ini: Unity 2018.3.0f2 (64-bit)
Bagian 1: Menyiapkan PUN 2 dan Contoh Multiplayer
Kami sudah memiliki tutorial cara setting contoh multiplayer menggunakan PUN 2, cek link dibawah ini:
Buat game multipemain di Unity 3D menggunakan PUN 2
Kembalilah setelah Anda selesai menyiapkan proyek multipemain sehingga kami dapat melanjutkan.
Alternatifnya, Anda dapat menghemat waktu dengan mendapatkan proyek sumber dari di sini.
Bagian 2: Menambahkan Benda Kaku Interaktif
Jika Anda mengikuti tutorial di atas, Anda sekarang akan memiliki 2 Adegan "GameLobby" dan "GameLevel"
- Buka Scene "GameLevel" dan buat beberapa Kubus (GameObject -> 3D Object -> Cube)
- Tambahkan komponen Rigidbody ke setiap Kubus
- Tambahkan komponen PhotonView ke setiap Kubus
Sekarang kita perlu membuat Script baru yang akan menyinkronkan Rigidbody melalui jaringan.
- Buat Script baru dan beri nama 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);
}
}
}
}
- Lampirkan PUN2_RigidbodySync ke kedua Kubus dan tetapkan juga ke Tampilan Foton "Observed Components":
Kita juga perlu melakukan beberapa perubahan pada skrip PUN2_PlayerSync dari tutorial Multiplayer:
- Buka PUN2_PlayerSync.cs
- Di void Start(), di dalam if(photonView.IsMine) tambahkan kode ini:
//Player is local
gameObject.tag = "Player";
//Add Rigidbody to make the player interact with rigidbody
Rigidbody r = gameObject.AddComponent<Rigidbody>();
r.isKinematic = true;
Jadi sekarang void Start() akan terlihat seperti ini:
// 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);
}
}
}
Dengan menambahkan komponen Rigidbody kami memastikan bahwa instance pemain dapat berinteraksi dengan Rigidbodies lain dan dengan mengubah tag menjadi "Player" kami dapat mendeteksi apakah instance lokal yang bertabrakan dengan Rigidbody.
- Simpan Scene GameLevel setelah semuanya selesai.
Sekarang mari kita buat dan ujilah!
Semuanya berfungsi seperti yang diharapkan, sekarang Rigidbodies dapat disinkronkan melalui Jaringan sambil tetap dapat berinteraksi.