Unity替换WWW为UnityWebRequest遇CS1503错误的解决方案
将Unity中已弃用的WWW替换为UnityWebRequest的解决方案
问题描述
Unity提示WWW已被弃用,需改用UnityWebRequest。尝试将原有上传Vuforia目标的代码替换为UnityWebRequest后,出现编译错误:
Assets\Scripts\CloudUpLoading.cs(98,63): error CS1503: 参数2: 无法从“byte[]”转换为“System.Collections.Generic.List<UnityEngine.Networking.IMultipartFormSection>”
错误原因是UnityWebRequest.Post的重载方法不支持直接传入字节数组作为第二个参数,该重载预期接收的是表单分段列表,而非原始字节数据。
修改方案
要实现与原WWW相同的功能(发送JSON格式的POST请求),需要改用UnityWebRequest的基础构造方法,配合UploadHandlerRaw处理原始字节数据,同时手动设置请求头。具体步骤如下:
- 移除无用的
WWWForm和HttpWebRequest代码(原代码中这两个对象并未实际使用) - 使用
UnityWebRequest构造方法创建POST请求 - 通过
UploadHandlerRaw传入JSON字节数据 - 逐个添加请求头,避免引入多余的表单相关头信息
修改后的完整代码
using UnityEngine; using System.Collections; using System; using System.Text; using System.Security.Cryptography; using System.IO; using UnityEngine.Networking; public class PostNewTrackableRequest { public string name; public float width; public string image; public string application_metadata; } public class CloudUpLoading : MonoBehaviour { public Texture2D texture; private string access_key = "588f3c9eeb13fe81f6827cced63adca95d6a"; private string secret_key = "77e56b7cac04b83d8ce55c13dd047e8acbbe"; private string url = @"https://vws.vuforia.com"; private string targetName = "Target_Hosted"; // 上传新目标时需修改,避免与云端已有目标重名 public void CallPostTarget() { StartCoroutine(PostNewTarget()); } IEnumerator PostNewTarget() { string requestPath = "/targets"; string serviceURI = url + requestPath; string httpAction = "POST"; string contentType = "application/json"; string date = string.Format("{0:r}", DateTime.Now.ToUniversalTime()); Debug.Log(date); // 处理纹理转为RGB24格式的PNG Texture2D tex = new Texture2D(texture.width, texture.height, TextureFormat.RGB24, false); tex.SetPixels(texture.GetPixels()); tex.Apply(); byte[] image = tex.EncodeToPNG(); // 构造请求模型 string metadataStr = "Target Image Detected"; byte[] metadata = ASCIIEncoding.ASCII.GetBytes(metadataStr); PostNewTrackableRequest model = new PostNewTrackableRequest(); model.name = targetName; model.width = 64.0f; model.image = Convert.ToBase64String(image); model.application_metadata = Convert.ToBase64String(metadata); string requestBody = JsonUtility.ToJson(model); // 计算Content-MD5 MD5 md5 = MD5.Create(); var contentMD5bytes = md5.ComputeHash(Encoding.ASCII.GetBytes(requestBody)); StringBuilder sb = new StringBuilder(); for (int i = 0; i < contentMD5bytes.Length; i++) { sb.Append(contentMD5bytes[i].ToString("x2")); } string contentMD5 = sb.ToString(); // 计算签名 string stringToSign = string.Format("{0}\n{1}\n{2}\n{3}\n{4}", httpAction, contentMD5, contentType, date, requestPath); HMACSHA1 sha1 = new HMACSHA1(Encoding.ASCII.GetBytes(secret_key)); byte[] sha1Hash = sha1.ComputeHash(Encoding.ASCII.GetBytes(stringToSign)); string signature = Convert.ToBase64String(sha1Hash); Debug.Log("<color=green>Signature: "+signature+"</color>"); // 创建UnityWebRequest并配置参数 UnityWebRequest www = new UnityWebRequest(serviceURI, httpAction); byte[] bodyRaw = Encoding.UTF8.GetBytes(requestBody); www.uploadHandler = new UploadHandlerRaw(bodyRaw); www.downloadHandler = new DownloadHandlerBuffer(); // 设置请求头 www.SetRequestHeader("Host", url); www.SetRequestHeader("Date", date); www.SetRequestHeader("Content-Type", contentType); www.SetRequestHeader("Authorization", string.Format("VWS {0}:{1}", access_key, signature)); // 发送请求 yield return www.SendWebRequest(); // 处理响应 if (www.result != UnityWebRequest.Result.Success) { Debug.Log("request error: " + www.error); } else { Debug.Log("request success"); Debug.Log("returned data: " + www.downloadHandler.text); } // 清理资源 www.Dispose(); } }
关键修改点说明
- 移除原代码中未使用的
WWWForm和HttpWebRequest实例,减少冗余代码 - 使用
UnityWebRequest构造方法指定请求方法为POST,配合UploadHandlerRaw传递JSON字节数据 - 用
SetRequestHeader方法逐个添加必要的请求头,避免引入WWWForm自带的表单相关头信息 - 添加
www.Dispose()手动释放资源,符合Unity资源管理规范 - 通过
downloadHandler.text获取响应内容,替代原WWW.text
内容的提问来源于stack exchange,提问作者ashah
相关产品推荐
相关产品推荐

