Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d 3d多人游戏中的FPS差异_Unity3d_3d_Socket.io_Frame Rate_Multiplayer - Fatal编程技术网

Unity3d 3d多人游戏中的FPS差异

Unity3d 3d多人游戏中的FPS差异,unity3d,3d,socket.io,frame-rate,multiplayer,Unity3d,3d,Socket.io,Frame Rate,Multiplayer,我正在用Unity开发一款3d手机游戏,现在我需要编写多人游戏部分。我用node.js/socket.io编写了所有的配对等,但我在游戏中遇到了一个问题。问题是,;每当用户移动时,他都会将自己的位置传递给其他用户。但是,尽管服务器功能非常强大(4GHz的cpu,16GB的ram),但用户并不像在单机上那样移动(我指的是AI移动)。它们似乎滑了几帧,这使得它们的移动不像我预期的那么平稳。我对可能导致这种情况的原因有一些想法,比如FPS差异。因为其中一个用户的发射速度可能比其他用户慢,因为他们之间的

我正在用Unity开发一款3d手机游戏,现在我需要编写多人游戏部分。我用node.js/socket.io编写了所有的配对等,但我在游戏中遇到了一个问题。问题是,;每当用户移动时,他都会将自己的位置传递给其他用户。但是,尽管服务器功能非常强大(4GHz的cpu,16GB的ram),但用户并不像在单机上那样移动(我指的是AI移动)。它们似乎滑了几帧,这使得它们的移动不像我预期的那么平稳。我对可能导致这种情况的原因有一些想法,比如FPS差异。因为其中一个用户的发射速度可能比其他用户慢,因为他们之间的FPS差异。有什么办法可以解决这个问题吗?

这取决于客户机/服务器之间的数据传输方式。
(这里我假设您只使用Unity的网络,而不是框架)

永远不要直接将接收方客户端上的新位置设置为

transform.position = X.Yf;
但是,由于您已经注意到了滞后/时间因素,因此需要进行一些插值

transform.position = Vector3.Lerp(actualPosition, receivedPosition, Time.deltaTime * interpolationRate);
我不太喜欢Unity的NetworkTransform,因为我没能让它顺利运行。所以我写了自己的同步脚本(当然,我经常在谷歌上搜索;)

我在这里仅为该职位提供一个示例。您应该能够调整它,然后自己编写旋转部分。它可能并不完美,但这就是我使用它的方式(到目前为止相当满意)

使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine。联网;
公共类CustomNetworkTransform:网络行为
{
/*如果我们不是本地玩家,我们将保存在这里
*我们实际移动到的最后接收位置。
*(见下文传输部分)*/
私有向量3_lastReceivedPosition=Vector3.0;
/*#############################################*/
/*接收部分*/
/*插值率。你可能需要调整一下
*但到目前为止,15似乎是一个不错的值*/
私人浮动_插值率=15.0f;
私有void更新()
{
/*我在这里使用了hasAuthority而不是isLocalPlayer
*因此,它与主机客户端一起工作
*安装程序以及客户端服务器客户端。
*/
如果(有权)返回;
接收数据();
}
私有void ReceiveData()
{
插值位置(_lastReceivedPosition,Time.deltaTime*_插值率);
}
专用空心插值位置(矢量3接收位置,浮动系数)
{
transform.position=Vector3.Lerp(transform.position,receivedPosition,factor);
}
/*接收部分已经完成了,也许已经完成了
*适合你的需要。在这里我添加了我传输信息的方式。也许这有助于你更好地理解Unity中网络的工作方式。
*/
/*#############################################*/
/*传输部分*/
/*为了节省一点带宽,我们将其用作treshold
*如果您吹口哨,也可以将其设置为0*/
[工具提示(“同步位置的准确性”)]
[序列化字段]
专用浮子位置精度=0.05f;
/*每x秒进行一次强制传输
*如果什么都没有改变*/
[序列化字段]
私人浮动_强制同步输出=2.0f;
/*强制传输计数器
*我在开始时将其设置为0以获得一个瞬间
*连接时同步*/
专用浮点_超时=0;
/*我们将把实际位置与这个位置进行比较
*同步,如果距离大于_位置精度*/
私有向量3 _lastTransmittedPosition=向量3.0;
私有void FixedUpdate()
{
/*这里我再次使用hasAuthority而不是
*IsLocalLayer,因此它可以在两种连接设计中工作*/
如果(!hasAuthority)返回;
传输更改数据();
_timeout-=Time.deltaTime;
如果(_timeout>0)返回;
传输数据();
_超时=_forcedSyncTimeout;
}
/*这是强制传输
*它不检查更改*/
私有无效传输数据()
{
TransmitPositionToServer(transform.position)
}
/*这是检查的正常传输
*如果在传输之前更改足够大*/
私有无效传输更改数据()
{
if(矢量3.距离(变换.位置,\上次传输位置)>位置精度)
{
TransmitPositionToServer(transform.position);
_lastTransmittedPosition=transform.position;
}
}
/*注意:对于传输,我不使用SyncVar
*而是一个三步同步:
* 
*1.客户端将数据传输到服务器
*2.服务器向所有客户端传输数据
*3.所有其他客户接收并插入位置
*
*我觉得这样做更舒服
*更多的自由度和更好的调试选项。
* 
*这也将在服务器上执行所有插值
*因此,它可以用于观察*/
//第一步。
/*
*仅在客户端上执行
*/
[客户]
私有void TransmitPositionToServer(矢量3值)
{
CmdPushPositionToServer(值);
}
//第二步。
/*
*从客户端开票,但仅在服务器上执行
*/
[命令]
私有void CmdPushPositionToServer(矢量3值)
{
_lastReceivedPosition=值;
RPC提供给客户(价值);
}
//第三步。
/*
*从服务器开票,但仅在所有客户端上执行
*/
[客户端RPC]
私有无效RPC提供给客户端(矢量3值)
{
/*此值也在最初发送的客户端上设置
*但事实并非如此