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

发布于:2023-01-01 ⋅ 阅读:(579) ⋅ 点赞:(0)

在这里插入图片描述


🟥 前言

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

  • 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
}





大家还有什么问题,欢迎在下方留言!


在这里插入图片描述
如果你有 技术的问题 项目开发

都可以加下方联系方式

和我聊一聊你的故事🧡

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到