选择要在Unity中用作字典的文本文件

时间:2017-03-07 08:49:00

标签: c# linq dictionary unity3d

我正在开发一款游戏,用户在玩游戏前选择一个类别。根据所选的类别,这里加载必要的字典是执行该操作的代码

wb.Navigate("http://authen.dzogame.com:8080/LauncherLogin.aspx?gid=200");
Wait();
id = txtID.Text;
pass = txtPassword.Text;
wb.Document.GetElementById("tbxUserName").SetAttribute("value", id);
wb.Document.GetElementById("tbxPassword").SetAttribute("value", pass);
wb.Document.GetElementById("btnLogin").InvokeMember("Click");
Wait();
string cookie = wb.Document.Cookie;
WebClient wc = new WebClient();
wc.Headers.Add(HttpRequestHeader.Cookie, cookie);
string token = wc.DownloadString("http://authen.dzogame.com:8080/ReturnLogin.ashx");

这第一段代码完美无缺,但当我将其更改为

public Text selectedCategory; //contains the text of the selected category
private Dictionary<String,String> wordList = new Dictionary<String,String> (); //holds the dictionary
private string[] wordListArray; //the array the contents of the text file is first loaded to
private TextAsset textAsset; //the text asset to be used
private string category; // the category selected

void Awake(){
    category = selectedCategory.text;
    textAsset = Resources.Load ("words", typeof(TextAsset)) as TextAsset;
    Debug.Log ("Words dictionary is loaded");
    wordListArray = textAsset.text.Split (new char[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
    wordList = wordListArray.ToDictionary (s => s);
    Debug.Log ("File loaded as dictionary");
}

我收到错误代码

  

ArgumentException:字典中已存在具有相同键的元素。   System.Collections.Generic.Dictionary void Awake(){ category = selectedCategory.text; if (String.Compare(category, "Animals") == 1) { textAsset = Resources.Load ("animals", typeof(TextAsset)) as TextAsset; Debug.Log ("Animals dictionary is loaded"); } else { textAsset = Resources.Load ("words", typeof(TextAsset)) as TextAsset; Debug.Log ("Words dictionary is loaded"); } wordListArray = textAsset.text.Split (new char[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries); wordList = wordListArray.ToDictionary (s => s); Debug.Log ("File loaded as dictionary"); } 1 source,System.Func 2[System.String,System.String].Add (System.String key, System.String value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:404) System.Linq.Enumerable.ToDictionary[String,String,String] (IEnumerable 2 elementSelector,IEqualityComparer 2 keySelector, System.Func 1 source,System.Func 1 comparer) System.Linq.Enumerable.ToDictionary[String,String] (IEnumerable 1 comparer)   System.Linq.Enumerable.ToDictionary [String,String](IEnumerable 2 keySelector, IEqualityComparer 2 keySelector)   GameController.Awake()(在Assets / Scripts / GameController.cs:127)

3 个答案:

答案 0 :(得分:3)

C#Dictionary具有键值结构,这意味着它看起来像这样:

Dictionary<string, string> dictionary示例:

(Key => Value)

"greeting" => "Hello"
"animal" => "Dog"

获取值时,您将字典赋予字符串Key并返回值。

 Debug.Log(dictionary["greeting"]) --> "Hello"

因此,当您在文本文件中尝试添加多个具有相同值的键时,例如:

"greeting" => "Hello"
"animal" => "Dog"
"greeting" => "Hey"

您将获得一个例外,因为您正在破坏字典的工作方式(值的一个唯一键)。如果您没有获得例外,并且您尝试访问密钥&#34;问候&#34;的价值,您会得到哪个值?

Debug.Log(dictionary["greeting"]) --> ???

这就是编译时遇到异常的原因。

您需要确保每个密钥都是唯一的。在您的文本文件中,您有多个相同单词的实例。我没有看到词典的使用,也许你已经停留在单词&#34; Dictionary&#34;的语义上了。以及你想用它做什么。我认为列表是你(?)之后的意思,意思是没有键,只有值。

由于我不知道您要尝试实现的目标,因此很难推荐解决方案,但您可以在字典here上阅读更多内容。 here是一个答案,如果你真的需要它作为字典,你将如何从数组中填充它。

更新

  

我使用了字典,因为我希望能够检查文本文件是否包含单词

确定!我认为词典不是你想要的;它是你之后的一个列表。将所有单词添加到列表中:

wordList = wordListArray.ToList();

并检查列表中是否包含您要检查的单词(也可以在您的阵列上完成)

if (wordList.contains(YourString)) {
    Debug.Log(YourString + " exist in wordList!");
}

UPDATE2:

  

我得到了字典的结构,但是从我的代码中我将文本文件的内容加载到字典中,然后根据选择的类别加载特定的文本文件...说我有文本文件名字动物,国家,名字。如果此人选择名称,则加载名称文本文件

给我的印象是你有另一个问题,即如何选择要加载的文件。好吧,你需要改变一些东西,我认为你有,我们称之为playerChoice。以下是如何做到的:

TextAsset textAsset;
switch (playerChoice) {
    case "PlayerOption1":
        textAsset = Resources.Load<TextAsset>("words1", typeof(TextAsset));
    break;
    case "PlayerOption2":
        textAsset = Resources.Load<TextAsset>("words2", typeof(TextAsset));
    break;
}

// and then the rest of your textAsset, 
// handling code (splitting on linebreaks and .ToList())

由于我不知道你何时想要加载不同的文件,这是我可以做的低抽象。

答案 1 :(得分:1)

这里的逻辑似乎有点混乱。您似乎试图决定使用textAsset变量加载哪个文本文档,但是您似乎从文件中加载了所有文本,然后将其粘贴到字典中。

如果你有不同的文字文件和独特的内容,那么只需要一个枚举列表,让玩家选择一个。然后根据他们的决定加载不同的文本文件。

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};

然后在你的代码中有类似的东西:

var currentChoice; //Value set elsewhere in code (through UI)
textAsset = Resources.Load (currentChoice.ToString(), typeof(TextAsset)) as TextAsset;

然后根据他们的选择获得正确的资产。

答案 2 :(得分:1)

在这里结合@Fredrik给出的答案是完整的工作代码

public Text selectedCategory; //contains the text of the selected category
private List<String> wordList; //holds the dictionary
private string[] wordListArray; //the array the contents of the text file is first loaded to
private TextAsset textAsset; //the text asset to be used
private string category; // the category selected

//new function to load the dictionary
void LoadDictionary(string category){
    switch (category) {
    case "Animals":
        textAsset = Resources.Load ("animals", typeof(TextAsset)) as TextAsset;
        Debug.Log ("Animals dictionary is loaded");
        break;
    default:
        textAsset = Resources.Load ("words", typeof(TextAsset)) as TextAsset;
        Debug.Log ("Words dictionary is loaded");
        break;
    }
    wordListArray = textAsset.text.Split (new char[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
    wordList = wordListArray.ToList();
    Debug.Log ("File is loaded");
}

此功能在启动功能中调用如下

void Start () {
    selectedCategory.text = PlayerPrefs.GetString("categorySelected");
    category = selectedCategory.text;
    LoadDictionary (category);
}