我开始讨论将列表结构切换到字典而我遇到了一些麻烦。我正在修改我的foreach语句foreach (KeyValuePair <int, Player> p in players)
以使用我的字典,但是我很难理解如何使用键值对访问我的播放器对象中的变量。
我目前使用字典坚持这一行:moveMsg += p.connectionId.ToString() + '%' + p.playerPosition.x.ToString() + '%' + p.playerPosition.y.ToString() + '|';
我得到的错误是:Assets/Scripts/Server.cs(118,18): error CS1061: Type System.Collections.Generic.KeyValuePair<int,Player>' does not contain a definition for connectionId' and no extension method connectionId' of type System.Collections.Generic.KeyValuePair<int,Player>' could be found. Are you missing an assembly reference?
如何进行修改?
声明字典:public Dictionary<int, Player> players = new Dictionary<int, Player>();
词典
// Ask player for their position
if (Time.time - lastMovementUpdate > movementUpdateRate)
{
lastMovementUpdate = Time.time;
string moveMsg = "ASKPOSITION|";
foreach (KeyValuePair <int, Player> p in players)
moveMsg += p.connectionId.ToString() + '%' + p.playerPosition.x.ToString() + '%' + p.playerPosition.y.ToString() + '|';
moveMsg = moveMsg.Trim('|');
Send(moveMsg, unreliableChannel, players);
}
玩家类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Player
{
public string PlayerName;
public GameObject Avatar;
public int ConnectionId;
public byte[] Tex; // data coming from CanvasController
public string Type; // data coming from CanvasController
public string Id; // data coming from GameManager
public int Strength; // data coming from PlayerController
public int Hitpoints; // data coming from PlayerController
public bool IsAlive; // data coming from PlayerController
// Initial method takes base arguments for testing
public Player(string playerName, GameObject avatar, int connectionID)
{
PlayerName = playerName;
Avatar = avatar;
ConnectionId = connectionID;
}
// Overload method takes all animal arguments
public Player(string playerName, GameObject avatar, int connectionID, byte[] tex, string type, string id, int strength, int hitpoints, bool isAlive)
{
PlayerName = playerName;
Avatar = avatar;
ConnectionId = connectionID;
Tex = tex;
Type = type;
Id = id;
Strength = strength;
Hitpoints = hitpoints;
IsAlive = isAlive;
Debug.Log(id + " : " + type + " created with strength " + strength + ", hit points " + hitpoints + ", and a texture the size of " + tex.Length);
}
}
答案 0 :(得分:4)
由于您的变量p
是KeyValuePair<int, Player>
,因此您无法直接使用ConnectionId
访问p.ConnectionId
。您应该使用p.Value.ConnectionId
访问它,因为在<int, Player>
KeyValuePair中,Player对应于Value。您还可以访问similar fashion中的密钥。
答案 1 :(得分:1)
KeyPairValue仅包含两个属性Key和Value
https://msdn.microsoft.com/en-us/library/5tbh8a42(v=vs.110).aspx
您尝试过:
p.Key
而不是p.ConnectionId
和
p.Value
代替p.PlayerPosition
编辑:我使用Aggregate fct编写了一个小lambda来简单地编写代码。我传递了默认值,然后对于你的dict中的每个项目,它将统一另一个字符串。我还使用字符串插值来避免字符串连接($&#34; {variable}&#34;)。
class Player
{
public Point Position { get; set; }
}
public void Test()
{
var players = new Dictionary<int, Player>();
var msg = players.Aggregate(
string.Empty,
(current, p) => current +
$"{p.Key}%{p.Value.Position.X}%{p.Value.Position.Y}|");
}
答案 2 :(得分:1)
您在玩家类中有一个ConnectionId,但访问connectionId。 PS。奇怪的是为什么编译。 顺便说一下,你可以使用player.Join - 一个linq扩展