You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity游戏存档系统加载异常:所有配置文件加载相同值

问题诊断与修复方案

我一眼就看出问题出在哪了——你用PlayerPrefs传递存档路径的方式踩了全局变量的坑,再加上LoadProfiles的优先级逻辑错误,导致每次加载的都是同一个文件!

核心问题分析

  1. PlayerPrefs的全局覆盖隐患:循环里你反复把当前存档路径存入PlayerPrefs.SetString("Path", ...),但PlayerPrefs是全局存储,这种方式很容易因为时序问题导致路径被覆盖。
  2. LoadProfiles的优先级逻辑错误:你的LoadProfiles函数先检查的是path(用PlayerPrefs.GetString("ProfileName")拼接的路径),但循环里根本没更新ProfileName这个值!只要这个旧路径对应的文件存在,就会一直加载它的数据,完全忽略了你存在Path里的正确路径。

修复方案:去掉PlayerPrefs,直接传递路径参数

PlayerPrefs在这里完全是多余的,直接把路径作为参数传递给方法才是可靠的方式,能彻底避免全局变量的各种坑。

步骤1:修改循环代码,直接传递路径给AddProfiles

// 获取Profiles文件夹下所有目录,用Path.Combine避免路径分隔符问题
string[] profiles = Directory.GetDirectories(Path.Combine(Application.persistentDataPath, "Profiles"));
for (int i = 0; i < profiles.Length; i++) {
    string profilePath = profiles[i];
    AddProfiles(profilePath); // 直接把当前存档路径传进去
    Debug.Log(profilePath);
}

步骤2:修改AddProfiles方法,接收路径参数并传递给LoadProfiles

// 新增路径参数,直接传入要加载的存档路径
public void AddProfiles(string profileSavePath) {
    ProfilesData data = SaveProfiles.LoadProfiles(profileSavePath);
    if (data == null) {
        Debug.LogError("Failed to load profile from: " + profileSavePath);
        return;
    }
    
    img = data.profileImage;
    ProfilesUIClone = Instantiate(ProfilesUI) as GameObject;
    ProfilesUIClone.transform.SetParent(wheretomaketheprofileUI.transform.parent);
    
    // 简化UI查找层级写法
    Profile = ProfilesUIClone.transform.Find("SelectProfile/Name").GetComponentInChildren<Text>();
    Company = ProfilesUIClone.transform.Find("SelectProfile/Company").GetComponentInChildren<Text>();
    
    Profile.text = data.profileName;
    Company.text = data.companyName;
    ProfilesUIClone.SetActive(true);
    
    // 简化图片选择逻辑,减少重复代码
    string imagePath = $"SelectProfile/ProfileImage{img + 1}";
    Image = ProfilesUIClone.transform.Find(imagePath).GetComponent<Image>();
    Image.gameObject.SetActive(true);
}

步骤3:修改LoadProfiles方法,直接接收路径参数,去掉PlayerPrefs依赖

// 直接接收存档路径参数,不再依赖PlayerPrefs
public static ProfilesData LoadProfiles(string saveFilePath) {
    if (File.Exists(saveFilePath)) {
        BinaryFormatter formatter = new BinaryFormatter();
        // 用using自动释放流资源,比手动Close更安全
        using (FileStream stream = new FileStream(saveFilePath, FileMode.Open)) {
            ProfilesData data = formatter.Deserialize(stream) as ProfilesData;
            return data;
        }
    } else {
        Debug.LogError("Save file not found in " + saveFilePath);
        return null;
    }
}

额外优化建议

  • 始终用Path.Combine拼接路径,适配不同平台的路径分隔符(Windows的\和Mac/Linux的/)。
  • using语句管理FileStream,确保流资源被正确释放,避免内存泄漏。
  • 简化UI查找逻辑,用斜杠层级查找比多次调用Find更高效简洁。

这样修改后,每个循环都会把对应存档的路径直接传递给加载方法,就能正确加载所有不同的配置文件,不会再出现重复显示的问题了。

内容的提问来源于stack exchange,提问作者Eiromplays

火山引擎 最新活动