PUN☀️七、网络同步:Object Synchronization

简介: PUN☀️七、网络同步:Object Synchronization

🟥 前言

首先我们要搞懂,我们要同步什么?

  • 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 Parameters
 
    public GameObject beams;
 
    public float Health = 1f;
 
    //当用户开火时,为True
    bool IsFiring;
 
    #endregion
 
 
    #region Mono CallBacks
 
    void 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 CallBacks
 
    public 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 Methods
 
    void 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
}


相关文章
|
4月前
|
存储 网络协议 Java
深入理解Linux网络——内核与用户进程协作之同步阻塞方案(BIO)
在上一部分中讲述了网络包是如何从网卡送到协议栈的(详见深入理解Linux网络——内核是如何接收到网络包的),接下来内核还有一项重要的工作,就是在协议栈接收处理完输入包后要通知到用户进程,如何用户进程接收到并处理这些数据。
PHP:guzzlehttp/guzzle发送同步和异步网络请求
PHP:guzzlehttp/guzzle发送同步和异步网络请求
700 0
|
1月前
|
缓存
PUN☀️八、拓展网络同步:RPCs 和 Properties
PUN☀️八、拓展网络同步:RPCs 和 Properties
|
1月前
|
存储 缓存 定位技术
如果遇到网络延迟问题,有哪些方法可以快速解决以保证视频源同步?
如果遇到网络延迟问题,有哪些方法可以快速解决以保证视频源同步?
|
20天前
|
UED 存储 数据管理
深度解析 Uno Platform 离线状态处理技巧:从网络检测到本地存储同步,全方位提升跨平台应用在无网环境下的用户体验与数据管理策略
【8月更文挑战第31天】处理离线状态下的用户体验是现代应用开发的关键。本文通过在线笔记应用案例,介绍如何使用 Uno Platform 优雅地应对离线状态。首先,利用 `NetworkInformation` 类检测网络状态;其次,使用 SQLite 实现离线存储;然后,在网络恢复时同步数据;最后,通过 UI 反馈提升用户体验。
34 0
|
2月前
|
安全 NoSQL Java
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R
|
4月前
|
网络协议 算法 开发者
如何实现网络同步?
【5月更文挑战第3天】如何实现网络同步?
82 9
|
3月前
计算机网络——物理层-传输方式(串行传输、并行传输,同步传输、异步传输,单工、半双工和全双工通信)
计算机网络——物理层-传输方式(串行传输、并行传输,同步传输、异步传输,单工、半双工和全双工通信)
96 0
|
4月前
|
网络协议
LabVIEW 通过网络同步多台计算机系统时间的方法与例程
LabVIEW 通过网络同步多台计算机系统时间的方法与例程
63 1
|
4月前
|
机器学习/深度学习 存储 安全
云端防御战线:云计算与网络安全的同步演进
【5月更文挑战第23天】 随着数字化转型的深入,云计算已成为现代企业架构的核心。然而,云服务的广泛应用也带来了前所未有的安全挑战。本文探讨了在动态和复杂的云环境中,如何实现网络和信息安全的同步提升。我们将详细分析云服务模式中的安全漏洞、网络攻击趋势以及应对策略,并展示最新的技术进展和最佳实践,以期为构建更加安全的云计算环境提供参考。