服务器端的 UNET SyncVar 未更新

UNET SyncVar on server side not updated

我正在尝试使用 SyncVar,但我不完全理解我做错了什么,如果我做错了的话。情况是这样的:

  1. 我有两个 public SyncVar:redFunds 和 blueFunds 以及两个本地 "old" 版本要与

  2. 进行比较
  3. 我在 Start 中使用 Cmd_UpdateXxx 启动 SyncVar,有效

  4. 我有两个按钮,每个 SyncVar 一个

  5. 在更新中,我比较了 SyncVar 与 oldXxxFunds。如果命中我显示在现场

当我 运行 代码时,它确实在两个播放器(红色和蓝色)的场景中显示了正确的数字,但是当查看 "public" SyncVar 时,这并没有完全反映在编辑器中.当按下红色按钮时,它只会在编辑器中反映在红色播放器上,而不是蓝色播放器上。

有人可以向我解释一下我在这里做错了什么吗? ...如果我做错了什么。我不应该在编辑器中看到更改吗?

[SyncVar] public int redFunds;
[SyncVar] public int blueFunds;
public int oldRedFunds;
public int oldBlueFunds;

private void Start () 
{

    if (!isLocalPlayer)
        return;

    Cmd_UpdateRed (10);
    Cmd_UpdateBlue (20);
}

// Button
void btn_Red () 
{
    if (!hasAuthority)
        return;

    Cmd_UpdateRed (10000);
}

void btn_Blue () 
{
    if (!hasAuthority)
        return;

    Cmd_UpdateBlue (20000);
}

[Command]
void Cmd_UpdateRed (int _value) 
{
    redFunds = _value;
}

[Command]
void Cmd_UpdateBlue (int _value) 
{
    blueFunds = _value;
}

void Update () 
{
    if (redFunds != oldRedFunds) 
    {
        txt_RedTotalFunds = GameObject.Find ("txt_RedTotalFunds").GetComponent<Text> ();
        txt_RedTotalFunds.text = "$" + redFunds;
        oldRedFunds = redFunds;
    }

    if (blueFunds != oldBlueFunds) 
    {
        txt_BlueTotalFunds = GameObject.Find ("txt_BlueTotalFunds").GetComponent<Text> ();
        txt_BlueTotalFunds.text = "$" + blueFunds;
        oldBlueFunds = blueFunds;
    }
}

我能想到的最好方法是使用 GameRoomInfo 作为服务器拥有的网络对象。

可以使用如下 2 个简单的脚本来完成:

GameRoomInfo 脚本

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using System.Collections;

public class GameRoomInfo : NetworkBehaviour
{
    public Text txt_RedTotalFunds;
    public Text txt_BlueTotalFunds;

    public int oldRedFunds = 0;
    public int oldBlueFunds = 0;

    [SyncVar]
    public int redFunds;
    [SyncVar]
    public int blueFunds;

    void Update()
    {
        if (redFunds != oldRedFunds)
        {
            //txt_RedTotalFunds = GameObject.Find("txt_RedTotalFunds").GetComponent<Text>();
            txt_RedTotalFunds.text = "$" + redFunds;
            Debug.Log("Red - $" + redFunds);
            oldRedFunds = redFunds;
        }

        if (blueFunds != oldBlueFunds)
        {
            //txt_BlueTotalFunds = GameObject.Find("txt_BlueTotalFunds").GetComponent<Text>();
            txt_BlueTotalFunds.text = "$" + blueFunds;
            Debug.Log("Blue - $" + blueFunds);
            oldBlueFunds = blueFunds;
        }
    }
}

播放器脚本

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using System.Collections;

public class Player : NetworkBehaviour 
{
    public enum PlayerColor
    { 
        Red, 
        Blue
    };

    //used to update the right variables (Blue player updates blueFunds and Red player updates redFunds)
    [SyncVar]
    PlayerColor playerColor;

    static int colorSelect = 0;

    void Start()
    {
        if(isServer) 
        {
            // the server selects the player color when created
            switch(colorSelect % 2)
            {
                case 0:
                    playerColor = PlayerColor.Red;
                    break;
                case 1:
                    playerColor = PlayerColor.Blue;
                    break;
            }

            colorSelect++;
        }
    }

    void Update()
    {
        if (!isLocalPlayer)
            return;

        if (hasAuthority && Input.GetKeyDown(KeyCode.KeypadPlus))
        {
            Cmd_UpdateAdd(10);
        }
    }

    // Button
    void btn_Update()
    {
        if (!hasAuthority)
            return;

        Cmd_Update(0);
    }

    void btn_Add()
    {
        if (!hasAuthority)
            return;

        Cmd_Update(10);
    }


    [Command]
    public void Cmd_Update(int _value)//The command updates the GameRoomInfo variables according to the player color
    {
        switch (playerColor)
        {
            case PlayerColor.Red:
                FindObjectOfType<GameRoomInfo>().redFunds = _value;
                break;

            case PlayerColor.Blue:
                FindObjectOfType<GameRoomInfo>().blueFunds = _value;
                break;

            default:
                break;
        }
    }

    [Command]
    public void Cmd_UpdateAdd(int _value)
    {
        switch (playerColor)
        {
            case PlayerColor.Red:
                FindObjectOfType<GameRoomInfo>().redFunds += _value;
                break;

            case PlayerColor.Blue:
                FindObjectOfType<GameRoomInfo>().blueFunds += _value;
                break;

            default:
                break;
        }
    }
}

我做了一些小改动以帮助测试。随意适应您的需求。