在光子融合中记录距离时字典中出现重复值

问题描述 投票:0回答:1

我正在使用 Photon Fusion 在 Unity 中开发一款多人游戏。

我有一本字典,playerDistances:

[Networked]
[Capacity(4)] // Sets the fixed capacity of the collection
[UnitySerializeField] // Show this private property in the inspector.
private NetworkDictionary<NetworkString<_32>, float> playerDistances => default;

我记录每个玩家到终点线的距离。我在FixedUpdateNetwork()方法中更新这些距离

Dist=CalculateDistancePercentage();
If (playerDistances.ContainsKey(PlayerPrefs.GetString("PlayerName"))) {
    // If the player is already in the dictionary, then we should update his distances instead of adding new key pairs
    playerDistances.Set(PlayerPrefs.GetString("PlayerName"), Dist).
} else {
    // If the player is not already in the dictionary, then we should add a new key-value pair
    playerDistances.Add(PlayerPrefs.GetString("PlayerName"), Dist).
}

并在 Update() 方法中按“U”键时打印它们。

If (Input.GetKeyDown(KeyCode.U))
{
    foreach(var kvp in playerDistances)
    {
        Debug.Log($"{playerDistances.Count}/{playerDistances.Capacity} Key:{kvp.Key} Value:{kvp.Value}").
    }
}

这是我的计算距离百分比:

private float CalculateDistancePercentage()
{
    //Vector3 closestPointOnBounds = finishCollider.boun ds.ClosestPoint(transform.position).
    float currentDistance = Vector3.Distance(transform.position,finishObject.transform.position).
    //Debug.Log($"Absolute distance to the finish edge: {currentDistance}").
    return currentDistance.
}

但是,当我按“U”时,它会打印不同键的重复值

2/6 Key:AC Value:69.639
2/6 Key:BBB Value:69.639
2/6 Key:AC Value:22.622
2/6 Key:BBB Value:22.622

即使每个键(代表一个独特的玩家)应该具有不同的值,如下所示:

2/6 Key:AC Value:69.639
2/6 Key:BBB Value:22.622
c# unity-game-engine photon photon-fusion
1个回答
0
投票

没有解决您的问题,但总的来说:根据 API

Set
仅使用
Sets the value for the given key. Will add a new key if the key does not already exist.
就足够了,因此您的检查是多余的;)


然后在我看来,你好像没有检查当地政府

=> 您可以同时运行将事物写入字典以及在本地打印这两个对象。

此外,

playerDistances
似乎绑定到玩家对象的特定实例,因此您实际上有两个独立的字典,每个玩家组件上都有一个。

所以发生的事情是针对你所做的每个玩家

CalculateDistancePercentage();

始终使用正确的变换距离

但是那么你总是使用

来存储它
PlayerPrefs.GetString("PlayerName")

as key,无论在哪个组件上运行,都将始终返回相同的本地名称。


所以我的猜测是,在一本字典中,我们可以说您存储的玩家“AC”

2/6 Key:AC Value:69.639

并且由于您还在您添加的字典中的其他客户端(“BBB”)组件上运行代码

2/6 Key:AC Value:22.622

在“AC”上添加组件的另一客户端上也会发生同样的情况

2/6 Key:BBB Value:69.639

并且添加了“BBB”成分

2/6 Key:BBB Value:22.622

现在它们已同步,并且两个词典都包含具有不同距离的两个键。

再次打印时,您实际上打印了两个独立的词典


因此,为了解决这个问题(免责声明:没有任何光子专家,我只是一起谷歌搜索)你要么根本不想使用字典,而只是在相应组件本身上同步单个浮点数

[Networked] [field: SerializeField] public float distance { get; private set; }

然后确保仅在本地客户端上计算

if(HasStateAuthority)
{
    distance = CalculateDistancePercentage();
}

或者您可以确保只为两个玩家使用一个字典 - 即与会话本身而不是每个玩家关联的字典 - 自定义会话属性每个玩家都可以写入

SessionInfo
UpdateCustomProperties
并阅读
SessionInfo.Properties

例如有点像

if(HasStateAuthority)
{
    var distance = CalculateDistancePercentage();
    var properties = SessionInfo.Properties;
    properties[PlayerPrefs.GetString("PlayerName")] = distance;
    SessionInfo.UpdateCustomProperties(properties);
}

然后进行打印

if (HasInputAuthority && Input.GetKeyDown(KeyCode.U))
{
    var properties = SessionInfo.Properties;
    foreach(var kvp in properties)
    {
        Debug.Log($"Key:{kvp.Key} Value:{kvp.Value}").
    }
}

如果使用更多这些属性,您可能需要向键添加专用前缀,以便您知道这是关于玩家距离的。

© www.soinside.com 2019 - 2024. All rights reserved.