SyncVar不会更改按钮上的Bool按下Unity 3d

时间:2018-10-06 23:41:01

标签: unity3d

这是我的第一个网络项目。我试图遵循一些教程,这就是我正在遇到的问题:我试图在单击按钮时简单地更改一个布尔值。该按钮位于一个场景中,而此处的文本对象位于另一个场景中。因此,我在两个不同的场景中运行同一网络管理器。我意识到这不是常规做法,但对我的项目来说必须是这种方式。我现在要寻找的只是它要更改文本,一旦我了解了它是如何发生的,我确定我可以弄清楚其余部分。

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

public class textChanger : NetworkBehaviour 
{
    Text text;

    [SyncVar]
    bool change = false;

    // Use this for initialization
    void Start () 
    {
        text = gameObject.GetComponent<Text>();
    }

    // Update is called once per frame
    void Update () 
    {
        if(change)
        {
            text.text = "it worked";
        }
    }


    [Command]
    public void CmdChangeText()
    {
        change = true;
    }

}

如果我通过按键将“ change”设置为true,则代码将完全按照应有的方式运行,文本也会更改。但是当我从另一个场景单击按钮时,它不起作用。我正在使用Networking Hud,实际上这两个场景已连接在一起。但是变量没有更新。

enter image description here

enter image description here

在第一张图片中,“ Text”游戏对象正在运行“ Text Changer”脚本。在第二张图片中,按钮也具有运行它的通用“游戏对象”对象。您可以在调用“文本转换器”脚本上的“ CmdChangeText”方法的onClick按钮区域中看到该引用。

所以在我脑海中,一切看起来都应该正常运行,但事实并非如此。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

来自Unity Documentation

  

这些变量的值将从服务器同步到客户端

因此,如果您尝试在客户端上安装它,将无法正常工作。只能像以前一样使用[Command]来完成。


您还应该检查控制台输出。据我所知,为了能够调用Command方法,必须将保持NetworkIdentity设置为LocalPlayerAuthority。为了使它工作,我总是不得不在Player对象本身上为所有命令放置一个特殊的类。


我知道这可能不是答案,但至少有一种解决方法:
不用等待[SyncVar],您可以直接使用[ClientRpc]设置值:

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

public class textChanger : NetworkBehaviour {

    Text text;

    private bool change = false;

    // Use this for initialization
    void Start () {
        text = gameObject.GetComponent<Text>();
    }

    // Update is called once per frame
    void Update () {
        if(change)
        {
            text.text = "it worked";
        }
    }

    [Command]
    public void CmdChangeText()
    {
        // sets the value on the server
        change = true;

        RpcChangeText();
    }

    // This is executed on ALL clients
    // SyncVar is no longer needed
    [ClientRpc]
    private void RpcChangeText()
    {
        change = true;
    }
}