【问题标题】:Choosing text file to use as dictionary in Unity在 Unity 中选择文本文件用作字典
【发布时间】:2017-03-07 08:48:59
【问题描述】:

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

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

第一段代码完美运行,但是当我将其更改为

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

我得到错误代码

ArgumentException:字典中已存在具有相同键的元素。 System.Collections.Generic.Dictionary2[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] (IEnumerable1 源,System.Func2 keySelector, System.Func2 元素选择器,IEqualityComparer1 comparer) System.Linq.Enumerable.ToDictionary[String,String] (IEnumerable1 源,System.Func2 keySelector, IEqualityComparer1 比较器) System.Linq.Enumerable.ToDictionary[String,String] (IEnumerable1 source, System.Func2 keySelector) GameController.Awake () (在 Assets/Scripts/GameController.cs:127)

【问题讨论】:

  • 您的代码似乎没有出现在您的问题中?
  • @Abdul 谢谢我遇到了同样的问题,您的问题帮助我找到了解决方案
  • @Thematkinson 我已经编辑过了...谢谢

标签: c# linq dictionary unity3d


【解决方案1】:

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

Dictionary&lt;string, string&gt; dictionary 示例:

(Key => Value)

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

当得到一个值时,你给字典一个字符串Key,它就会返回这个值。

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

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

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

您会遇到异常,因为您破坏了 Dictionary 的工作方式(一个值的唯一键)。如果你没有得到异常并且你试图访问键“greeting”的值,你会得到哪个值?

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

这就是编译时出现异常的原因。

您需要确保每个键都是唯一的。在您的文本文件中,您有同一个单词的多个实例。我没有看到字典的使用,也许你被困在“字典”这个词的语义上,以及你想用它做什么。我认为列表是您所追求的(?),这意味着没有键,只有值。

由于我不知道您想要实现什么,因此很难推荐解决方案,但您可以在 Dictionary here 上阅读更多信息。如果您确实需要将它作为字典,here 是您如何从数组中填充它的答案。


更新:

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

好的!我认为字典不是您想要的;这是您所追求的列表。将所有单词添加到列表中:

wordList = wordListArray.ToList();

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

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

更新2:

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

给我的印象是您还有另一个问题,即如何选择要加载的文件。好吧,为此你需要有所改变,我假设你有,我们称之为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())

因为我不知道你什么时候想加载不同的文件,所以这是我可以做的低抽象。

【讨论】:

  • 我使用字典是因为我希望能够检查文本文件是否包含单词
  • 把它钉在@Fredrik 上。 +1
  • @Abdul 好的!我更新了答案,检查底部!比格沃斯先生,谢谢! =)
  • 我得到了字典的结构,但是从我的代码中,我将文本文件的内容加载到字典中,然后根据选择的类别加载特定的文本文件......说我有名称为动物、国家、名称的文本文件。如果该人选择名称,则加载名称文本文件
  • Yh 非常感谢您现在一切正常...结合您最初使用 List 的建议,然后将 switch 应用到它。
【解决方案2】:

这里的逻辑似乎有点混乱。您似乎正在尝试使用 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;

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

【讨论】:

  • 是的,这比我的建议要干净。 +1 马上回你哥们
  • 谢谢哥们,愿 Stack Overflow 爱情盛宴继续下去。
【解决方案3】:

在这里结合@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");
}

这个函数在start函数中调用如下

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-27
    • 2017-07-21
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 2010-10-25
    相关资源
    最近更新 更多