Dark Rift 2 Movement-Движение

Поделиться.

Движение

Отправка нашей позиции
В проекте Unity создайте новый скрипт C # под названием Player, он будет отправлять нашу позицию на сервер каждый раз, когда мы будем двигаться. Вставьте в него следующий код:

public class Player : MonoBehaviour
{
    const byte MOVEMENT_TAG = 1;
    const ushort MOVE_SUBJECT = 0;

    [SerializeField]
    [Tooltip("The distance we can move before we send a position update.")]
    float moveDistance = 0.05f;

    public UnityClient Client { get; set; }

    Vector3 lastPosition;

    void Awake()
    {
        lastPosition = transform.position;
    }

    void Update()
    {
        if (Vector3.Distance(lastPosition, transform.position) > moveDistance)
        {
            /* Send position to server here */

            lastPosition = transform.position;
        }
    }
}

Добавьте этот скрипт на Controllable Player прифаб. В нашем PlayerSpawner измените оператор if в цикле while на:

if (id == client.ID)
{
    obj = Instantiate(controllablePrefab, position, Quaternion.identity) as GameObject;

    Player player = obj.GetComponent<Player>();
    player.Client = client;
}
else
{
    obj = Instantiate(networkPrefab, position, Quaternion.identity) as GameObject;
}

Теперь заполним класс Player кодом для отправки нашей позиции на сервер. Все, что нужно отправить, это x, y, z  компоненты transform.position.

Вот код :

using (DarkRiftWriter writer = DarkRiftWriter.Create())
{
    writer.Write(transform.position.x);
    writer.Write(transform.position.y);

    using (Message message = Message.Create(Tags.MovePlayerTag, writer))
        Client.SendMessage(message, SendMode.Unreliable);

Не забудьте добавить тег в файл тегов:

public static readonly ushort MovePlayerTag = 1;

Ничто из этого не должно выглядеть незнакомым, мы создаем кодировцик и упаковываем данные, которые хотим отправить, помещаем их внутри сообщения с тегом движения, а затем отправляем (если сервер не получает позицию, это еще не конец света потому что очень скоро мы пошлем еще).

Обновление позиции сервера
На нашем сервере нам нужно отслеживать позиционные изменения каждого игрока, чтобы новые игроки подключались всегда к последней позиции, нам также нужно отправить это сообщение об обновлении движения всем другим игрокам.

В нашем плагине сервера добавьте следующую строку в метод ClientConnected:

e.Client.MessageReceived += MovementMessageReceived;

Вам также необходимо добавить константу тега движения в файл тега.

Мы сообщаем объекту клиента, что всякий раз, когда он получает сообщение, он должен вызывать наш обработчик для его обработки. Давайте добавим этот обработчик .

void MovementMessageReceived(object sender, MessageReceivedEventArgs e)
{
    using (Message message = e.GetMessage() as Message)
    {
        if (message.Tag == Tags.MovePlayerTag)
        {
            using (DarkRiftReader reader = message.GetReader())
            {
                float newX = reader.ReadSingle();
                float newY = reader.ReadSingle();

                Player player = players[e.Client];

                player.X = newX;
                player.Y = newY;

                using (DarkRiftWriter writer = DarkRiftWriter.Create())
                {
                    writer.Write(player.ID);
                    writer.Write(player.X);
                    writer.Write(player.Y);
                    message.Serialize(writer);
                }

                foreach (IClient c in ClientManager.GetAllClients().Where(x => x != e.Client))
                    c.SendMessage(message, e.SendMode);
            }
        }
    }
} 

Еще раз, первые несколько строк этого должны выглядеть знакомыми. Кодировщик здесь просто обновляет содержимое сообщения, поэтому мы включаем идентификатор игрока (нам нужно знать, кто его отправил, когда мы получаем на клиенте). Наконец, мы отправляем сообщение всем, кроме отправителя, чтобы все они обновили позицию.!

Обновление позиции клиента

Чтобы справиться с движением по игре, мы собираемся переместить всех клиентов с одним менеджером. Создайте новый скрипт C # в проекте Unity под названием NetworkPlayerManager и добавьте этот код:

public class NetworkPlayerManager : MonoBehaviour
{
    [SerializeField]
    [Tooltip("The DarkRift client to communicate on.")]
    UnityClient client;

    Dictionary<ushort, AgarObject> networkPlayers = new Dictionary<ushort, AgarObject>();

    public void Add(ushort id, AgarObject player)
    {
        networkPlayers.Add(id, player);
    }
}

Добавьте скрипт к нашему объекту Network и назначьте поле клиента.

Добавьте следующее поле в PlayerSpawner и назначьте его в инспекторе:

[SerializeField]
[Tooltip("The network player manager.")]
NetworkPlayerManager networkPlayerManager;

Добавьте эту строку в нижнюю часть окна метода SpawnPlayer:

networkPlayerManager.Add(id, agarObj);

Напишем логику, чтобы получать сообщения о движении .  Вот код:

public void Awake()
{
    client.MessageReceived += MessageReceived;
}

void MessageReceived(object sender, MessageReceivedEventArgs e)
{
    using (Message message = e.GetMessage() as Message)
    {
        if (message.Tag == Tags.MovePlayerTag)
        {
            using (DarkRiftReader reader = message.GetReader())
            {
                ushort id = reader.ReadUInt16();
                Vector3 newPosition = new Vector3(reader.ReadSingle(), reader.ReadSingle(), 0);

                networkPlayers[id].SetMovePosition(newPosition);
                networkPlayers[id].SetRadius(reader.ReadSingle());
            }
        }
    }
}

Поделиться.

Добавить комментарий

Войти с помощью: 

Ваш e-mail не будет опубликован. Обязательные поля помечены *