Unity游戏存档系统加载异常:所有配置文件加载相同值
问题诊断与修复方案
我一眼就看出问题出在哪了——你用PlayerPrefs传递存档路径的方式踩了全局变量的坑,再加上LoadProfiles的优先级逻辑错误,导致每次加载的都是同一个文件!
核心问题分析
- PlayerPrefs的全局覆盖隐患:循环里你反复把当前存档路径存入
PlayerPrefs.SetString("Path", ...),但PlayerPrefs是全局存储,这种方式很容易因为时序问题导致路径被覆盖。 - 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




