Unity集成TikTokLive库时抛出ArgumentNullException(路径参数为空)
Unity中使用TikTokLive库保存送礼数据时触发ArgumentNullException(path参数为空)
我用Frank v Hoof开发的TikTokLive库制作Unity游戏,当前需要将送礼者及其赠送的金币数量保存至JSON文件(游戏关闭时存入数据库),但每次接收礼物并执行保存函数时,都会抛出错误:ArgumentNullException: Value cannot be null, Parameter name:path。已耗时3小时排查仍未找到问题,移除Init中对OnGiftUpdateValue的调用后,其余代码运行正常。
文件路径初始化与Start方法
private string filePath; private void Start() { filePath = Path.Combine(Application.dataPath, "/userGiftData.json"); //filePath = "C:/Users/Kaki/Desktop/userGiftData.json"; // 检查文件是否存在,不存在则创建 if (!File.Exists(filePath)) { File.WriteAllText(filePath, "{}"); } }
触发调用的Init函数
public void Init(TikTokGift gift) { if (gift == null || gift.Sender.UniqueId == null || gift.Gift.Name == null) { Debug.LogError("Gift or sender data is null!"); return; } Gift = gift; Gift.OnAmountChanged += AmountChanged; Gift.OnStreakFinished += StreakFinished; txtUserName.text = $"{Gift.Sender.UniqueId} sent a {Gift.Gift.Name}!"; txtAmount.text = $"{Gift.Amount}x"; RequestImage(imgUserProfile, Gift.Sender.AvatarThumbnail); RequestImage(imgGiftIcon, Gift.Gift.Image); // 为不可连击的礼物触发连击结束逻辑 if (gift.StreakFinished) StreakFinished(gift, gift.Amount); OnGiftUpdateValue(Gift.Sender.UniqueId, Gift.Gift.Name); //第93行 }
OnGiftUpdateValue函数
public void OnGiftUpdateValue(string userName, string giftName) { // 读取文件中已有的JSON数据 Dictionary<string, int> userData = ReadUserDataFromJson(); if (giftValues.ContainsKey(giftName)) { int giftValue = giftValues[giftName]; // 获取礼物对应的金币数量 // 用户已存在则更新总额,不存在则新增记录 if (userData.ContainsKey(userName)) { userData[userName] += giftValue; } else { userData[userName] = giftValue; // 新用户初始值为当前礼物的金币数 } // 将更新后的数据写回JSON文件 WriteUserDataToJson(userData); //第120行 } else { Debug.LogError($"Gift '{giftName}' does not exist in the dictionary."); } }
JSON读写函数
private Dictionary<string, int> ReadUserDataFromJson() { if (File.Exists(filePath)) { string jsonData = File.ReadAllText(filePath); //return JsonConvert.DeserializeObject<Dictionary<string, int>>(jsonData) ?? new Dictionary<string, int>(); return JsonUtility.FromJson<Dictionary<string, int>>(jsonData); } return new Dictionary<string, int>(); } private void WriteUserDataToJson(Dictionary<string, int> data) { string jsonData = JsonUtility.ToJson(data); //File.WriteAllText(filePath, jsonData); System.IO.File.WriteAllText(filePath, jsonData); //第144行 Debug.Log("Data saved to: "+filePath); }
问题根源分析
报错提示path参数为空,说明调用File.WriteAllText或File.ReadAllText时,filePath变量未初始化(值为null)。核心原因是Unity的Start方法执行时机晚于TikTokLive的礼物回调触发时机:
Start方法在脚本实例化后的第一帧更新前执行,但如果TikTokLive的礼物事件在脚本Start执行前就触发并调用了Init,此时filePath还未被赋值,自然会引发空值错误。
解决方案
- 提前初始化文件路径
将filePath的初始化移到Awake方法中(Awake在脚本实例化时立即执行,比Start更早),同时修复路径拼接的格式错误(Path.Combine不需要手动加斜杠):
private string filePath; private void Awake() { // 让Path.Combine自动处理路径分隔符,避免跨平台格式错误 filePath = Path.Combine(Application.dataPath, "userGiftData.json"); if (!File.Exists(filePath)) { File.WriteAllText(filePath, "{}"); } }
- 修复JSON序列化问题
Unity内置的JsonUtility不支持直接序列化/反序列化Dictionary<string, int>,会导致读写数据异常。建议导入Newtonsoft.Json for Unity包(在Package Manager中搜索安装),替换原有JSON处理逻辑:
private Dictionary<string, int> ReadUserDataFromJson() { if (string.IsNullOrEmpty(filePath)) { Debug.LogError("filePath is not initialized!"); return new Dictionary<string, int>(); } if (File.Exists(filePath)) { string jsonData = File.ReadAllText(filePath); return JsonConvert.DeserializeObject<Dictionary<string, int>>(jsonData) ?? new Dictionary<string, int>(); } return new Dictionary<string, int>(); } private void WriteUserDataToJson(Dictionary<string, int> data) { if (string.IsNullOrEmpty(filePath)) { Debug.LogError("filePath is not initialized!"); return; } string jsonData = JsonConvert.SerializeObject(data); System.IO.File.WriteAllText(filePath, jsonData); Debug.Log("Data saved to: "+filePath); }
- 增加空值防御检查
在读写文件的方法中先判断filePath是否为空,避免无意义的报错,方便快速定位问题。
内容的提问来源于stack exchange,提问作者Granny
相关产品推荐
相关产品推荐

