PUN☀️七、网络同步:Object Synchronization
文章目錄
- 🟥 前言
- 🟧 同步設置
- 1?? 基礎信息
- 2?? Transform與Animator
- 3?? 代碼是否屬于當前用戶
- 4?? 當前是否為離線模式
- 5?? 消息的發送與數據同步
🟥 前言
首先我們要搞懂,我們要同步什么?
- Transform
- Animator
- 代碼是否屬于當前用戶(每個玩家控制的角色都有相同腳本,輸入控制角色的命令,要確定哪個角色屬于當前玩家,只執行那個角色的代碼,比如攝像頭控制代碼、角色運動控制代碼)
- 某玩家發送給其他玩家的消息(其他玩家減血、勝利等等)
Object Synchronization,即對象同步。Object Synchronization適合頻繁同步的屬性。
使用 PUN,我們可以很容易地使某些游戲對象“網絡感知”。
- PhotonView 組件,可實現對象位置、旋轉和其他值的遠程復制,完成同步。
- 一些腳本實現 OnPhotonSerializeView() 并成為PhotonView 的觀察組件。現在,這個腳本也可被網絡同步。
🟧 同步設置
1?? 基礎信息
該組件的信息同步,通過 PhotonView 組件完成。
Owner:物體的擁有者
-0Fixed:固定的
-0Takeover:可被接管的
-0Request:可被請求接管
ViewID:運行后顯示當前物體是擁有者的第幾個物體。最多是999。若超過999,則只是后三位
Observeoption:觀察設置,添加上同步組件后,該值默認是UnreliableOnChange(在每次改變時通過“不可靠”傳輸同步)
2?? Transform與Animator
ObservedComponents:同步組件。我們可以往里面添加該物體的Transform、Animator等,同步這些選項。
添加上這些屬性之后,會自動再添加屬性。
添加Transform會自動添加PhotoTransformView,勾選需要同步的選項即可
添加Animator會自動添加PhotonAnimatorView中:
- Disable為該屬性不同步
- Discrete為每秒同步10次
- Countinuous為該屬性每幀同步一次。但比較占用網速。
Animator中Trigger屬性要放在棧的最后,否則會可能沒被執行(不是很理解怎樣放在棧最后。。)
3?? 代碼是否屬于當前用戶
場景中有好幾個人控制的角色,都掛有某相同腳本,按下按鍵,如不判斷,這些角色不知道誰該執行當前用戶輸入的命令。因此要進行判斷:
//需繼承MonoBehaviourPun bool isMine = photonView.IsMine;攝像機設置
在網絡中,要先判斷攝像機是否屬于當前用戶,再決定是否跟隨。因此PlayerManager增加代碼如下。并取消CameraWork的FollowOnStart。
我們之前已經做完了發射激光的判斷。現在我們已實現了本機的操作,后面我們要將本機的狀態同步到互聯網上,同步其他電腦中自己人物的狀態。
void Start(){Skode_CameraWork _cameraWork = GetComponent<Skode_CameraWork>();if (_cameraWork != null && photonView.IsMine){_cameraWork.OnStartFollowing();}}4?? 當前是否為離線模式
false為離線。使用教程:傳送門
bool isConnected = PhotonNetwork.IsConnected;5?? 消息的發送與數據同步
目標:
- 我們要實現將本機自己控制的人物的狀態,同步到其他客戶端中。實現各個客戶端中自己人物動作一致
- 實現調用其他玩家的方法等操作
流程:
a、繼承并實現
要同步的腳本繼承接口 IPunObservable 并實現。
實現OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)方法,用它接收發送數據。
注:若不繼承不會報錯,但代碼不會運行。
b、書寫方式
腳本判斷自己是發送方還是接收方
寫法有規范,要怎樣發,怎樣接收。
c、Inspector面板配置
要把要同步的腳本(發送信息、接收信息的腳本)賦值進同步組件ObservedComponents
PlayerManager 最新代碼:
using UnityEngine; using Photon.Pun;public class PlayerManager : MonoBehaviourPunCallbacks, IPunObservable {#region Parameterspublic GameObject beams;public float Health = 1f;//當用戶開火時,為Truebool IsFiring;#endregion#region Mono CallBacksvoid Awake(){beams.SetActive(false);}void Start(){Skode_CameraWork _cameraWork = GetComponent<Skode_CameraWork>();if (_cameraWork != null && photonView.IsMine){_cameraWork.OnStartFollowing();}}void Update(){if (Health <= 0f)GameManager.ins.Skode_LeaveRoom();if (PhotonNetwork.IsConnected == true && photonView.IsMine)ProcessInputs();if (IsFiring != beams.activeSelf)beams.SetActive(IsFiring);}#endregion#region IPunObservable CallBackspublic void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){if (stream.IsWriting){// 我們擁有這個角色:把我們的數據發送給其他人stream.SendNext(IsFiring);stream.SendNext(Health);}else{// 網絡角色,接收數據IsFiring = (bool)stream.ReceiveNext();Health = (float)stream.ReceiveNext();}}#endregion#region Private Methodsvoid ProcessInputs(){//鼠標左鍵if (Input.GetButtonDown("Fire1"))IsFiring = true;if (Input.GetButtonUp("Fire1"))IsFiring = false;}void OnTriggerEnter(Collider other){if (!photonView.IsMine && !other.CompareTag("beam"))return;Health -= 0.1f;}void OnTriggerStay(Collider other){if (!photonView.IsMine && !other.CompareTag("beam"))return;//乘以增量時間,防止因為幀率FPS不同,扣血不同(舉例:不乘,每幀執行一次扣血,卡的人比流暢的人扣血少)Health -= 0.1f * Time.deltaTime;}#endregion }
大家還有什么問題,歡迎在下方留言!
如果你有 技術的問題 或 項目開發
都可以加下方聯系方式
和我聊一聊你的故事🧡
總結
以上是生活随笔為你收集整理的PUN☀️七、网络同步:Object Synchronization的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络聊天室项目介绍
- 下一篇: mysql中获取时间的年月日_MySQL