Unity game on iOS ArgumentOutOfRangeException in dictionary

本文关键字:in dictionary ArgumentOutOfRangeException iOS game on Unity | 更新日期: 2023-09-27 17:49:19

我有一个成就模块,用于保存和加载一个带有成就名称(键)的字典,如果它已经完成(bool值)。我使用GDE(游戏数据编辑器)插件(这个)。

我的模块在Unity编辑器中工作良好,保存和加载所有内容。但在iOS中,它会因参数out of range异常而崩溃。我的保存和加载方法:

    public void Load(){
    GDEAchievementsData achievements;
    if (!GDEDataManager.DataDictionary.TryGetCustom(GDEItemKeys.Achievements_Achievements, out achievements)){
        Debug.LogError("Error reading save data!");
    }
    LoadAchievementsInDictionary(achievements);
    Debug.Log("Achievement loaded data");
}
public void Save(){
    GDEAchievementsData achievements;
    if (!GDEDataManager.DataDictionary.TryGetCustom(GDEItemKeys.Achievements_Achievements, out achievements)){
        Debug.LogError("Error reading save data!");
    }
    SaveDictionaryInAchievements(AchievementScript.achievements, achievements);
    achievements.Set_Achievements();
    Debug.Log("ACHIEVEMENTS saved data");
}
void LoadAchievementsInDictionary(GDEAchievementsData gdeData){
    Debug.Log("Achievements: "+gdeData.Achievements);
    if(achievements==null){
        achievements = new AchievementList();
    }
    foreach(List<String> achievement in gdeData.Achievements){
        if(achievements.list.ContainsKey(achievement[0]))
        {
            achievements.list[achievement[0]] = (achievement[1]=="true")||(achievement[1]=="True");
        }else{
            achievements.list.Add(achievement[0], achievement[1]=="true"||achievement[1]=="True");
        }
    }
}
void SaveDictionaryInAchievements(AchievementList list, GDEAchievementsData gdeData){
    for(int i = 0; i < gdeData.Achievements.Count; i++){
        List<string> item = gdeData.Achievements[i];
        string achievementName = item[0];
        item[1] = list.list[achievementName].ToString();
    }
}

和XCode调试器中生成的错误,用于保存:

ArgumentOutOfRangeException:参数超出范围。参数名称:index在System.Collections.Generic.List ' 1 system . string][。get_Item (Int32 index) [0x00000] in:0在AchievementScript。SaveDictionaryInAchievements(。成就列表列表,GameDataEditor。GDEAchievementsData gdeData) [0x00000] in:0在AchievementScript。Save () [0x00000] in:0在AchievementScript。OnApplicationFocus (Boolean focusStatus) [0x00000] in:0在AchievementScript。OnApplicationPause (Boolean pauseState) [0x00000] in:0

和加载:

ArgumentOutOfRangeException:参数超出范围。参数名称:index在System.Collections.Generic.List ' 1 system . string][。get_Item (Int32 index) [0x00000] in:0在AchievementScript。LoadAchievementsInDictionary (GameDataEditor。GDEAchievementsData gdeData) [0x00000] in:0在AchievementScript。Load () [0x00000] in:0在AchievementScript。OnApplicationFocus (Boolean focusStatus) [0x00000] in:0

问GDE团队同样的问题,但如果有人知道为什么会发生这种情况,那就太好了。

Unity game on iOS ArgumentOutOfRangeException in dictionary

多次访问achievement[0]achievement[1],而不首先检查achievement的大小-这可能导致索引异常,因为achievement中没有足够的元素。注意,如果List<>为空,即使访问[0]也会导致此错误。

要解决这个问题,请确保检查列表大小。这可以通过Linq

来完成
foreach(List<String> achievement in gdeData.Achievements.Where(l => l.Count >= 2)

或通过if语句

foreach(List<String> achievement in gdeData.Achievements)
{
    if(achievment < 2) continue;
    // Put the rest of your foreach logic here.
}