获取基于密钥的所有资源和伪随机选择值的字典

时间:2017-06-22 17:53:09

标签: c# dictionary unity3d resources

让我们假设我在Assests/Resources文件夹中的精心设计的目录树中有多个精灵。我想加载来自Assests/Resources/gfx的所有精灵(如果事实 - 来自其所有子文件夹; gfx self没有精灵)并将它们存储在Dictionary<string, Sprite> sprites;中。 这是我的代码:

void LoadSprites() {
        buildingSprites = new Dictionary<string, Sprite>();
        Sprite[] sprites = Resources.LoadAll<Sprite>("gfx/");

        Debug.Log("Loaded following resources:");
        foreach(Sprite s in sprites) {
            //Debug.Log(s);
            string path = AssetDatabase.GetAssetPath (s);
            path = path.Remove (0, 17); // "assets/resources" bit
            Debug.Log ("Found asset " + s + " in path: " + path);
            buildingSprites[s.path] = s;
        }
    }
}

事情是,如果我要求给定路径,我想得到一个与路径匹配的随机精灵。例如,如果ABC中的文件夹Assests/Resources/gfx有精灵XYZ,那么我想通过函数只获得其中一个spites提供ABC的路径(所以我可以将它分配给我的Gameobject或其他)。

我的问题:

  1. 如何获取精灵的资产path
  2. 如何将完整的path + name存储为字典键? (当1.回答时应该是显而易见的,但我想指出,这可能只是用于获取path
  3. 如何仅通过提供path部分从字典中获取任何值 关键并寻找匹配的东西?
  4. 如何仅通过提供path部分从字典中获取随机值 关键的,寻找匹配的一切?

1 个答案:

答案 0 :(得分:0)

嗯,首先,你不能存储这样的数据,无论如何,你需要存储你所在的每个目录级别的精灵列表。因为我有很多空闲时间,我做了这个..

考虑:

  • 如果一个目录是空的(或只包含文件夹),它将不会在字典中有任何条目,并且它在字典中没有密钥。你可以找出这部分;)
  • 请注意我存储了一个List&gt;而不是每个路径的精灵。
  • 在创建课程时记住包含
  • 请实际阅读代码,这里有很多值得学习的地方。 代码:

`

Dictionary<string, List<Sprite>> buildingSprites;

void Start()
{
    LoadSprites();
}

void LoadSprites() {
    buildingSprites = new Dictionary<string, List<Sprite>>();
    Sprite[] sprites = Resources.LoadAll<Sprite>("gfx/");
    foreach (Sprite s in sprites) {
        string path = AssetDatabase.GetAssetPath(s);
        path = path.Remove(0, 17);
        addToDictionary(path, s);
    }

    string FOLDER_NAME = "/"; // FODLER NAME SHOULD BE LIKE /ABC/ ... OR / FOR ROOT DIRECTORY
    if (!buildingSprites.ContainsKey(FOLDER_NAME)) {
        Debug.LogWarning("Wheres the folder: " + FOLDER_NAME + "?");
        return;
    }

    foreach (Sprite s in getEntriesThatStartWith(FOLDER_NAME, false))
        Debug.Log(AssetDatabase.GetAssetPath(s));

    // GET A RANDOM SPRITE ?

    Sprite aRandomSprite =   (getRandomSprite ( getEntriesThatStartWith (FOLDER_NAME , true)));

}

Sprite getRandomSprite(List<Sprite> sprites){
    int randomIndex = Mathf.RoundToInt(Random.Range(0f, 1f) * sprites.Count );
    return sprites[randomIndex];
}

List<Sprite> getEntriesThatStartWith(string prefix, bool allowSubFolders){
    if (!allowSubFolders && buildingSprites.ContainsKey(prefix)) {
        return buildingSprites[prefix];
    }
    else if (allowSubFolders) {
        List<Sprite> allSubSprites = new List<Sprite>();
        foreach (string s in buildingSprites.Keys)
            if (s.StartsWith(prefix))
                foreach (Sprite subSprite in buildingSprites[s])
                    allSubSprites.Add(subSprite);
        return allSubSprites;
    }

    return null;
}

void addToDictionary (string path_with_name , Sprite spriteToAdd ) {
    string path = getPath (path_with_name);
    List<Sprite> sprites = null;
    buildingSprites.TryGetValue (path , out sprites );

    if (sprites == null){
        sprites = new List<Sprite>();
        buildingSprites.Add(path, sprites);
    }
    sprites.Add(spriteToAdd);
}

string getPath (string path_with_name) {
    int firstIndex = path_with_name.IndexOf('/');
    int lastIndex = path_with_name.LastIndexOf('/');
    return path_with_name.Substring(firstIndex, lastIndex - firstIndex + 1);
}

`