提问人:Tom3652 提问时间:11/13/2023 最后编辑:derHugoTom3652 更新时间:11/17/2023 访问量:72
客户端/服务器 RPC 如何使用全局变量?
How Client / Server RPC works with global variables?
问:
我是Unity的新手,对于我所看到的行为,我找不到任何合乎逻辑的答案。
我写了一个基本的脚本,例如:
public class PlayerPosition : NetworkBehaviour
{
private Dictionary<string, int> testDict = new();
[ServerRpc(RequireOwnership = false)]
private void HitServerRpc(string key, int value)
{
RefreshClientRpc(key, value);
}
[ClientRpc]
private void RefreshClientRpc(string key, int value)
{
testDict[key] = value;
foreach (var item in testDict)
{
Debug.Log($"Item in current dict {item}");
}
}
// Other logical code that calls only HitServerRpc().
}
我在客户端/主机情况下在我的播放器上使用此脚本。
我有一个客户端和一个主机(服务器 + 客户端)用于测试和问题。Prefab
我的问题是:当通过 2 个不同的 RPC 调用(每个客户端一个)添加至少 2 个不同的键和值时,为什么只有一个键和一个值?testDict
即使在两个不同的客户端上调用了日志,日志也只显示一次:Item in current dict
HitServerRpc()
HitServerRpc("user1", 3)
HitServerRpc("user2", 4)
所有客户端都应等于:testDict
{{"user1", 3}, {"user2", 4}}
PS:最奇怪的是,我试图在静态类中移动并在静态类内部更新它,而不是处理RPC调用的类,它现在在主机上具有正确的值,但在客户端上仍然没有。testDict
答:
所有客户端的 testDict 都应等于:
{{"user1", 3}, {"user2", 4}}
我明白你为什么这么想,但不是!这些调用中的每一个都来自不同的客户端 ->,因此来自/到你的 的不同实例。PlayerPosition
假设在您的描述中,您有两个玩家和 .user1
user2
其中每个都调用了各自的地方当局实例。然后,它作为 ClientRPC 中继到其他连接的客户端,但仍然只中继到它们各自的实例。HitServerRpc
PlayerPosition
试图将此可视化
user 1 Device Server user 2 Device
user 1 (local auth) ----> user 1 ----> user1
user 2 <---- user 2 <---- user 2 (local auth)
结果是,相应的字典确实是同步的,但是,属于用户 1 的用户将只知道密钥,因此另一个实例只拥有密钥。PlayPosition
user1
user2
所以我认为在您的用例中,实际上使用静态是有意义的。不过,没有必要把它放到不同的类中。你可以使用
private static readonly Dictionary<string, int> testDict = new();
因此,所有本地实例都使用相同的字典实例。PlayerPosition
评论
Debug.Log(nameof(HitServerRpc), this);
Debug.Log(nameof(RefreshClientRpc), this);
this
评论