2017-10-15 28 views
1

我開始將列表結構切換到字典,並且遇到了一些麻煩。我正在修改我的foreach語句foreach (KeyValuePair <int, Player> p in players)以處理我的字典,但我很難理解我如何使用鍵值對訪問播放器對象中的變量。從列表轉換爲字典,foreach語句出現問題

而且我currenty停留在使用字典這一行: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); 
} 

Player類

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); 
    } 
} 

回答

4

由於您的變量p是一個KeyValuePair<int, Player>您無法訪問到ConnectionId直接與p.ConnectionId。您應該使用p.Value.ConnectionId來訪問它,因爲在<int, Player> KeyValuePair中,Player對應於Value。您也可以訪問similar fashion中的密鑰。

1

KeyPairValue只包含兩個屬性鍵和值

https://msdn.microsoft.com/en-us/library/5tbh8a42(v=vs.110).aspx

你嘗試用:的 p.Key代替p.ConnectionIdp.Value代替的p.PlayerPosition

編輯:我寫了一個小lambda來只需使用Aggregate fct的代碼即可。我傳遞默認值,然後爲您的字典中的每個項目,它將concact另一個字符串。我也使用字符串插值來避免字符串連接($「{variable}」)。

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}|"); 
    } 
+0

另外我很確定你可以將你的foreach循環轉換成一個不錯的lambda表達式。我會給你更多的細節tmr – Seb

+0

看來你也錯過了PlayPosition屬性 – Seb

1

您在yr Player類中有ConnectionId,但是可以訪問connectionId。 PS。奇怪爲什麼它編譯。 順便說一句,你可以使用players.Join - 一個LINQ擴展