在我的联网游戏的代码中,客户端接收一个消息,即玩家实体由用户控制或仅由服务器控制。
UserControlled = msg.ReadBoolean();
此变量设置绝对没有其他位置,除非使用默认值false进行实例化。我使用Visual C#中的“查找所有引用”功能对此进行了双重检查。此外,在此语句的范围内没有具有相同名称的局部变量。我发现在上述陈述的范围内,一切都是发现和花花公子;变量设置为true,如之后直接将其打印到控制台所示。此时,奇怪的事情发生了。每次从我的播放器类的外部引用变量时,它都会正确显示为true - 但是只要从播放器代码中引用它,它就会返回布尔值实例化的默认值;无论是真还是假。
我对这个问题一无所知,任何可能导致解决方案的信息都非常感激:)
如果您想要更多代码,我当然可以提供。我只是不确定除变量的随机引用之外还包括什么,所以我决定将它们排除在外。
谢谢!
编辑更多代码:
UserControlled被定义为普通的类范围变量。
public bool UserControlled = false;
设置值的方法:
public override void ParseUpdateMsg(NetIncomingMessage msg)
{
switch (msg.ReadByte())
{
case 0: // positional message
//snip
break;
case 1: // other info
// The following simply reads in the information
// I'm using Lidgren Network Library. It's extensively tested so I don't suspect that it's the issue
Speed = msg.ReadInt16();
Username = msg.ReadString();
UserControlled = msg.ReadBoolean();
MovingDir = msg.ReadString();
Health = msg.ReadInt16();
Hunger = msg.ReadInt16();
Mana = msg.ReadInt16();
// The following is simply debugging information to the screen
// As said above, UserControlled at this point is correctly displayed as True
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("--------------------------");
Console.WriteLine("Update message received!");
Console.WriteLine("ID: " + ID + "\tType: " + this.GetType().ToString());
Console.WriteLine("Speed: " + Speed);
Console.WriteLine("Username: " + Username);
Console.WriteLine("UserControlled: " + UserControlled);
Console.WriteLine("MovingDir: " + MovingDir);
Console.WriteLine("--------------------------");
Console.ForegroundColor = ConsoleColor.White;
break;
}
}
以下是接收消息并将其传递给播放器实体以进行评估的客户端代码:
switch (msg.ReadInt16())
{
case 1:
// Entity message
switch (msg.ReadByte())
{
case 0: // Create entity
//snip
break;
case 1: // Update entity
int id1 = msg.ReadInt16();
Entities[id1].ParseUpdateMsg(msg); // the player entity is passed the information
// At this point, there is only one entity, and that is the player.
// More debug information. Still displayed correctly as true.
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("--------------------------");
Console.WriteLine("-analysis 1-");
Console.WriteLine("(Within scope of update-entity message)");
Console.WriteLine("UserControlled: " + ((ClientEntPlayer)Entities[id1]).UserControlled);
Console.WriteLine("--------------------------");
Console.ForegroundColor = ConsoleColor.White;
break;
case 2: // Destroy entity
//snip
break;
}
// Displayed correctly here as well!
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("--------------------------");
Console.WriteLine("-Post-analysis 2-");
Console.WriteLine("(Within scope of generic entity message)");
Console.WriteLine("UserControlled: " + player.UserControlled);
Console.WriteLine("--------------------------");
Console.ForegroundColor = ConsoleColor.White;
break;
}
设置值后,上面的所有调试代码都会正确显示为True。但是,一旦我们开始进入定时检查,它就开始变得不正确(但仍然只是来自玩家的代码!)
以下内容来自客户的更新代码。它每5秒正确显示一次UserControlled值。
if (gameTime.TotalGameTime.Seconds % 5 == 0 && player != null && debugTime != gameTime.TotalGameTime.Seconds)
{
Console.ForegroundColor = ConsoleColor.DarkMagenta;
Console.WriteLine("--------------------------");
Console.WriteLine("Client's Timed Post-Analysis");
Console.WriteLine("Elapsed time: " + gameTime.TotalGameTime.Seconds + " sec");
Console.WriteLine("(Within scope of client update)");
Console.WriteLine("UserControlled: " + player.UserControlled);
Console.WriteLine("--------------------------");
Console.ForegroundColor = ConsoleColor.White;
debugTime = gameTime.TotalGameTime.Seconds;
}
这是表示在离开功能后玩家的值不正确的部分。它显示为false(以及依赖于被控制的播放器的其他代码,如响应键盘输入。)它与客户端的定时调试信息基本相同,只是在播放器的更新功能中。
if (gameTime.TotalGameTime.Seconds % 5 == 0 && debugTime != gameTime.TotalGameTime.Seconds)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("--------------------------");
Console.WriteLine("Player's Timed Post-Analysis");
Console.WriteLine("(Within scope of player update)");
Console.WriteLine("Elapsed time: " + gameTime.TotalGameTime.Seconds +" sec");
Console.WriteLine("UserControlled: " + UserControlled);
Console.WriteLine("--------------------------");
Console.ForegroundColor = ConsoleColor.White;
debugTime = gameTime.TotalGameTime.Seconds;
}
就是这样。谢谢你的帮助。
答案 0 :(得分:1)
由于缺少代码,这很难回答,但与此同时,无论如何发布所有代码都是不切实际的。
我大多数时候都是偶然地做过这件事,会在另一个范围内声明另一个变量,然后设置一个而不是我想要的变量。
所以,看起来代码只是设置在那个区域,但这也可能就是为什么你的“查找所有引用”只能找到那个位置。我会尝试右键单击UserControlled
和msg
变量,然后选择Go to declaration
。也许你会发现你正在设置一个与你没想到的同名的不同变量。
如果UserControlled
是类中的属性,您还可以尝试在其上设置断点。您可以右键单击断点并选择“When Hit ...”并将其设置为在其命中时打印堆栈跟踪及其值,而不是停止执行(我假设这是一个游戏,您可能不会希望/轻松地能够停止并继续执行。)
答案 1 :(得分:1)
正如我上面的评论所说,我无法告诉你发生了什么,但只能提供有关如何调试的建议。
首先,您说您已经检查了这一点但确保设置正确的UserControlled
。如果它是该类的成员(假设它是属性?),则在其前面添加this.
this.UserControlled = msg.ReadBoolean();
根据我在您的问题中的理解,UserControlled
在课堂内被询问时是 true ,但是当从课堂外查询时, false 。这只能是两件事:
为了进一步调查,你的财产是否正在做任何聪明的事情 - 即是否正在做其他任何设置和获得支持领域?你确定你正在使用你班级的单个实例吗?