Reputation: 1348
I started poking at switching a list structure over to a dictionary and i'm having some trouble. I'm in the middle of modifying my foreach statement foreach (KeyValuePair <int, Player> p in players)
to work with my dictionary but I'm having difficulty in understanding how I then go about accessing variables in my player object using the key value pair.
And I'm currenty stuck on this line using a dictionary : moveMsg += p.connectionId.ToString() + '%' + p.playerPosition.x.ToString() + '%' + p.playerPosition.y.ToString() + '|';
The error I'm getting is: 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?
How do I make the modification?
Declare dictionary: public Dictionary<int, Player> players = new Dictionary<int, Player>();
Dictionary
// 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 class
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);
}
}
Upvotes: 1
Views: 89
Reputation:
KeyPairValue contains only two properties Key and Value
https://msdn.microsoft.com/en-us/library/5tbh8a42(v=vs.110).aspx
Did you try with:
p.Key
instead of p.ConnectionId
and
p.Value
instead of of p.PlayerPosition
Edit: I wrote a small lambda to simply your code using the Aggregate fct. I pass the default value and then for each items in your dict, it will concact another string. I also use string Interpolation to avoid string concatenation ($"{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}|");
}
Upvotes: 1
Reputation: 693
Since your variable p
is a KeyValuePair<int, Player>
you can not access to ConnectionId
directly with p.ConnectionId
. You should access it with p.Value.ConnectionId
, because in an <int, Player>
KeyValuePair, Player corresponds to the Value. You can also access to the key in a similar fashion.
Upvotes: 4
Reputation: 311
You have a ConnectionId in yr Player class, but access to connectionId. PS. Strangely why its compiled. Btw, you may use players.Join - a linq extension
Upvotes: 1