Я создаю многопользовательскую игру, которая должна взаимодействовать с сервером. Для связи я создал ClientObject, который постоянно ожидает сообщения от сервера. Когда сообщение получено, оно расшифровывает его и отправляет событие с сообщением. В функции, которая срабатывает, когда событие транслируется, я пытаюсь присвоить часть сообщения PlayerObject. Например, имя других игроков. Моя проблема в том, что когда он достигает Players [i] .Name = name [i], программа зависает. Отладка показывает, что имя [i] является ожидаемым значением. Player [i] .Name имеет значение null в точке назначения, но является доступной переменной String, поэтому строка должна работать.
Объект клиента:
public class ClientObject
{
public Socket clientSocket;
public void Connect()
{
IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse("192.168.56.1"), 3000);
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(serverAddress);
Thread thread = new Thread(new ThreadStart(ReceiveMessage));
thread.Start();
}
public void ReceiveMessage() {
try
{
while (true)
{
byte[] rcvLenBytes = new byte[4];
clientSocket.Receive(rcvLenBytes);
int rcvLen = System.BitConverter.ToInt32(rcvLenBytes, 0);
byte[] rcvBytes = new byte[rcvLen];
clientSocket.Receive(rcvBytes);
String rcv = System.Text.Encoding.ASCII.GetString(rcvBytes);
MessageReceivedEventArgs args = new MessageReceivedEventArgs();
args.Message = rcv;
if (TestMessageRecevied != null)
{
TestMessageRecevied(this, args);
}
}
}
catch
{
}
}
public delegate void MessageHandler(object sender, MessageReceivedEventArgs e);
public event MessageHandler TestMessageRecevied;
}
public class MessageReceivedEventArgs : EventArgs
{
public string Message { get; set; }
}
Объект игрока:
public class PlayerObject
{
public string Name
{
get;
set;
}
public bool ReadyState
{
get;
set;
}
public int DiceLeft
{
get;
set;
}
}
Готовое меню:
В этом случае я назначаю переменную PlayerObject.Name, но она также зависает, если я пытаюсь изменить спрайт изображений или значение текстового объекта в пользовательском интерфейсе. Так что, похоже, проблема с назначением, но не может тренироваться, что. Если я выполняю назначение в методе Start (), он отлично работает.
public class ReadyMenu : MonoBehaviour
{
ClientObject client;
public GameObject backgroundPanel;
public Sprite tick;
public Sprite cross;
Text pName;
Image imgCheck;
PlayerObject[] players;
// Start is called before the first frame update
void Start()
{
pName = GameObject.Find("PlayerPanel1/Name").GetComponent<Text>();
players = new PlayerObject[6];
client = new ClientObject();
client.TestMessageRecevied += Client_MessagedReceived;
client.Connect();
SendClientMessage(PlayerPrefs.GetString("name"));
}
private void Client_MessagedReceived(object sender, MessageReceivedEventArgs e)
{
Debug.Log("In C_MR: " + e.Message);
string message = e.Message;
if (message.Contains("READY"))
{
//NOT IMPLEMENTED YET
return;
}
if (message.Contains("PLAYERS"))
{
//Message before split
Debug.Log(message);
message = message.Substring(7);
//Cut PLAYERS from the string
Debug.Log("substring: "+message);
//Seperate names
char[] sep = { ' ' };
String[] names = message.Split(sep,StringSplitOptions.RemoveEmptyEntries);
Debug.Log("after name split");
Debug.Log("names length is: "+names.Length);
Debug.Log("names 0 is: "+names[0]);
for (int i = 0; i < names.Length; i++)
{
Debug.Log("in loop, i = "+i);
Debug.Log("in loop, setting playerobject name");
players[i] = new PlayerObject();
players[i].Name = names[i];
Debug.Log("in loop, after setting playerobject name");
//GameObject panel = GameObject.Find("PlayerPanel" + (i + 1));
//Debug.Log("in loop, activate apnel");
//panel.SetActive(true);
}
Debug.Log("finsihed");
}
}
Вывод с проверяемым именем
В C_MR: PLAYERStest
PLAYERtest
Подстрока: test
после разделения
длина имен равна: 1
длина имен 0: test
в l oop, i = 0
в l oop, установка имени игрока