我正在使用 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
没有解决您的问题,但总的来说:根据 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}").
}
}
如果使用更多这些属性,您可能需要向键添加专用前缀,以便您知道这是关于玩家距离的。