Unet не синхронизирует значение с плавающей запятой между клиент-сервер, сервер-клиент

Я пытаюсь синхронизировать значение с плавающей запятой между сервером и клиентом.

На экране сервера есть скрипт босса HpBar с настройкой значения MAXHP в сцене.

сборка игрока имеет свой собственный интерфейс HP босса и скрипт localhp, который будет получать текущее значение HP босса из скрипта HpBar на сервере.

когда пользователь нажимает кнопку «Атака», он отправляет значение урона в скрипт HpBar, после чего он должен обновляться до префаба игрока. но это не синхронизируется вместе. Благодарность

фото здесь https://imgur.com/a/KrYtC3T

Скрипт localPlayerHPBAR:

public class localHpBar : NetworkBehaviour
{

    public HpBar serverHp;
    public float localhpPoint;
    public Image localhpBar;

    // Start is called before the first frame update
    void Start()
    {
        serverHp = GameObject.FindObjectOfType<HpBar>();
        //Get OBJ of serverHP
    }

    public void sendDamage(float dmg)
    {
        serverHp.TakeDamage(dmg); //SendDamageToserver
    }

    // Update is called once per frame
    void Update()
    { 
        //get HP point from server
        localhpPoint = serverHp.sum;
        localhpBar.fillAmount = localhpPoint;
    }
}

СЕРВЕР

public class HpBar : NetworkBehaviour
{
    public Image HP;
    public float MaxHP;
    float currentHP;
    public float localhp;
    [SyncVar] public float sum;

    void Start()
    { 
        //set CURRENT HP
        currentHP = MaxHP;
    }

    [ClientRpc]
    void rpcDamage(float dmg)
    {       
        sum = currentHP / MaxHP;
        HP.fillAmount = sum;
    }

    public void TakeDamage(float dmg)
    {

        //recieve DamageFrom client
        currentHP = currentHP - dmg;
        rpcDamage(currentHP);
    }
}

person warwolf    schedule 03.09.2019    source источник


Ответы (1)


Обратите внимание, что [SyncVar] — это только синхронизированные серверные клиенты.

Никогда в другом направлении. Изменение этого значения на клиенте не повлияет на сервер или других клиентов.

Вы меняете sum с помощью [ClientRpc]. [ClientRpc] вызывается сервером, но выполняется на всех клиентах. Вам даже не разрешено вызывать это как клиент.


Что вам лучше сделать, так это сделать метод TakeDamage [Command], чтобы он вызывался клиентом, но выполнялся только на сервере, где вы затем можете изменить синхронизированное значение, например

// This is called by clients but executed on the server
[Command]
public void CmdTakeDamage(float dmg)
{
    currentHP -= dmg;

    sum = currentHP / MaxHP;

    // actually pass on the new sum
    rpcDamage(sum);
}

// This is called ONLY by the server but executed on all clients
[ClientRpc]
// also make sure the prefix is capital Rpc otherwise it might not work
void RpcDamage(float newSum)
{
    // if you set sum here then you should simply remove the 
    // [SyncVar] since you already sync it "manually"
    // I would actually do this since it is not guaranteed that the syncvar
    // transfers its new value before this method is executed
    // on the other hand syncvar is additionally synchronized when connecting a new client
    // so you might have to do it "manually"
    sum = newSum;
    HP.fillAmount = sum;
}
person derHugo    schedule 03.09.2019
comment
Спасибо. код работает и значение синхронизируется, когда я нажимаю кнопку атаки на хосте. но в клиенте он не обновляет значение. спасибо - person warwolf; 03.09.2019