Unity NetworkTransform, принудительно обновлять каждый кадр? - PullRequest
0 голосов
/ 13 ноября 2018

В назначенной настройке локальной сети я хочу, чтобы Unity NetworkTransform просто отправлял каждый кадр.(Режим «Синхронное преобразование», а не твердое тело и т. Д.)

Мне интересно, как это сделать ... если вы просто установите скорость отправки 0,00001, будет ли она фактически делать это каждый кадр, что объектдвижется?

(Интерфейс Inspector позволяет только до 29 Гц, просто установите его в коде, если вы хотите меньшие значения.)

Я также думал о чем-то похожем на сценарий ......

 void Update() { .. SetDirtyBit( ? ); }

будет ли это делать?

(И что вы там используете в качестве битовой маски?)

Для определения такого рода действительно требуется вечностьвещь экспериментальная.Очевидно, доку Unity - это шутка.И я не мог гуглить никого, кто уже понял это.Есть опыт?


Во-вторых ...

Дополнительная информация.Мы провели несколько экспериментов, и действительно, если вы установите его на очень маленькое значение, кажется для синхронизации NetworkTransform каждого отдельного кадра.

(Конечноотправка не беспокоит, если она не перемещается, как @Programmer указывает ниже.)

ОДНАКО это не дает плавные результаты для кинематических объектов или положений камеры.Я не знаю почему;это связано с циклом обновления и точно, когда изменение происходит.Но то, что вы получаете, это «очень хороший джиттер».


В-третьих ...

Я провел эксперимент, , просто используя команды и Rpcs, для отправки некоторой информации каждый кадр (на самом деле от одного клиента к другому).

Я специально использовал специальную сеть ethernet соло, и приложения практически ничего не делают, кроме отправки информации каждый кадр (т.е. "вручную, просто используя Command / Rpc), то есть в Update ().

На самом деле, все еще отбрасывает много кадров, часто не отправляется.(Допустим, он пропускает 10 или 20 за 10 секунд.)

Горе!

Не беспокойтесь, если вам нужна информация, отправляемая "каждый кадр", скажем, по локальной сетисистема.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

если вы просто установите скорость отправки 0,00001, будет ли она фактически делать это каждый кадр, в котором движется объект?

Да , но когда объектпреобразование не движется и не вращается, оно не обновляется по сети независимо от значения NetworkTransform.sendInterval.

Я тоже думал что-то вроде сценария ......

void Update() { .. SetDirtyBit( ? ); }

Да .Вам нужно вызывать SetDirtyBit каждый кадр, если вам нужно отправить сетевое обновление для объекта.

И что вы там используете в качестве битовой маски?

Функция SetDirtyBit технически является версией функции атрибута SyncVar.Аргумент не очень документирован, но если помечена переменная SyncVar, ее грязная маска меняется на 1.Это также означает, что вы должны передать 1 в функцию SetDirtyBit, если вы хотите, чтобы сетевое обновление отправлялось для объекта.

Вы также должны использовать его из функции, отмеченной атрибутом [Command], а не непосредственно из функции Update.Пример ниже:

void Update()
{
    if (isLocalPlayer)
    {
        CmdUpdateTransform();
    }
}

[Command]
void CmdUpdateTransform()
{
    SetDirtyBit(1u);
}

Хотя Unity заявляет, что вы можете обновить преобразование, просто используя функцию SetDirtyBit.Я не думаю, что это правда.В заявлении отсутствует много информации.Вам потребуется OnSerialize для сериализации и отправки данных и OnDeserialize для их получения и десериализации.Функция SetDirtyBit просто используется для определения того, какие данные отправлять.Он используется для уменьшения проблем с пропускной способностью, возникающих при использовании uNET.

Приведенный ниже код показывает, как должно выглядеть использование SetDirtyBit.Может потребоваться несколько изменений, чтобы работать на вашей стороне.

public class Example : NetworkBehaviour
{
    private const uint SEND_POSITION = 1u;
    private const uint SEND_ROTATION = 2u;
    private const uint SEND_SCALE = 3u;

    void Update()
    {
        uint dirtyBit = syncVarDirtyBits;

        dirtyBit |= SEND_POSITION;
        dirtyBit |= SEND_ROTATION;
        dirtyBit |= SEND_SCALE;

        if (isLocalPlayer)
        {
            CmdUpdateTransform(dirtyBit);
        }
    }

    [Command]
    void CmdUpdateTransform(uint dirtyBit)
    {
        SetDirtyBit(dirtyBit);
    }

    public override bool OnSerialize(NetworkWriter writer, bool initialState)
    {
        if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
        {
            writer.Write(this.transform.position);
        }

        if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
        {
            writer.Write(this.transform.rotation);
        }

        if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
        {
            writer.Write(this.transform.localScale);
        }
        return true;
    }

    public override void OnDeserialize(NetworkReader reader, bool initialState)
    {

        if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
        {
            Vector3 pos = reader.ReadVector3();
        }

        if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
        {
            Quaternion rot = reader.ReadQuaternion();
        }

        if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
        {
            Vector3 scale = reader.ReadVector3();
        }
    }
}
0 голосов
/ 13 ноября 2018

В Документах Unity Там написано

Если sendInterval равен нулю, обновления будут отправляться в конце кадра, когда для этого сценария установлены грязные биты. Обратите внимание, что установка значения SyncVar автоматически установит грязные биты.

Таким образом, вы можете использовать свой собственный скрипт, используя NetworkSettings

using UnityEngine.Networking;

[NetworkSettings(channel = 1, sendInterval = 0.0f)]
class MyScript : NetworkBehaviour
{
    [SyncVar]
    int value;
}

Однако SyncVar работает только Сервер -> Клиент.

Но вы можете использовать SetDirtyBit , чтобы вручную установить грязное поведение.


Или, возможно, вы также можете использовать InvokeSyncEvent для непосредственной синхронизации некоторых значений.


Здесь Я нашел немного больше информации о Dirty битах.

...