• 看了些文章,大牛对同问题的解决方案
  • 传送门:Fast-Paced Multiplayer

文中大体的思路:

  1. A玩家 移动时,本机自行移动,并发送移动指令给服务端,假设移动是成功的,服务端同步其他客户端 B玩家,B玩家 中用一个队列 Queue 来装服务端来的移动指令,然后客户端在updata中做插值 (lerp ) 处理,这样 A玩家 在 B玩家客户端中移动起来就比较平滑

  2. 如果 A玩家 移动很频繁,B玩家 中的 指令队列 Queue 会堆积的很大,这里可以做个优化,就是当 Queuesize 超过某个临界值 (threshold)时,加快插值(lerp)的速率

  3. A玩家 移动时,本机自行移动 并保留一份此次移动的 副本 (copy)到一个 队列 中,并发送移动指令给服务端,如果服务端判定移动是失败的(比如穿墙之类的),则服务端下发指令给 A玩家 修复此次移动的位置,然后 队列 中移除此次移动的副本

  4. 关于攻击时的同步,客户端A 中自行播放攻击动作并上行给服务的此次攻击的指令,服务端同步其他 客户端B 播放攻击动作,同时同步给所有客户端(客户端A和B)扣血指令,为防止客户端作弊必须有服务端运行计算实际扣血量。


下面是部分关于位置同步的代码

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Collections.Generic;/// <summary>
/// 可以通过
/// 1. 减少发包率(意思就是 增大 sendInterval 发包间隔)
/// 2. 增大 closeEnough 距离
/// 3. 增大 normalLerpRate、fasterLerpRate 插值速率
/// </summary>[NetworkSettings(channel = 0, sendInterval = 0.1f)]
public class SmoothMove : NetworkBehaviour
{[SyncVar(hook = "SyncPostionsValues")]private Vector3 syncPos; //同步变量[SerializeField]Transform myTransform; //SerializeField用于inspector中显示非public变量private float lerpRate;private float normalLerpRate = 16.0f;private float fasterLerpRate = 27.0f;private Vector3 lastPos;private float threshold = 0.5f;private List<Vector3> syncPosList = new List<Vector3>();[SerializeField]private bool useHistoriicalLerping = false; //是否启用平滑插值的开关,直接在 inspector 中设置private float closeEnough = 0.11f;public void Start(){lerpRate = normalLerpRate;}public void Update(){LerpPosition(); //因为方法利用了Time.deltaTime,所以只能在 Updata中调用}public void FixedUpdate() //1. server 和 client 都执行FixedUpdate{TransmitPosition(); //2. 因为是 ClientCallback,所以只有客户端调用}void LerpPosition(){if (!isLocalPlayer) //5. 只有非本机玩家才进行插值移动到最新的 syncPos 位置{if (useHistoriicalLerping) //更加平滑{HistoryLerping();}else{OrdinaryLerping();}}}[Command]void CmdProvidePositionToServer(Vector3 pos){syncPos = pos; //4. 服务端收到信息同步给所有客户端的该对象的syncPos变量}[Client]void TransmitPosition(){if (isLocalPlayer && Vector3.Distance(myTransform.position, lastPos) > threshold) //3. 只用本机玩家才提交位置信息到server上{CmdProvidePositionToServer(myTransform.position);}}[Client]public void SyncPostionsValues(Vector3 lastPos){syncPos = lastPos;syncPosList.Add(syncPos); //将所有服务端同步过来的 pos 全都保存在队列中}void OrdinaryLerping() //普通插值,有卡顿现象{myTransform.position = Vector3.Lerp(myTransform.position, syncPos, Time.deltaTime * lerpRate);}void HistoryLerping() //平滑插值{if (syncPosList.Count > 0){//取出队列中的第一个设为插值的目标myTransform.position = Vector3.Lerp(myTransform.position, syncPosList[0], Time.deltaTime * lerpRate);//位置足够接近,从队列中移除第一个,紧接着就是第二个if (Vector3.Distance(myTransform.position, syncPosList[0]) < closeEnough){syncPosList.RemoveAt(0);}//如果同步队列过大,加快插值速率,使其更快到达目标点if (syncPosList.Count > 10){lerpRate = fasterLerpRate;}else{lerpRate = normalLerpRate;}Debug.LogFormat("--- syncPosList, count:{0}", syncPosList.Count);}}
}

unity-unet-多人在线同步问题解决方案相关推荐

  1. Zotero+OneDrive多平台在线同步完美解决方案(一):安装配置、云端同步文献数据

    1 下载安装 Zotero下载官网:软件下载界面 微软用户直接点击"Download",其他系统用户选择对应的安装包下载就可以 用什么浏览器打开就会显示对应的Zotero Conn ...

  2. Unity Unet(四)多人在线游戏框架

    准备设置 打开项目后,进入Window/Services视图. 创建或登录项目ID进入下面面板. 选择Multiplayer进入 选择GoToDashboard进入网页(登录Unity账号) 选择下方 ...

  3. BigWorld Pty. Ltd.是一家全球领先的大型多人在线游戏(MMOG)开发解决方案供应商...

    BigWorld Pty. Ltd.是一家全球领先的大型多人在线游戏(MMOG)开发解决方案供应商.其开发套件为网络游戏提供了一整套解决方案,可大幅度提高游戏产品质量,并使用户大大降低游戏开发成本,从 ...

  4. 实时多人在线游戏研究(同步和延迟)

    本文讨论实时多人在线游戏的服务器和客户端技术. 实时多人在线游戏主要包括2类,FPS(quake系列,UT系列,CF等),ACT(DNF,龙之谷这类) 其共同特点是需要用户操作尽快的得到体现.并且所有 ...

  5. Unity联网之使用Socket简单实现多人在线聊天室(一)

    「前言」 之前在一直在写lua联网等一些知识,虽然lua重要,但C#联网也必不可少是吧.所以呢,本篇博客就主要介绍如何使用Unity和C#在实现多人在线聊天室. 服务器 客户端工作原理:(通过消息类型 ...

  6. photon多人在线_Photon Cloud网络多人游戏开发简介

    photon多人在线 Exit Games is a well-known provider of high-performance network multiplayer server and ho ...

  7. 多人在线游戏技术难点分析

    本文主要聚焦于多人在线游戏的三个技术难点: 1.通信架构的选择 2.服务器的承载能力 3.玩家体验 通信架构的选择 同步方式和异步方式 同步: 同步简单粗暴,数据稳定性高,但需要收集到所有玩家数据后才 ...

  8. 用Unity和C#创建在线多人游戏学习教程

    MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:58节课(6h 41m) |大小解压后:6.1 GB ...

  9. Unity3d多人在线教程

    [转载]Unity3d多人在线教程 (2013-02-25 16:02:49) 转载▼ 标签: 转载   原文地址:Unity3d多人在线教程作者:lsy0031 Unity 多个玩家开发教程 Uni ...

最新文章

  1. TF-IDF与余弦相似性的应用(一):自动提取关键词 - 阮一峰的网络日志
  2. v-for遍历数组 || v-for遍历对象
  3. 业务服务管理究竟为何可望而不可及
  4. Android Kotlin Flow 如何使用callbackflow
  5. centos 6.5 rpm mysql_Linux平台(CentOS 6.5) RPM包方式安装 Mysql 5.7
  6. ZoomBlur 聚焦模糊效果Shader(URP)
  7. LeetCode 1653. 使字符串平衡的最少删除次数(DP)
  8. Visual C++学习总结——进程或线程与指定CPU绑定
  9. 【数据结构笔记44】线性探测的散列表的逆问题(拓扑排序的方法)
  10. 神奇网盘搜索 只搜网盘不搜其它 一键搜索所有网盘资源
  11. 如何用大数据做行为预测的?
  12. SSH连接越狱iPhone
  13. 【RTX操作系统教程】第4章 RTX操作系统介绍
  14. 【推荐+转摘】如何又快又好的做出一份优质PPT
  15. (一)性能测试(压力测试、负载测试)、
  16. 从零开始学python的第18天
  17. c语言初学者常见错误归纳,C语言中常见错误分析.doc
  18. java 随机生成头像,javascript 随机展示头像实现代码
  19. 997. 找到小镇的法官
  20. python银行小项目

热门文章

  1. 电信说的几兆带宽和自己看到的下载/上传速度有什么关系
  2. 论文阅读笔记【1】:在线凸优化算法Greedy Projection
  3. 人品差的人,开口闭口都是这些话,一定不要深交!
  4. 计划任务,账户密钥集不存在 错误是: 0x80090016
  5. 行业第一,规模百亿,这家量化基金是怎么赚钱的?
  6. Node.js 字符串转换为数字型
  7. java大学教程习题答案_Java程序设计大学教程:习题解答与课程设计
  8. 什么是Mesh网络结构?
  9. 超级S32750双相不锈钢
  10. 制作一个移动Ubuntu系统,可以做到即插即用(U盘系统,非启动盘)