Unity调用含UnityWebRequest方法时Step Over抛异常Step Into正常问题求助
问题根因与解决方案
核心问题
你遇到的异常本质是异步网络请求未完成就直接读取返回值导致的,和调试操作的关联原因如下:
UnityWebRequest.SendWebRequest()是异步非阻塞API,调用后会在后台执行网络请求,不会阻塞当前线程等待结果返回,代码会直接向后执行- 执行Step Into单步调试时,手动操作的延迟刚好给了网络请求足够的完成时间,等你走到读取返回值的代码行时,请求已经返回了正确数据,因此不会报错
- 执行Step Over时,代码会立刻执行完
GetCountryByName方法,此时网络请求还在后台运行,downloadHandler.text是空值,拆分后得到的数组长度远小于你访问的索引,自然会抛出「索引超出范围」「输入字符串格式不正确」的异常
代码修正方案
你当前的GetCountryByName写法完全不符合Unity网络请求的规范,需要做以下修改:
1. 将方法改为协程实现
Unity中处理UnityWebRequest必须用协程等待请求完成,这是你原有代码缺失的核心逻辑,示例修改如下:
// 建议移除方法的static修饰,或者准备一个全局MonoBehaviour实例来启动协程 public IEnumerator GetCountryByName(string countryName, Action<CountryModel> onComplete) { CountryModel country = new CountryModel(); WWWForm form = new WWWForm(); form.AddField("CountryName", countryName); using (UnityWebRequest req = UnityWebRequest.Post(WebReguests.getCountryByName, form)) { // 等待请求完成,必须添加该逻辑 yield return req.SendWebRequest(); if (req.isNetworkError || req.isHttpError) { Debug.LogError(req.error); onComplete?.Invoke(country); yield break; } var data = req.downloadHandler.text; string[] result = data.Split(','); // 增加数组长度校验,避免非法索引异常 if (result.Length < 15) { Debug.LogError("返回数据格式错误:" + data); onComplete?.Invoke(country); yield break; } int id; if (int.TryParse(result[0], out id)) { country.id = id; } country.CountryName = result[1]; // 后续字段赋值逻辑保持原有逻辑不变 // ... 省略其他字段赋值代码 onComplete?.Invoke(country); } }
2. 调整调用方式
调用处不能再用同步赋值的写法,需要通过回调接收结果:
// CreateUser方法也需要调整为协程,或者通过回调处理后续逻辑 public IEnumerator CreateUser(PersonModel model, Action<PersonModel> onComplete) { CountryModel nativeCountry = null; // 假设MySQLCountryManager已实例化,实例名为mysqlCountryMgr yield return mysqlCountryMgr.GetCountryByName(model.NativeCountry, res => { nativeCountry = res; }); // 此处再执行依赖nativeCountry的后续业务逻辑 // <some other code here....> onComplete?.Invoke(model); }
额外注意事项
- 不要在继承自MonoBehaviour的类里写不必要的静态方法,会导致协程、生命周期逻辑无法正常执行
- 所有涉及数组索引访问的逻辑,必须先校验数组长度,避免非法索引异常
- 字符串转数值的操作要做好异常兼容,避免空值、非法格式输入导致的崩溃
内容的提问来源于stack exchange,提问作者castelum85
相关产品推荐
相关产品推荐

