【问题标题】:unknown error with the unitywebrequest functionunitywebrequest 函数的未知错误
【发布时间】:2023-08-29 13:27:01
【问题描述】:

我正在做一个apk,当我在手机上运行它时出现以下错误

“未知错误”

但最奇怪的是,如果我从 unity 运行它时它正常工作,我使用以下代码向我展示了当我在手机上执行它时出现的错误,因为在 unity 中运行完美

IEnumerator logIn(WWWForm form)
{
    using (UnityWebRequest webRequest = UnityWebRequest.Post("http://localhost:3000/login", form))
    {
        yield return webRequest.SendWebRequest();

        if (webRequest.isNetworkError )
        {
            Debug.Log(webRequest.error);
            advertencia.SetActive(true);
            advertencia.GetComponent<Text>().text=webRequest.error+"1";
        }
        else if (webRequest.isHttpError)
        {
            advertencia.SetActive(true);
            advertencia.SetActive(true);
            advertencia.GetComponent<Text>().text = webRequest.error+"2";
        }
        else
        {                
            SceneManager.LoadScene("Principal");
        }
    }
}

使用以下代码检查我的 apk 是否已连接到互联网,如果它连接到互联网则显示文本

private void Update()
{
    if (Application.internetReachability == NetworkReachability.NotReachable)
    {
        advertencia.SetActive(true);
        Debug.Log("Error. Check internet connection!");
    }

}

代码更完整一点:

private Text userText;
private InputField password;
public GameObject advertencia;

    private void Start()
{
    userText = GameObject.Find("UserInput").GetComponent<Text>();
    password = GameObject.Find("PasswordInput").GetComponent<InputField>();
    advertencia = GameObject.Find("Advertencia");
    advertencia.SetActive(false);

}

  //the function with which the corrutina invoked
   public void Log()
{
    Debug.Log("Usuario : " + userText.text + "\nContraseña : " + password.text);

    WWWForm form = new WWWForm();
    form.AddField("codigo", userText.text);
    form.AddField("contrasena", password.text);

    StartCoroutine(logIn(form));

}

【问题讨论】:

  • 因为这个社区是英文的,所以我删除了西班牙文的副本。您能否添加一个完整的代码示例..您提供的内容并不多。
  • 错误是 100% 可重复的还是间歇性的?间歇性网络错误是意料之中的,您必须处理它,通常通过重试您正在执行的任何操作。
  • @derHugo 准备好并添加更完整的代码
  • @RetiredNinja 当我在手机上运行它时,它总是会发生,但团结起来它永远不会发生
  • 手机需要 https 或安全策略才能允许 http。

标签: unity3d webrequest unitywebrequest


【解决方案1】:

问题

您使用网址

http://localhost:3000/login

您正在尝试将 Web 请求发送到主机 localhost。这适用于 Unity 中的 PC,因为 PC 您尝试联系的服务器。

服务器未在您的手机上运行,​​但您的手机正尝试通过端口3000自身发送请求,这显然会失败。

阅读更多What is a localhost?

解决方案

localhost 替换为您的服务器/PC 实际拥有的IP 或network address,应该没问题。

要找出您的 PC 的 IP,请使用例如

  • Linux/Unix:在终端调用ifconfig
  • Windows:在 CMD 调用中ipconfig

当然,您的 PC 和手机也必须在同一个网络中,或者至少经过路由,以便您的手机可以访问给定 IP/网络地址的服务器/PC。

您可能还必须配置 PC 的防火墙以允许该端口上的传入流量。

【讨论】:

    【解决方案2】:
    • 如果您在移动设备上运行此代码,则应更改主机名。您不能在边缘设备中使用 localhost。因此,您必须输入运行后端服务器的计算机的 IP 地址,而不是 localhost

      为了获取 IP 地址,

      在命令提示符/终端输入以下命令,

      对于 Windows 机器

      ipconfig
      

      适用于 Linux / Mac 机器

      ifconfig
      

      然后取 IPv4 地址并用这个 IP 替换 localhost,像这样,

      using (UnityWebRequest webRequest = UnityWebRequest.Post("http://192.168.1.9:3000/login", form))
      

    • 您必须确保已将计算机(运行服务器的地方)和移动设备连接到同一网络。您只需通过 wifi 网络连接所有设备即可。

    • 如果您使用的是在 Android 9、Pie(API 级别 27+) 或更高版本的操作系统上运行的移动设备,那么您必须在 @ 中指定 android:usesCleartextTraffic="true" 987654328@文件。

      所以,点击播放器设置 --> 发布设置 --> 检查自定义清单模板。您可以像这样在清单文件中添加android:usesCleartextTraffic="true"

      <?xml version="1.0" encoding="utf-8"?>
      <manifest ...>
          <uses-permission android:name="android.permission.INTERNET" />
          <application
              ...
              android:usesCleartextTraffic="true"
          ...>
          ...
          </application>
      </manifest>
      

      AndroidManifest.xml

      <?xml version="1.0" encoding="utf-8"?>
      <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" android:installLocation="preferExternal" android:versionCode="1" android:versionName="1.0">
          <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
          <uses-permission android:name="android.permission.INTERNET" />
          <application android:theme="@style/UnityThemeSelector" android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="true" android:usesCleartextTraffic="true">
              <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name">
                  <intent-filter>
                       <action android:name="android.intent.action.MAIN" />
                       <category android:name="android.intent.category.LAUNCHER" />
                  </intent-filter>
                  <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
             </activity>
        </application>
      </manifest>
      

    【讨论】: