Важно: UNet — это устаревшее решение, а также новая многопользовательская и сетьсистема Unity, которая обеспечивает многопользовательскую игру. игры через компьютерную сеть. Подробнее См. в Словарь Решение (Netcode для GameObjects) находится в разработке. Дополнительную информацию и дальнейшие действия см. на веб-сайте Unity Netcode for GameObjects. |
В дополнение к «высокоуровневым» командам и вызовам RPC вы также можете отправлять необработанные сетевые сообщения.
Существует класс с именем MessageBase, который можно расширить для создания сериализуемых классов сетевых сообщений. Этот класс имеет функции Serialize и Deserialize, которые возьмите объекты писателя и читателя. Вы можете реализовать эти функции самостоятельно или положиться на реализацию, сгенерированную кодом, которая автоматически создается сетевой системой. Базовый класс выглядит так:
public abstract class MessageBase
{
// De-serialize the contents of the reader into this message
public virtual void Deserialize(NetworkReader reader) {}
// Serialize the contents of this message into the writer
public virtual void Serialize(NetworkWriter writer) {}
}
Класс сообщений может содержать члены, являющиеся базовыми типами, структурами и массивами, включая большинство распространенных типов Unity Engine (например, Vector3). Они не могут содержать членов, являющихся сложными классами или универсальными контейнерами. Помните, что если вы хотите полагаться на реализации, сгенерированные кодом, вы должны убедиться, что ваши типы общедоступны.
Существуют встроенные классы сообщений для распространенных типов сетевых сообщений:
Чтобы отправить сообщение, используйте метод Send()
в NetworkClient, NetworkServer и NetworkConnection, которые работают одинаково. Он принимает идентификатор сообщения и объект сообщения, полученный из MessageBase. В приведенном ниже коде показано, как отправить и обработать сообщение с помощью одного из встроенных классов сообщений:
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;
public class Begin : NetworkBehaviour
{
const short MyBeginMsg = 1002;
NetworkClient m_client;
public void SendReadyToBeginMessage(int myId)
{
var msg = new IntegerMessage(myId);
m_client.Send(MyBeginMsg, msg);
}
public void Init(NetworkClient client)
{
m_client = client;
NetworkServer.RegisterHandler(MyBeginMsg, OnServerReadyToBeginMessage);
}
void OnServerReadyToBeginMessage(NetworkMessage netMsg)
{
var beginMessage = netMsg.ReadMessage();
Debug.Log("received OnServerReadyToBeginMessage " + beginMessage.value);
}
}
Чтобы объявить собственный класс сетевых сообщений и использовать его:
using UnityEngine;
using UnityEngine.Networking;
public class Scores : MonoBehaviour
{
NetworkClient myClient;
public class MyMsgType {
public static short Score = MsgType.Highest + 1;
};
public class ScoreMessage : MessageBase
{
public int score;
public Vector3 scorePos;
public int lives;
}
public void SendScore(int score, Vector3 scorePos, int lives)
{
ScoreMessage msg = new ScoreMessage();
msg.score = score;
msg.scorePos = scorePos;
msg.lives = lives;
NetworkServer.SendToAll(MyMsgType.Score, msg);
}
// Create a client and connect to the server port
public void SetupClient()
{
myClient = new NetworkClient();
myClient.RegisterHandler(MsgType.Connect, OnConnected);
myClient.RegisterHandler(MyMsgType.Score, OnScore);
myClient.Connect("127.0.0.1", 4444);
}
public void OnScore(NetworkMessage netMsg)
{
ScoreMessage msg = netMsg.ReadMessage();
Debug.Log("OnScoreMessage " + msg.score);
}
public void OnConnected(NetworkMessage netMsg)
{
Debug.Log("Connected to server");
}
}
Обратите внимание, что в этом примере исходного кода нет кода сериализации для класса ScoreMessage
. Тело функций сериализации автоматически создается Unity для этого класса.
Класс ErrorMessage
Также существует класс ErrorMessage, производный от MessageBase
. Этот класс передается в обратные вызовы ошибок на клиентах и серверах.
код_ошибки в классе ErrorMessage соответствует Перечисление Networking.NetworkError.
class MyClient
{
NetworkClient client;
void Start()
{
client = new NetworkClient();
client.RegisterHandler(MsgType.Error, OnError);
}
void OnError(NetworkMessage netMsg)
{
var errorMsg = netMsg.ReadMessage();
Debug.Log("Error:" + errorMsg.errorCode);
}
}