从错误的玩家发射的射弹

本文关键字:发射 玩家 错误 | 更新日期: 2023-09-27 18:36:10

我正在为我的朋友做一个小游戏。到目前为止,我已经正确设置了网络,两个玩家都可以飞来飞去,而且一切都是同步的。

现在我添加了射弹(激光),我像这样生成:

if (_mou.LeftButton == ButtonState.Pressed 
         && oldState.LeftButton 
         != ButtonState.Released)               
         {
             if (timeSinceShot > timePerShot)
            {
                timeSinceShot = 0;
                bulletRotation = rotation; //Rotation of the players ship
                laser.addLaser(myID, bulletRotation, localPosition);
            }
         }

这工作正常,它从我的船上发射激光,但尚未显示。

现在当我开火时,我称之为:

om.Write(bulletRotation); //Sends the rotation to the server

当服务器收到它时,它会将其发送回所有玩家,包括射击的玩家。

以下是我在客户端上接收数据并将其写入激光器列表的方式:

if (who != myID)
{
   try
   {
      float laserR = msg.ReadFloat();
      laser.addLaser(who, laserR, player.players[i].position);
   }
   catch { }
}

现在,当我在 2 个客户端上测试它并开火时,我可以看到自己在第二个客户端上开火,这很好。但是,它不仅会在第二个客户端上开火,还会在我客户端的第二个玩家上开火。

编辑:谁是RemoteUniqueIdentifier,myID是客户端RemoteUniqueIdentifier

这是我的问题的图片。https://i.stack.imgur.com/CYJyW.png(还不能上传,因为我没有 10 次代表。

编辑2:

这是服务器将其数据发送给所有玩家的方式:

foreach (NetConnection player in server.Connections)
                    {
                        // ... send information about every other player (actually including self)
                        foreach (NetConnection otherPlayer in server.Connections)
                        {
                            // send position update about 'otherPlayer' to 'player'
                            NetOutgoingMessage om = server.CreateMessage();
                            // write who this position is for
                            om.Write(player.RemoteUniqueIdentifier);
                            om.Write(otherPlayer.RemoteUniqueIdentifier);
                            if (otherPlayer.Tag == null)
                                otherPlayer.Tag = new float[4];
                            float[] pos = otherPlayer.Tag as float[];
                            om.Write(pos[0]); // velocity X
                            om.Write(pos[1]); // velocity X
                            om.Write(pos[2]); // rotation
                            if (!noLasers)
                            {
                                om.Write(pos[3]); // bullet rotation
                            }
                            // send message
                            server.SendMessage(om, player, NetDeliveryMethod.Unreliable);
                        }
                    }

从错误的玩家发射的射弹

如果RemoteUniqueIdentifier是某个类的对象,并且您试图天真地通过线路传递它,您将永远无法测试本地版本和您从服务器获得的相等版本。

"另一侧"的重建对象将始终具有无法与原始对象进行比较的参考。

在这种情况下,您可以选择从RemoteUniqueIdentifier切换到某种不可变类型,例如 intGuid ,即使string也可以使用。