unity-unet-多人在线同步问题解决方案
- 看了些文章,大牛对同问题的解决方案
- 传送门:Fast-Paced Multiplayer
文中大体的思路:
A玩家 移动时,本机自行移动,并发送移动指令给服务端,假设移动是成功的,服务端同步其他客户端 B玩家,B玩家 中用一个队列 Queue 来装服务端来的移动指令,然后客户端在updata中做插值 (lerp ) 处理,这样 A玩家 在 B玩家客户端中移动起来就比较平滑
如果 A玩家 移动很频繁,B玩家 中的 指令队列 Queue 会堆积的很大,这里可以做个优化,就是当 Queue 的 size 超过某个临界值 (threshold)时,加快插值(lerp)的速率
A玩家 移动时,本机自行移动 并保留一份此次移动的 副本 (copy)到一个 队列 中,并发送移动指令给服务端,如果服务端判定移动是失败的(比如穿墙之类的),则服务端下发指令给 A玩家 修复此次移动的位置,然后 队列 中移除此次移动的副本
关于攻击时的同步,客户端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-多人在线同步问题解决方案相关推荐
- Zotero+OneDrive多平台在线同步完美解决方案(一):安装配置、云端同步文献数据
1 下载安装 Zotero下载官网:软件下载界面 微软用户直接点击"Download",其他系统用户选择对应的安装包下载就可以 用什么浏览器打开就会显示对应的Zotero Conn ...
- Unity Unet(四)多人在线游戏框架
准备设置 打开项目后,进入Window/Services视图. 创建或登录项目ID进入下面面板. 选择Multiplayer进入 选择GoToDashboard进入网页(登录Unity账号) 选择下方 ...
- BigWorld Pty. Ltd.是一家全球领先的大型多人在线游戏(MMOG)开发解决方案供应商...
BigWorld Pty. Ltd.是一家全球领先的大型多人在线游戏(MMOG)开发解决方案供应商.其开发套件为网络游戏提供了一整套解决方案,可大幅度提高游戏产品质量,并使用户大大降低游戏开发成本,从 ...
- 实时多人在线游戏研究(同步和延迟)
本文讨论实时多人在线游戏的服务器和客户端技术. 实时多人在线游戏主要包括2类,FPS(quake系列,UT系列,CF等),ACT(DNF,龙之谷这类) 其共同特点是需要用户操作尽快的得到体现.并且所有 ...
- Unity联网之使用Socket简单实现多人在线聊天室(一)
「前言」 之前在一直在写lua联网等一些知识,虽然lua重要,但C#联网也必不可少是吧.所以呢,本篇博客就主要介绍如何使用Unity和C#在实现多人在线聊天室. 服务器 客户端工作原理:(通过消息类型 ...
- photon多人在线_Photon Cloud网络多人游戏开发简介
photon多人在线 Exit Games is a well-known provider of high-performance network multiplayer server and ho ...
- 多人在线游戏技术难点分析
本文主要聚焦于多人在线游戏的三个技术难点: 1.通信架构的选择 2.服务器的承载能力 3.玩家体验 通信架构的选择 同步方式和异步方式 同步: 同步简单粗暴,数据稳定性高,但需要收集到所有玩家数据后才 ...
- 用Unity和C#创建在线多人游戏学习教程
MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:58节课(6h 41m) |大小解压后:6.1 GB ...
- Unity3d多人在线教程
[转载]Unity3d多人在线教程 (2013-02-25 16:02:49) 转载▼ 标签: 转载 原文地址:Unity3d多人在线教程作者:lsy0031 Unity 多个玩家开发教程 Uni ...
最新文章
- TF-IDF与余弦相似性的应用(一):自动提取关键词 - 阮一峰的网络日志
- v-for遍历数组 || v-for遍历对象
- 业务服务管理究竟为何可望而不可及
- Android Kotlin Flow 如何使用callbackflow
- centos 6.5 rpm mysql_Linux平台(CentOS 6.5) RPM包方式安装 Mysql 5.7
- ZoomBlur 聚焦模糊效果Shader(URP)
- LeetCode 1653. 使字符串平衡的最少删除次数(DP)
- Visual C++学习总结——进程或线程与指定CPU绑定
- 【数据结构笔记44】线性探测的散列表的逆问题(拓扑排序的方法)
- 神奇网盘搜索 只搜网盘不搜其它 一键搜索所有网盘资源
- 如何用大数据做行为预测的?
- SSH连接越狱iPhone
- 【RTX操作系统教程】第4章 RTX操作系统介绍
- 【推荐+转摘】如何又快又好的做出一份优质PPT
- (一)性能测试(压力测试、负载测试)、
- 从零开始学python的第18天
- c语言初学者常见错误归纳,C语言中常见错误分析.doc
- java 随机生成头像,javascript 随机展示头像实现代码
- 997. 找到小镇的法官
- python银行小项目